Newer version

pull/2151/head
Siddharth Rakesh 10 years ago
parent 467af23d22
commit 39824335ea
  1. 54
      test/cpp/qps/report.cc
  2. 6
      test/cpp/qps/report.h
  3. 135
      test/cpp/qps/run_auth_test.py
  4. 55
      test/cpp/qps/user_data.proto
  5. 62
      test/cpp/qps/user_data_client.cc
  6. 51
      test/cpp/qps/user_data_client.h
  7. 4
      test/cpp/util/benchmark_config.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:

@ -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

@ -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()

@ -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

@ -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;
}
}
}

@ -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;
};
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

@ -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);
}

Loading…
Cancel
Save