aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Siddharth Rakesh <sidrakesh@google.com>2015-06-08 13:44:51 -0700
committerGravatar Siddharth Rakesh <sidrakesh@google.com>2015-06-08 13:44:51 -0700
commit39824335ea2d29ab627a8accb8e12c3bd50352ad (patch)
tree85a951745a5e14cb14e83e97deae95ed72aba489
parent467af23d22f710d9bc41a16233cc6c95cffd6391 (diff)
Newer version
-rw-r--r--test/cpp/qps/report.cc54
-rw-r--r--test/cpp/qps/report.h6
-rw-r--r--test/cpp/qps/run_auth_test.py135
-rw-r--r--test/cpp/qps/user_data.proto55
-rw-r--r--test/cpp/qps/user_data_client.cc62
-rw-r--r--test/cpp/qps/user_data_client.h51
-rw-r--r--test/cpp/util/benchmark_config.cc4
7 files changed, 258 insertions, 109 deletions
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
index b4229889ad..124bdc70fd 100644
--- a/test/cpp/qps/report.cc
+++ b/test/cpp/qps/report.cc
@@ -130,19 +130,8 @@ void UserDatabaseReporter::ReportQPS(const ScenarioResult& result) const {
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;
- }
+ userDataClient.setConfigs(result.client_config, result.server_config);
}
void UserDatabaseReporter::ReportQPSPerCore(const ScenarioResult& result,
@@ -153,40 +142,17 @@ void UserDatabaseReporter::ReportQPSPerCore(const ScenarioResult& result,
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;
- }
+ userDataClient.setConfigs(result.client_config, result.server_config);
}
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;
- }
+ result.latencies.Percentile(90) / 1000,
+ result.latencies.Percentile(95) / 1000,
+ result.latencies.Percentile(99) / 1000,
+ result.latencies.Percentile(99.9) / 1000);
+ userDataClient.setConfigs(result.client_config, result.server_config);
}
void UserDatabaseReporter::ReportTimes(const ScenarioResult& result) const {
@@ -207,11 +173,13 @@ void UserDatabaseReporter::ReportTimes(const ScenarioResult& result) const {
sum(result.client_resources,
[](ResourceUsage u) { return u.wall_time; });
- userDataClient.setAccessToken(access_token_);
userDataClient.setTimes(serverSystemTime, serverUserTime,
clientSystemTime, clientUserTime);
+ userDataClient.setConfigs(result.client_config, result.server_config);
+}
- int userDataState = userDataClient.sendDataIfReady();
+void UserDatabaseReporter::Flush() const {
+ int userDataState = userDataClient.sendData(access_token_, test_name_);
switch(userDataState) {
case 1:
diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h
index 2e5b627e58..8a1ce2dabc 100644
--- a/test/cpp/qps/report.h
+++ b/test/cpp/qps/report.h
@@ -109,15 +109,19 @@ class GprLogReporter : public Reporter {
/** Reporter for client leaderboard. */
class UserDatabaseReporter : public Reporter {
public:
- UserDatabaseReporter(const string& name, const string& access_token) : Reporter(name), access_token_(access_token) {}
+ UserDatabaseReporter(const string& name, const string& access_token,
+ const string& test_name) : Reporter(name), access_token_(access_token), test_name_(test_name) {}
+ ~UserDatabaseReporter() { Flush(); };
private:
std::string access_token_;
+ std::string test_name_;
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;
+ void Flush() const;
};
} // namespace testing
diff --git a/test/cpp/qps/run_auth_test.py b/test/cpp/qps/run_auth_test.py
new file mode 100644
index 0000000000..3ed2a7c980
--- /dev/null
+++ b/test/cpp/qps/run_auth_test.py
@@ -0,0 +1,135 @@
+#!/usr/bin/python
+
+import os
+import sys
+import re
+import urllib2
+import urllib
+import json
+import time
+import subprocess
+
+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'
+
+def fetchJSON(url, paramDict):
+ if len(paramDict) == 0:
+ req = urllib2.Request(url)
+ else:
+ data = urllib.urlencode(paramDict)
+ req = urllib2.Request(url, data)
+
+ try:
+ response = urllib2.urlopen(req)
+ result = response.read()
+
+ except urllib2.HTTPError, error:
+ result = error.read()
+
+ return result
+
+def getUserInfo(accessToken):
+ url = USER_INFO_LINK + '?access_token=' + accessToken
+ paramDict = {}
+ JSONBody = fetchJSON(url, paramDict)
+ data = json.loads(JSONBody)
+
+ return data
+
+def isAccessTokenValid(accessToken):
+ data = getUserInfo(accessToken);
+
+ if 'id' in data:
+ return True
+ else:
+ return False
+
+def getUserId(accessToken):
+ data = getUserInfo(accessToken)
+
+ email = data['email']
+ email = email.split('@')[0].lower()
+ userId = re.sub('[.]', '', email)
+
+ return userId
+
+def useAccessToken(userTokFile):
+ with open(userTokFile, "r") as data_file:
+ data = json.load(data_file)
+ accessToken = data["access_token"]
+
+ if not isAccessTokenValid(accessToken):
+ return refreshAccessToken(data["refresh_token"], userTokFile)
+
+ return accessToken
+
+def refreshAccessToken(refreshToken, userTokFile):
+ paramDict = {'refresh_token':refreshToken, 'client_id':CLIENT_ID, 'client_secret':CLIENT_SECRET, 'grant_type':'refresh_token'}
+ JSONBody = fetchJSON(AUTH_TOKEN_LINK, paramDict)
+ data = json.loads(JSONBody)
+ if not 'access_token' in data:
+ return reauthenticate()
+ else:
+ tokenData = {}
+
+ with open(userTokFile, "r") as data_file:
+ tokenData = json.load(data_file)
+
+ with open(userTokFile, "w") as data_file:
+ tokenData['access_token'] = data['access_token']
+ json.dump(tokenData, data_file)
+
+ return data['access_token']
+
+def reauthenticate():
+ paramDict = {'client_id':CLIENT_ID, 'scope':'email profile'}
+ JSONBody = fetchJSON(GOOGLE_ACCOUNTS_LINK, paramDict)
+ data = json.loads(JSONBody)
+
+ print 'User authorization required\n'
+ print 'Please use the following code in you browser: ', data['user_code']
+ print 'Verification URL: ', data['verification_url']
+ print '\nAwaiting user authorization. May take a few more seconds after authorizing...\n'
+
+ authData = {}
+
+ while not 'access_token' in authData:
+ authDict = {'client_id':CLIENT_ID, 'client_secret':CLIENT_SECRET, 'code':data['device_code'], 'grant_type':GRANT_TYPE}
+ JSONBody = fetchJSON(AUTH_TOKEN_LINK, authDict)
+ authData = json.loads(JSONBody)
+ time.sleep(data['interval'])
+
+ newUserTokFile = ACCESS_TOKENS_DIR + '/' + getUserId(authData['access_token'])
+
+ with open(newUserTokFile, "w") as data_file:
+ json.dump(authData, data_file)
+
+ return authData['access_token']
+
+def main():
+ if not os.path.exists(ACCESS_TOKENS_DIR):
+ os.makedirs(ACCESS_TOKENS_DIR)
+
+ email = sys.argv[2]
+ email = email.split('@')[0].lower()
+ userId = re.sub('[.]', '', email)
+
+ userTokFile = ACCESS_TOKENS_DIR + '/' + userId
+
+ accessToken = ''
+
+ if os.path.exists(userTokFile):
+ accessToken = useAccessToken(userTokFile)
+ else:
+ accessToken = reauthenticate()
+
+ testName = sys.argv[1].split('/')[-1]
+ subprocess.call([sys.argv[1], '--access_token='+accessToken, '--test_name='+testName])
+
+if __name__ == "__main__":
+ main() \ No newline at end of file
diff --git a/test/cpp/qps/user_data.proto b/test/cpp/qps/user_data.proto
index 9c941cae2c..27d0049cf0 100644
--- a/test/cpp/qps/user_data.proto
+++ b/test/cpp/qps/user_data.proto
@@ -29,7 +29,9 @@
syntax = "proto2";
-package UserData;
+import "test/cpp/qps/qpstest.proto";
+
+package grpc.testing;
service UserDataTransfer {
// Sends client info
@@ -42,37 +44,56 @@ service UserDataTransfer {
//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;
+ optional double qps = 1;
+ optional double qps_per_core = 2;
+ optional double perc_lat_50 = 3;
+ optional double perc_lat_90 = 4;
+ optional double perc_lat_95 = 5;
+ optional double perc_lat_99 = 6;
+ optional double perc_lat_99_point_9 = 7;
+ optional double server_system_time = 8;
+ optional double server_user_time = 9;
+ optional double client_system_time = 10;
+ optional double client_user_time = 11;
}
//Timestamped details
message DataDetails {
- required string timestamp = 1;
- required Metrics metrics = 2;
+ optional string timestamp = 1;
+ optional string test_name = 2;
+ optional Metrics metrics = 3;
+ optional ClientConfig client_config = 4;
+ optional ServerConfig server_config = 5;
}
//User details
message UserDetails {
- required string id = 1;
- required string name = 2;
- required string link = 3;
+ optional string id = 1;
+ optional string email = 2;
+ optional bool verified_email = 3;
+ optional string name = 4;
+ optional string given_name = 5;
+ optional string family_name = 6;
+ optional string link = 7;
+ optional string picture = 8;
+ optional string gender = 9;
+ optional string locale = 10;
+ optional string hd = 11;
}
//Stored to database
message SingleUserDetails {
repeated DataDetails data_details = 1;
- required UserDetails user_details = 2;
+ optional UserDetails user_details = 2;
}
//Request for storing a single user's data
message SingleUserRecordRequest {
- required string access_token = 1;
- required Metrics metrics = 2;
+ optional string access_token = 1;
+ optional string test_name = 2;
+ optional Metrics metrics = 3;
+ optional ClientConfig client_config = 4;
+ optional ServerConfig server_config = 5;
}
//Reply to request for storing single user's data
@@ -81,12 +102,12 @@ message SingleUserRecordReply {
//Request for retrieving single user's data
message SingleUserRetrieveRequest {
- required string client_id = 1;
+ optional string user_id = 1;
}
//Reply for request to retrieve single user's data
message SingleUserRetrieveReply {
- required SingleUserDetails details = 1;
+ optional SingleUserDetails details = 1;
}
//Request for retrieving all users' data
diff --git a/test/cpp/qps/user_data_client.cc b/test/cpp/qps/user_data_client.cc
index 20ce6d9c09..50b74276d2 100644
--- a/test/cpp/qps/user_data_client.cc
+++ b/test/cpp/qps/user_data_client.cc
@@ -33,17 +33,20 @@
#include "user_data_client.h"
-void UserDataClient::setAccessToken(std::string access_token) {
- access_token_ = access_token;
+namespace grpc {
+namespace testing {
+
+void UserDataClient::setConfigs(const ClientConfig& clientConfig, const ServerConfig& serverConfig) {
+ clientConfig_ = clientConfig;
+ serverConfig_ = serverConfig;
}
void UserDataClient::setQPS(double QPS) {
QPS_ = QPS;
- qpsSet = true;
}
-void UserDataClient::setQPSPerCore(double qpsPerCore) {
- //TBD
+void UserDataClient::setQPSPerCore(double QPSPerCore) {
+ QPSPerCore_ = QPSPerCore;
}
void UserDataClient::setLatencies(double percentileLatency50, double percentileLatency90,
@@ -53,29 +56,37 @@ void UserDataClient::setLatencies(double percentileLatency50, double percentileL
percentileLatency95_ = percentileLatency95;
percentileLatency99_ = percentileLatency99;
percentileLatency99Point9_ = percentileLatency99Point9;
-
- latenciesSet = true;
}
void UserDataClient::setTimes(double serverSystemTime, double serverUserTime,
double clientSystemTime, double clientUserTime) {
- //TBD
+ serverSystemTime_ = serverSystemTime;
+ serverUserTime_ = serverUserTime;
+ clientSystemTime_ = clientSystemTime;
+ clientUserTime_ = clientUserTime;
}
-int UserDataClient::sendDataIfReady() {
- if(!(qpsSet && latenciesSet))
- return 0;
+int UserDataClient::sendData(std::string access_token, std::string test_name) {
SingleUserRecordRequest singleUserRecordRequest;
- singleUserRecordRequest.set_access_token(access_token_);
+ singleUserRecordRequest.set_access_token(access_token);
+ singleUserRecordRequest.set_test_name(test_name);
+ *(singleUserRecordRequest.mutable_client_config()) = clientConfig_;
+ *(singleUserRecordRequest.mutable_server_config()) = serverConfig_;
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_);
+
+ if(QPS_ != DBL_MIN) metrics->set_qps(QPS_);
+ if(QPSPerCore_ != DBL_MIN) metrics->set_qps_per_core(QPSPerCore_);
+ if(percentileLatency50_ != DBL_MIN) metrics->set_perc_lat_50(percentileLatency50_);
+ if(percentileLatency90_ != DBL_MIN) metrics->set_perc_lat_90(percentileLatency90_);
+ if(percentileLatency95_ != DBL_MIN) metrics->set_perc_lat_95(percentileLatency95_);
+ if(percentileLatency99_ != DBL_MIN) metrics->set_perc_lat_99(percentileLatency99_);
+ if(percentileLatency99Point9_ != DBL_MIN) metrics->set_perc_lat_99_point_9(percentileLatency99Point9_);
+ if(serverSystemTime_ != DBL_MIN) metrics->set_server_system_time(serverSystemTime_);
+ if(serverUserTime_ != DBL_MIN) metrics->set_server_user_time(serverUserTime_);
+ if(clientSystemTime_ != DBL_MIN) metrics->set_client_system_time(clientSystemTime_);
+ if(clientUserTime_ != DBL_MIN) metrics->set_client_user_time(clientUserTime_);
SingleUserRecordReply singleUserRecordReply;
ClientContext context;
@@ -90,11 +101,14 @@ int UserDataClient::sendDataIfReady() {
// 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);
+ 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;
+ strftime(buf, sizeof(buf), "%Y/%m/%d, %X", &tstruct);
+ return buf;
+}
+
+}
} \ No newline at end of file
diff --git a/test/cpp/qps/user_data_client.h b/test/cpp/qps/user_data_client.h
index ec3dcb5d44..0186ec9071 100644
--- a/test/cpp/qps/user_data_client.h
+++ b/test/cpp/qps/user_data_client.h
@@ -34,6 +34,7 @@
#include <iostream>
#include <memory>
#include <string>
+#include <cfloat>
#include <grpc/grpc.h>
#include <grpc++/channel_arguments.h>
@@ -44,27 +45,22 @@
#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;
+
+namespace grpc{
+namespace testing {
class UserDataClient {
- public:
+public:
UserDataClient(std::shared_ptr<ChannelInterface> channel)
: stub_(UserDataTransfer::NewStub(channel)) {}
~UserDataClient() {}
- void setAccessToken(std::string access_token);
+ void setConfigs(const ClientConfig& clientConfig, const ServerConfig& serverConfig);
void setQPS(double QPS);
- void setQPSPerCore(double qpsPerCore);
+ void setQPSPerCore(double QPSPerCore);
void setLatencies(double percentileLatency50, double percentileLatency90,
double percentileLatency95, double percentileLatency99, double percentileLatency99Point9);
@@ -72,17 +68,26 @@ class UserDataClient {
void setTimes(double serverSystemTime, double serverUserTime,
double clientSystemTime, double clientUserTime);
- int sendDataIfReady();
+ int sendData(std::string access_token, std::string test_name);
- private:
+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;
-}; \ No newline at end of file
+ ClientConfig clientConfig_;
+ ServerConfig serverConfig_;
+ double QPS_ = DBL_MIN;
+ double QPSPerCore_ = DBL_MIN;
+ double percentileLatency50_ = DBL_MIN;
+ double percentileLatency90_ = DBL_MIN;
+ double percentileLatency95_ = DBL_MIN;
+ double percentileLatency99_ = DBL_MIN;
+ double percentileLatency99Point9_ = DBL_MIN;
+ double serverSystemTime_ = DBL_MIN;
+ double serverUserTime_ = DBL_MIN;
+ double clientSystemTime_ = DBL_MIN;
+ double clientUserTime_ = DBL_MIN;
+};
+
+} //namespace testing
+} //namespace grpc
+
+
diff --git a/test/cpp/util/benchmark_config.cc b/test/cpp/util/benchmark_config.cc
index b68822436d..6b573abb50 100644
--- a/test/cpp/util/benchmark_config.cc
+++ b/test/cpp/util/benchmark_config.cc
@@ -39,6 +39,8 @@ DEFINE_bool(enable_log_reporter, true,
DEFINE_string(access_token, "", "Authorizing JSON string for leaderboard");
+DEFINE_string(test_name, "", "Name of the test being executed");
+
// 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 {}
@@ -61,7 +63,7 @@ static std::shared_ptr<Reporter> InitBenchmarkReporters() {
}
if(!FLAGS_access_token.empty())
composite_reporter->add(
- std::unique_ptr<Reporter>(new UserDatabaseReporter("UserDataReporter", FLAGS_access_token)));
+ std::unique_ptr<Reporter>(new UserDatabaseReporter("UserDataReporter", FLAGS_access_token, FLAGS_test_name)));
return std::shared_ptr<Reporter>(composite_reporter);
}