Numerous proto changes to make things more sane and fix some outstanding issues

reviewable/pr3905/r3
vjpai 9 years ago
parent 4b69152e7f
commit 754751e3c6
  1. 40
      Makefile
  2. 4
      build.yaml
  3. 4
      test/cpp/qps/async_streaming_ping_pong_test.cc
  4. 4
      test/cpp/qps/async_unary_ping_pong_test.cc
  5. 50
      test/cpp/qps/client.h
  6. 6
      test/cpp/qps/client_async.cc
  7. 2
      test/cpp/qps/client_sync.cc
  8. 2
      test/cpp/qps/driver.h
  9. 2
      test/cpp/qps/histogram.h
  10. 2
      test/cpp/qps/perf_db.proto
  11. 63
      test/cpp/qps/qps_driver.cc
  12. 5
      test/cpp/qps/qps_openloop_test.cc
  13. 4
      test/cpp/qps/qps_test.cc
  14. 4
      test/cpp/qps/qps_test_with_poll.cc
  15. 2
      test/cpp/qps/qps_worker.cc
  16. 2
      test/cpp/qps/server.h
  17. 2
      test/cpp/qps/server_async.cc
  18. 2
      test/cpp/qps/server_sync.cc
  19. 4
      test/cpp/qps/sync_streaming_ping_pong_test.cc
  20. 4
      test/cpp/qps/sync_unary_ping_pong_test.cc
  21. 17
      test/proto/perf_tests/perf_control.proto
  22. 0
      test/proto/perf_tests/perf_stats.proto
  23. 8
      tools/run_tests/sources_and_headers.json
  24. 16
      vsprojects/vcxproj/qps/qps.vcxproj
  25. 11
      vsprojects/vcxproj/qps/qps.vcxproj.filters

