diff options
author | Siddharth Rakesh <sidrakesh@google.com> | 2015-06-08 13:44:51 -0700 |
---|---|---|
committer | Siddharth Rakesh <sidrakesh@google.com> | 2015-06-08 13:44:51 -0700 |
commit | 39824335ea2d29ab627a8accb8e12c3bd50352ad (patch) | |
tree | 85a951745a5e14cb14e83e97deae95ed72aba489 | |
parent | 467af23d22f710d9bc41a16233cc6c95cffd6391 (diff) |
Newer version
-rw-r--r-- | test/cpp/qps/report.cc | 54 | ||||
-rw-r--r-- | test/cpp/qps/report.h | 6 | ||||
-rw-r--r-- | test/cpp/qps/run_auth_test.py | 135 | ||||
-rw-r--r-- | test/cpp/qps/user_data.proto | 55 | ||||
-rw-r--r-- | test/cpp/qps/user_data_client.cc | 62 | ||||
-rw-r--r-- | test/cpp/qps/user_data_client.h | 51 | ||||
-rw-r--r-- | test/cpp/util/benchmark_config.cc | 4 |
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); } |