@ -3586,30 +3586,30 @@ $(GENDIR)/test/proto/messages.grpc.pb.cc: test/proto/messages.proto $(PROTOBUF_D
endif endif
ifeq ($(NO_PROTOC),true) ifeq ($(NO_PROTOC),true)
$(GENDIR)/test/proto/perf_control.pb.cc: protoc_dep_error $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc: protoc_dep_error
$(GENDIR)/test/proto/perf_control.grpc.pb.cc: protoc_dep_error $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/test/proto/perf_control.pb.cc: test/proto/perf_control.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc: test/proto/perf_tests/perf_control.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) --cpp_out=$(GENDIR) $< $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
$(GENDIR)/test/proto/perf_control.grpc.pb.cc: test/proto/perf_control.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc: test/proto/perf_tests/perf_control.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif endif
ifeq ($(NO_PROTOC),true) ifeq ($(NO_PROTOC),true)
$(GENDIR)/test/proto/perf_stats.pb.cc: protoc_dep_error $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc: protoc_dep_error
$(GENDIR)/test/proto/perf_stats.grpc.pb.cc: protoc_dep_error $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/test/proto/perf_stats.pb.cc: test/proto/perf_stats.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc: test/proto/perf_tests/perf_stats.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) --cpp_out=$(GENDIR) $< $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
$(GENDIR)/test/proto/perf_stats.grpc.pb.cc: test/proto/perf_stats.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc: test/proto/perf_tests/perf_stats.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
@ -5205,8 +5205,8 @@ $(OBJDIR)/$(CONFIG)/test/cpp/interop/server.o: $(GENDIR)/test/proto/empty.pb.cc
LIBQPS_SRC = \ LIBQPS_SRC = \
$(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc \ $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc \
$(GENDIR)/test/proto/perf_control.pb.cc $(GENDIR)/test/proto/perf_control.grpc.pb.cc \ $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc \
$(GENDIR)/test/proto/perf_stats.pb.cc $(GENDIR)/test/proto/perf_stats.grpc.pb.cc \ $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc \
$(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc \ $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc \
test/cpp/qps/client_async.cc \ test/cpp/qps/client_async.cc \
test/cpp/qps/client_sync.cc \ test/cpp/qps/client_sync.cc \
@ -5261,16 +5261,16 @@ ifneq ($(NO_DEPS),true)
-include $(LIBQPS_OBJS:.o=.dep) -include $(LIBQPS_OBJS:.o=.dep)
endif endif
endif endif
$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_control.pb.cc $(GENDIR)/test/proto/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_stats.pb.cc $(GENDIR)/test/proto/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_control.pb.cc $(GENDIR)/test/proto/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_stats.pb.cc $(GENDIR)/test/proto/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_control.pb.cc $(GENDIR)/test/proto/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_stats.pb.cc $(GENDIR)/test/proto/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/perf_db_client.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_control.pb.cc $(GENDIR)/test/proto/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_stats.pb.cc $(GENDIR)/test/proto/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/qps/perf_db_client.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_control.pb.cc $(GENDIR)/test/proto/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_stats.pb.cc $(GENDIR)/test/proto/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_control.pb.cc $(GENDIR)/test/proto/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_stats.pb.cc $(GENDIR)/test/proto/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_control.pb.cc $(GENDIR)/test/proto/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_stats.pb.cc $(GENDIR)/test/proto/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_sync.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_control.pb.cc $(GENDIR)/test/proto/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_stats.pb.cc $(GENDIR)/test/proto/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/qps/server_sync.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_control.pb.cc $(GENDIR)/test/proto/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_stats.pb.cc $(GENDIR)/test/proto/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/benchmark_config.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_control.pb.cc $(GENDIR)/test/proto/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_stats.pb.cc $(GENDIR)/test/proto/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/util/benchmark_config.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.pb.cc $(GENDIR)/test/proto/perf_tests/perf_control.grpc.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.pb.cc $(GENDIR)/test/proto/perf_tests/perf_stats.grpc.pb.cc $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc
LIBGRPC_CSHARP_EXT_SRC = \ LIBGRPC_CSHARP_EXT_SRC = \

@ -750,8 +750,8 @@ libs:
- test/cpp/util/benchmark_config.h - test/cpp/util/benchmark_config.h
src: src:
- test/proto/messages.proto - test/proto/messages.proto
- test/proto/perf_control.proto - test/proto/perf_tests/perf_control.proto
- test/proto/perf_stats.proto - test/proto/perf_tests/perf_stats.proto
- test/cpp/qps/perf_db.proto - test/cpp/qps/perf_db.proto
- test/cpp/qps/client_async.cc - test/cpp/qps/client_async.cc
- test/cpp/qps/client_sync.cc - test/cpp/qps/client_sync.cc

@ -52,7 +52,7 @@ static void RunAsyncStreamingPingPong() {
ClientConfig client_config; ClientConfig client_config;
client_config.set_client_type(ASYNC_CLIENT); client_config.set_client_type(ASYNC_CLIENT);
client_config.set_enable_ssl(false); client_config.set_use_tls(false);
client_config.set_outstanding_rpcs_per_channel(1); client_config.set_outstanding_rpcs_per_channel(1);
client_config.set_client_channels(1); client_config.set_client_channels(1);
client_config.set_payload_size(1); client_config.set_payload_size(1);
@ -61,7 +61,7 @@ static void RunAsyncStreamingPingPong() {
ServerConfig server_config; ServerConfig server_config;
server_config.set_server_type(ASYNC_SERVER); server_config.set_server_type(ASYNC_SERVER);
server_config.set_enable_ssl(false); server_config.set_use_tls(false);
server_config.set_threads(1); server_config.set_threads(1);
const auto result = const auto result =

@ -52,7 +52,7 @@ static void RunAsyncUnaryPingPong() {
ClientConfig client_config; ClientConfig client_config;
client_config.set_client_type(ASYNC_CLIENT); client_config.set_client_type(ASYNC_CLIENT);
client_config.set_enable_ssl(false); client_config.set_use_tls(false);
client_config.set_outstanding_rpcs_per_channel(1); client_config.set_outstanding_rpcs_per_channel(1);
client_config.set_client_channels(1); client_config.set_client_channels(1);
client_config.set_payload_size(1); client_config.set_payload_size(1);
@ -61,7 +61,7 @@ static void RunAsyncUnaryPingPong() {
ServerConfig server_config; ServerConfig server_config;
server_config.set_server_type(ASYNC_SERVER); server_config.set_server_type(ASYNC_SERVER);
server_config.set_enable_ssl(false); server_config.set_use_tls(false);
server_config.set_threads(1); server_config.set_threads(1);
const auto result = const auto result =

@ -40,7 +40,7 @@
#include "test/cpp/qps/histogram.h" #include "test/cpp/qps/histogram.h"
#include "test/cpp/qps/interarrival.h" #include "test/cpp/qps/interarrival.h"
#include "test/cpp/qps/timer.h" #include "test/cpp/qps/timer.h"
#include "test/proto/perf_control.grpc.pb.h" #include "test/proto/perf_tests/perf_control.grpc.pb.h"
#include "test/cpp/util/create_test_channel.h" #include "test/cpp/util/create_test_channel.h"
namespace grpc { namespace grpc {
@ -122,7 +122,7 @@ class Client {
// We have to use a 2-phase init like this with a default // We have to use a 2-phase init like this with a default
// constructor followed by an initializer function to make // constructor followed by an initializer function to make
// old compilers happy with using this in std::vector // old compilers happy with using this in std::vector
channel_ = CreateTestChannel(target, config.enable_ssl()); channel_ = CreateTestChannel(target, config.use_tls());
stub_ = TestService::NewStub(channel_); stub_ = TestService::NewStub(channel_);
} }
Channel* get_channel() { return channel_.get(); } Channel* get_channel() { return channel_.get(); }
@ -146,37 +146,31 @@ class Client {
void SetupLoadTest(const ClientConfig& config, size_t num_threads) { void SetupLoadTest(const ClientConfig& config, size_t num_threads) {
// Set up the load distribution based on the number of threads // Set up the load distribution based on the number of threads
if (config.load_type() == CLOSED_LOOP) { const auto& load = config.load_params();
closed_loop_ = true;
} else {
closed_loop_ = false;
std::unique_ptr<RandomDist> random_dist; std::unique_ptr<RandomDist> random_dist;
const auto& load = config.load_params(); if (load.has_poisson()) {
switch (config.load_type()) { random_dist.reset(new ExpDist(load.poisson().offered_load() /
case POISSON: num_threads));
random_dist.reset( } else if (load.has_uniform()) {
new ExpDist(load.poisson().offered_load() / num_threads)); random_dist.reset(new UniformDist(load.uniform().interarrival_lo() *
break; num_threads,
case UNIFORM: load.uniform().interarrival_hi() *
random_dist.reset( num_threads));
new UniformDist(load.uniform().interarrival_lo() * num_threads, } else if (load.has_determ()) {
load.uniform().interarrival_hi() * num_threads)); random_dist.reset(new DetDist(num_threads / load.determ().offered_load()));
break; } else if (load.has_pareto()) {
case DETERMINISTIC: random_dist.reset(new ParetoDist(load.pareto().interarrival_base() * num_threads,
random_dist.reset(
new DetDist(num_threads / load.determ().offered_load()));
break;
case PARETO:
random_dist.reset(
new ParetoDist(load.pareto().interarrival_base() * num_threads,
load.pareto().alpha())); load.pareto().alpha()));
break; } else { // No load parameters, so must be closed-loop
default:
GPR_ASSERT(false);
break;
} }
// Set closed_loop_ based on whether or not random_dist is set
if (!random_dist) {
closed_loop_ = true;
} else {
closed_loop_ = false;
// set up interarrival timer according to random dist
interarrival_timer_.init(*random_dist, num_threads); interarrival_timer_.init(*random_dist, num_threads);
for (size_t i = 0; i < num_threads; i++) { for (size_t i = 0; i < num_threads; i++) {
next_time_.push_back( next_time_.push_back(

@ -48,7 +48,7 @@
#include <gflags/gflags.h> #include <gflags/gflags.h>
#include <grpc++/client_context.h> #include <grpc++/client_context.h>
#include "test/proto/perf_control.grpc.pb.h" #include "test/proto/perf_tests/perf_control.grpc.pb.h"
#include "test/cpp/qps/timer.h" #include "test/cpp/qps/timer.h"
#include "test/cpp/qps/client.h" #include "test/cpp/qps/client.h"
#include "test/cpp/util/create_test_channel.h" #include "test/cpp/util/create_test_channel.h"
@ -439,8 +439,8 @@ class AsyncStreamingClient GRPC_FINAL : public AsyncClient {
public: public:
explicit AsyncStreamingClient(const ClientConfig& config) explicit AsyncStreamingClient(const ClientConfig& config)
: AsyncClient(config, SetupCtx) { : AsyncClient(config, SetupCtx) {
// async streaming currently only supported closed loop // async streaming currently only supports closed loop
GPR_ASSERT(config.load_type() == CLOSED_LOOP); GPR_ASSERT(closed_loop_);
StartThreads(config.async_client_threads()); StartThreads(config.async_client_threads());
} }

@ -54,7 +54,7 @@
#include "test/cpp/util/create_test_channel.h" #include "test/cpp/util/create_test_channel.h"
#include "test/cpp/qps/client.h" #include "test/cpp/qps/client.h"
#include "test/proto/perf_control.grpc.pb.h" #include "test/proto/perf_tests/perf_control.grpc.pb.h"
#include "test/cpp/qps/histogram.h" #include "test/cpp/qps/histogram.h"
#include "test/cpp/qps/interarrival.h" #include "test/cpp/qps/interarrival.h"
#include "test/cpp/qps/timer.h" #include "test/cpp/qps/timer.h"

@ -37,7 +37,7 @@
#include <memory> #include <memory>
#include "test/cpp/qps/histogram.h" #include "test/cpp/qps/histogram.h"
#include "test/proto/perf_control.grpc.pb.h" #include "test/proto/perf_tests/perf_control.grpc.pb.h"
namespace grpc { namespace grpc {
namespace testing { namespace testing {

@ -35,7 +35,7 @@
#define TEST_QPS_HISTOGRAM_H #define TEST_QPS_HISTOGRAM_H
#include <grpc/support/histogram.h> #include <grpc/support/histogram.h>
#include "test/proto/perf_stats.grpc.pb.h" #include "test/proto/perf_tests/perf_stats.grpc.pb.h"
namespace grpc { namespace grpc {
namespace testing { namespace testing {

@ -29,7 +29,7 @@
syntax = "proto3"; syntax = "proto3";
import "test/proto/perf_control.proto"; import "test/proto/perf_tests/perf_control.proto";
package grpc.testing; package grpc.testing;

@ -50,7 +50,7 @@ DEFINE_int32(benchmark_seconds, 30, "Benchmark time (in seconds)");
DEFINE_int32(local_workers, 0, "Number of local workers to start"); DEFINE_int32(local_workers, 0, "Number of local workers to start");
// Common config // Common config
DEFINE_bool(enable_ssl, false, "Use SSL"); DEFINE_bool(use_tls, false, "Use TLS");
DEFINE_string(rpc_type, "UNARY", "Type of RPC: UNARY or STREAMING"); DEFINE_string(rpc_type, "UNARY", "Type of RPC: UNARY or STREAMING");
// Server config // Server config
@ -64,15 +64,20 @@ DEFINE_int32(client_channels, 1, "Number of client channels");
DEFINE_int32(payload_size, 1, "Payload size"); DEFINE_int32(payload_size, 1, "Payload size");
DEFINE_string(client_type, "SYNCHRONOUS_CLIENT", "Client type"); DEFINE_string(client_type, "SYNCHRONOUS_CLIENT", "Client type");
DEFINE_int32(async_client_threads, 1, "Async client threads"); DEFINE_int32(async_client_threads, 1, "Async client threads");
DEFINE_double(poisson_load, -1.0, "Poisson offered load (qps)");
DEFINE_double(uniform_lo, -1.0, "Uniform low interarrival time (us)");
DEFINE_double(uniform_hi, -1.0, "Uniform high interarrival time (us)");
DEFINE_double(determ_load, -1.0, "Deterministic offered load (qps)");
DEFINE_double(pareto_base, -1.0, "Pareto base interarrival time (us)");
DEFINE_double(pareto_alpha, -1.0, "Pareto alpha value");
DEFINE_string(load_type, "CLOSED_LOOP", "Load type"); DEFINE_string(load_type, "CLOSED_LOOP", "Load type");
DEFINE_double(load_param_1, 0.0, "Load parameter 1");
DEFINE_double(load_param_2, 0.0, "Load parameter 2");
using grpc::testing::ClientConfig; using grpc::testing::ClientConfig;
using grpc::testing::ServerConfig; using grpc::testing::ServerConfig;
using grpc::testing::ClientType; using grpc::testing::ClientType;
using grpc::testing::ServerType; using grpc::testing::ServerType;
using grpc::testing::LoadType;
using grpc::testing::RpcType; using grpc::testing::RpcType;
using grpc::testing::ResourceUsage; using grpc::testing::ResourceUsage;
@ -85,15 +90,12 @@ static void QpsDriver() {
ClientType client_type; ClientType client_type;
ServerType server_type; ServerType server_type;
LoadType load_type;
GPR_ASSERT(ClientType_Parse(FLAGS_client_type, &client_type)); GPR_ASSERT(ClientType_Parse(FLAGS_client_type, &client_type));
GPR_ASSERT(ServerType_Parse(FLAGS_server_type, &server_type)); GPR_ASSERT(ServerType_Parse(FLAGS_server_type, &server_type));
GPR_ASSERT(LoadType_Parse(FLAGS_load_type, &load_type));
ClientConfig client_config; ClientConfig client_config;
client_config.set_client_type(client_type); client_config.set_client_type(client_type);
client_config.set_load_type(load_type); client_config.set_use_tls(FLAGS_use_tls);
client_config.set_enable_ssl(FLAGS_enable_ssl);
client_config.set_outstanding_rpcs_per_channel( client_config.set_outstanding_rpcs_per_channel(
FLAGS_outstanding_rpcs_per_channel); FLAGS_outstanding_rpcs_per_channel);
client_config.set_client_channels(FLAGS_client_channels); client_config.set_client_channels(FLAGS_client_channels);
@ -102,46 +104,29 @@ static void QpsDriver() {
client_config.set_rpc_type(rpc_type); client_config.set_rpc_type(rpc_type);
// set up the load parameters // set up the load parameters
switch (load_type) { if (FLAGS_poisson_load > 0.0) {
case grpc::testing::CLOSED_LOOP:
break;
case grpc::testing::POISSON: {
auto poisson = client_config.mutable_load_params()->mutable_poisson(); auto poisson = client_config.mutable_load_params()->mutable_poisson();
GPR_ASSERT(FLAGS_load_param_1 != 0.0); poisson->set_offered_load(FLAGS_poisson_load);
poisson->set_offered_load(FLAGS_load_param_1); } else if (FLAGS_uniform_lo > 0.0) {
break;
}
case grpc::testing::UNIFORM: {
auto uniform = client_config.mutable_load_params()->mutable_uniform(); auto uniform = client_config.mutable_load_params()->mutable_uniform();
GPR_ASSERT(FLAGS_load_param_1 != 0.0); uniform->set_interarrival_lo(FLAGS_uniform_lo / 1e6);
GPR_ASSERT(FLAGS_load_param_2 != 0.0); uniform->set_interarrival_hi(FLAGS_uniform_hi / 1e6);
uniform->set_interarrival_lo(FLAGS_load_param_1 / 1e6); } else if (FLAGS_determ_load > 0.0) {
uniform->set_interarrival_hi(FLAGS_load_param_2 / 1e6);
break;
}
case grpc::testing::DETERMINISTIC: {
auto determ = client_config.mutable_load_params()->mutable_determ(); auto determ = client_config.mutable_load_params()->mutable_determ();
GPR_ASSERT(FLAGS_load_param_1 != 0.0); determ->set_offered_load(FLAGS_determ_load);
determ->set_offered_load(FLAGS_load_param_1); } else if (FLAGS_pareto_base > 0.0) {
break;
}
case grpc::testing::PARETO: {
auto pareto = client_config.mutable_load_params()->mutable_pareto(); auto pareto = client_config.mutable_load_params()->mutable_pareto();
GPR_ASSERT(FLAGS_load_param_1 != 0.0); pareto->set_interarrival_base(FLAGS_pareto_base / 1e6);
GPR_ASSERT(FLAGS_load_param_2 != 0.0); pareto->set_alpha(FLAGS_pareto_alpha);
pareto->set_interarrival_base(FLAGS_load_param_1 / 1e6); } else {
pareto->set_alpha(FLAGS_load_param_2); // Default is closed loop
break; // No need to set up any other load parameters here
}
default:
GPR_ASSERT(false);
break;
} }
ServerConfig server_config; ServerConfig server_config;
server_config.set_server_type(server_type); server_config.set_server_type(server_type);
server_config.set_threads(FLAGS_server_threads); server_config.set_threads(FLAGS_server_threads);
server_config.set_enable_ssl(FLAGS_enable_ssl); server_config.set_use_tls(FLAGS_use_tls);
// If we're running a sync-server streaming test, make sure // If we're running a sync-server streaming test, make sure
// that we have at least as many threads as the active streams // that we have at least as many threads as the active streams

@ -52,19 +52,18 @@ static void RunQPS() {
ClientConfig client_config; ClientConfig client_config;
client_config.set_client_type(ASYNC_CLIENT); client_config.set_client_type(ASYNC_CLIENT);
client_config.set_enable_ssl(false); client_config.set_use_tls(false);
client_config.set_outstanding_rpcs_per_channel(1000); client_config.set_outstanding_rpcs_per_channel(1000);
client_config.set_client_channels(8); client_config.set_client_channels(8);
client_config.set_payload_size(1); client_config.set_payload_size(1);
client_config.set_async_client_threads(8); client_config.set_async_client_threads(8);
client_config.set_rpc_type(UNARY); client_config.set_rpc_type(UNARY);
client_config.set_load_type(POISSON);
client_config.mutable_load_params()->mutable_poisson()->set_offered_load( client_config.mutable_load_params()->mutable_poisson()->set_offered_load(
1000.0); 1000.0);
ServerConfig server_config; ServerConfig server_config;
server_config.set_server_type(ASYNC_SERVER); server_config.set_server_type(ASYNC_SERVER);
server_config.set_enable_ssl(false); server_config.set_use_tls(false);
server_config.set_threads(4); server_config.set_threads(4);
const auto result = const auto result =

@ -52,7 +52,7 @@ static void RunQPS() {
ClientConfig client_config; ClientConfig client_config;
client_config.set_client_type(ASYNC_CLIENT); client_config.set_client_type(ASYNC_CLIENT);
client_config.set_enable_ssl(false); client_config.set_use_tls(false);
client_config.set_outstanding_rpcs_per_channel(1000); client_config.set_outstanding_rpcs_per_channel(1000);
client_config.set_client_channels(8); client_config.set_client_channels(8);
client_config.set_payload_size(1); client_config.set_payload_size(1);
@ -61,7 +61,7 @@ static void RunQPS() {
ServerConfig server_config; ServerConfig server_config;
server_config.set_server_type(ASYNC_SERVER); server_config.set_server_type(ASYNC_SERVER);
server_config.set_enable_ssl(false); server_config.set_use_tls(false);
server_config.set_threads(8); server_config.set_threads(8);
const auto result = const auto result =

@ -56,7 +56,7 @@ static void RunQPS() {
ClientConfig client_config; ClientConfig client_config;
client_config.set_client_type(ASYNC_CLIENT); client_config.set_client_type(ASYNC_CLIENT);
client_config.set_enable_ssl(false); client_config.set_use_tls(false);
client_config.set_outstanding_rpcs_per_channel(1000); client_config.set_outstanding_rpcs_per_channel(1000);
client_config.set_client_channels(8); client_config.set_client_channels(8);
client_config.set_payload_size(1); client_config.set_payload_size(1);
@ -65,7 +65,7 @@ static void RunQPS() {
ServerConfig server_config; ServerConfig server_config;
server_config.set_server_type(ASYNC_SERVER); server_config.set_server_type(ASYNC_SERVER);
server_config.set_enable_ssl(false); server_config.set_use_tls(false);
server_config.set_threads(4); server_config.set_threads(4);
const auto result = const auto result =

@ -52,7 +52,7 @@
#include <grpc++/security/server_credentials.h> #include <grpc++/security/server_credentials.h>
#include "test/core/util/grpc_profiler.h" #include "test/core/util/grpc_profiler.h"
#include "test/proto/perf_control.pb.h" #include "test/proto/perf_tests/perf_control.pb.h"
#include "test/cpp/qps/client.h" #include "test/cpp/qps/client.h"
#include "test/cpp/qps/server.h" #include "test/cpp/qps/server.h"
#include "test/cpp/util/create_test_channel.h" #include "test/cpp/util/create_test_channel.h"

@ -35,7 +35,7 @@
#define TEST_QPS_SERVER_H #define TEST_QPS_SERVER_H
#include "test/cpp/qps/timer.h" #include "test/cpp/qps/timer.h"
#include "test/proto/perf_control.grpc.pb.h" #include "test/proto/perf_tests/perf_control.grpc.pb.h"
namespace grpc { namespace grpc {
namespace testing { namespace testing {

@ -49,7 +49,7 @@
#include <grpc++/security/server_credentials.h> #include <grpc++/security/server_credentials.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "test/proto/perf_control.grpc.pb.h" #include "test/proto/perf_tests/perf_control.grpc.pb.h"
#include "test/cpp/qps/server.h" #include "test/cpp/qps/server.h"
namespace grpc { namespace grpc {

@ -43,7 +43,7 @@
#include <grpc++/server_context.h> #include <grpc++/server_context.h>
#include <grpc++/security/server_credentials.h> #include <grpc++/security/server_credentials.h>
#include "test/proto/perf_control.grpc.pb.h" #include "test/proto/perf_tests/perf_control.grpc.pb.h"
#include "test/cpp/qps/server.h" #include "test/cpp/qps/server.h"
#include "test/cpp/qps/timer.h" #include "test/cpp/qps/timer.h"

@ -52,7 +52,7 @@ static void RunSynchronousStreamingPingPong() {
ClientConfig client_config; ClientConfig client_config;
client_config.set_client_type(SYNCHRONOUS_CLIENT); client_config.set_client_type(SYNCHRONOUS_CLIENT);
client_config.set_enable_ssl(false); client_config.set_use_tls(false);
client_config.set_outstanding_rpcs_per_channel(1); client_config.set_outstanding_rpcs_per_channel(1);
client_config.set_client_channels(1); client_config.set_client_channels(1);
client_config.set_payload_size(1); client_config.set_payload_size(1);
@ -60,7 +60,7 @@ static void RunSynchronousStreamingPingPong() {
ServerConfig server_config; ServerConfig server_config;
server_config.set_server_type(SYNCHRONOUS_SERVER); server_config.set_server_type(SYNCHRONOUS_SERVER);
server_config.set_enable_ssl(false); server_config.set_use_tls(false);
server_config.set_threads(1); server_config.set_threads(1);
const auto result = const auto result =

@ -52,7 +52,7 @@ static void RunSynchronousUnaryPingPong() {
ClientConfig client_config; ClientConfig client_config;
client_config.set_client_type(SYNCHRONOUS_CLIENT); client_config.set_client_type(SYNCHRONOUS_CLIENT);
client_config.set_enable_ssl(false); client_config.set_use_tls(false);
client_config.set_outstanding_rpcs_per_channel(1); client_config.set_outstanding_rpcs_per_channel(1);
client_config.set_client_channels(1); client_config.set_client_channels(1);
client_config.set_payload_size(1); client_config.set_payload_size(1);
@ -60,7 +60,7 @@ static void RunSynchronousUnaryPingPong() {
ServerConfig server_config; ServerConfig server_config;
server_config.set_server_type(SYNCHRONOUS_SERVER); server_config.set_server_type(SYNCHRONOUS_SERVER);
server_config.set_enable_ssl(false); server_config.set_use_tls(false);
server_config.set_threads(1); server_config.set_threads(1);
const auto result = const auto result =

@ -32,7 +32,7 @@
syntax = "proto3"; syntax = "proto3";
import "test/proto/messages.proto"; import "test/proto/messages.proto";
import "test/proto/perf_stats.proto"; import "test/proto/perf_tests/perf_stats.proto";
package grpc.testing; package grpc.testing;
@ -51,14 +51,6 @@ enum RpcType {
STREAMING = 1; STREAMING = 1;
} }
enum LoadType {
CLOSED_LOOP = 0;
POISSON = 1;
UNIFORM = 2;
DETERMINISTIC = 3;
PARETO = 4;
}
message PoissonParams { message PoissonParams {
double offered_load = 1; double offered_load = 1;
} }
@ -83,13 +75,15 @@ message LoadParams {
UniformParams uniform = 2; UniformParams uniform = 2;
DeterministicParams determ = 3; DeterministicParams determ = 3;
ParetoParams pareto = 4; ParetoParams pareto = 4;
// No need to separately specify Closed-Loop as that
// will just be the absence of any of the above
}; };
} }
message ClientConfig { message ClientConfig {
repeated string server_targets = 1; repeated string server_targets = 1;
ClientType client_type = 2; ClientType client_type = 2;
bool enable_ssl = 3; bool use_tls = 3;
int32 outstanding_rpcs_per_channel = 4; int32 outstanding_rpcs_per_channel = 4;
int32 client_channels = 5; int32 client_channels = 5;
int32 payload_size = 6; int32 payload_size = 6;
@ -97,7 +91,6 @@ message ClientConfig {
int32 async_client_threads = 7; int32 async_client_threads = 7;
RpcType rpc_type = 8; RpcType rpc_type = 8;
string host = 9; string host = 9;
LoadType load_type = 10;
LoadParams load_params = 11; LoadParams load_params = 11;
} }
@ -119,7 +112,7 @@ message ClientArgs {
message ServerConfig { message ServerConfig {
ServerType server_type = 1; ServerType server_type = 1;
int32 threads = 2; int32 threads = 2;
bool enable_ssl = 3; bool use_tls = 3;
string host = 4; string host = 4;
} }

@ -13658,10 +13658,10 @@
"test/cpp/util/benchmark_config.h", "test/cpp/util/benchmark_config.h",
"test/proto/messages.grpc.pb.h", "test/proto/messages.grpc.pb.h",
"test/proto/messages.pb.h", "test/proto/messages.pb.h",
"test/proto/perf_control.grpc.pb.h", "test/proto/perf_tests/perf_control.grpc.pb.h",
"test/proto/perf_control.pb.h", "test/proto/perf_tests/perf_control.pb.h",
"test/proto/perf_stats.grpc.pb.h", "test/proto/perf_tests/perf_stats.grpc.pb.h",
"test/proto/perf_stats.pb.h" "test/proto/perf_tests/perf_stats.pb.h"
], ],
"language": "c++", "language": "c++",
"name": "qps", "name": "qps",

@ -155,21 +155,21 @@
</ClCompile> </ClCompile>
<ClInclude Include="..\..\..\test\proto\messages.grpc.pb.h"> <ClInclude Include="..\..\..\test\proto\messages.grpc.pb.h">
</ClInclude> </ClInclude>
<ClCompile Include="..\..\..\test\proto\perf_control.pb.cc"> <ClCompile Include="..\..\..\test\proto\perf_tests\perf_control.pb.cc">
</ClCompile> </ClCompile>
<ClInclude Include="..\..\..\test\proto\perf_control.pb.h"> <ClInclude Include="..\..\..\test\proto\perf_tests\perf_control.pb.h">
</ClInclude> </ClInclude>
<ClCompile Include="..\..\..\test\proto\perf_control.grpc.pb.cc"> <ClCompile Include="..\..\..\test\proto\perf_tests\perf_control.grpc.pb.cc">
</ClCompile> </ClCompile>
<ClInclude Include="..\..\..\test\proto\perf_control.grpc.pb.h"> <ClInclude Include="..\..\..\test\proto\perf_tests\perf_control.grpc.pb.h">
</ClInclude> </ClInclude>
<ClCompile Include="..\..\..\test\proto\perf_stats.pb.cc"> <ClCompile Include="..\..\..\test\proto\perf_tests\perf_stats.pb.cc">
</ClCompile> </ClCompile>
<ClInclude Include="..\..\..\test\proto\perf_stats.pb.h"> <ClInclude Include="..\..\..\test\proto\perf_tests\perf_stats.pb.h">
</ClInclude> </ClInclude>
<ClCompile Include="..\..\..\test\proto\perf_stats.grpc.pb.cc"> <ClCompile Include="..\..\..\test\proto\perf_tests\perf_stats.grpc.pb.cc">
</ClCompile> </ClCompile>
<ClInclude Include="..\..\..\test\proto\perf_stats.grpc.pb.h"> <ClInclude Include="..\..\..\test\proto\perf_tests\perf_stats.grpc.pb.h">
</ClInclude> </ClInclude>
<ClCompile Include="..\..\..\test\cpp\qps\perf_db.pb.cc"> <ClCompile Include="..\..\..\test\cpp\qps\perf_db.pb.cc">
</ClCompile> </ClCompile>

@ -4,11 +4,11 @@
<ClCompile Include="..\..\..\test\proto\messages.proto"> <ClCompile Include="..\..\..\test\proto\messages.proto">
<Filter>test\proto</Filter> <Filter>test\proto</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\test\proto\perf_control.proto"> <ClCompile Include="..\..\..\test\proto\perf_tests\perf_control.proto">
<Filter>test\proto</Filter> <Filter>test\proto\perf_tests</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\test\proto\perf_stats.proto"> <ClCompile Include="..\..\..\test\proto\perf_tests\perf_stats.proto">
<Filter>test\proto</Filter> <Filter>test\proto\perf_tests</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\test\cpp\qps\perf_db.proto"> <ClCompile Include="..\..\..\test\cpp\qps\perf_db.proto">
<Filter>test\cpp\qps</Filter> <Filter>test\cpp\qps</Filter>
@ -96,6 +96,9 @@
<Filter Include="test\proto"> <Filter Include="test\proto">
<UniqueIdentifier>{44e63a33-67f4-0575-e87a-711a7c9111e2}</UniqueIdentifier> <UniqueIdentifier>{44e63a33-67f4-0575-e87a-711a7c9111e2}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="test\proto\perf_tests">
<UniqueIdentifier>{cf788def-630c-8a5f-9a8c-6abdd500d712}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
</Project> </Project>

Loading…
Cancel
Save