Interop stress tests

pull/3868/head
Sree Kuchibhotla 9 years ago
parent b839682c0b
commit 728a6104d5
  1. 6
      .gitignore
  2. 55
      Makefile
  3. 21
      build.yaml
  4. 47
      test/cpp/interop/interop_client.cc
  5. 2
      test/cpp/interop/interop_client.h
  6. 158
      test/cpp/interop/stress_interop_client.cc
  7. 103
      test/cpp/interop/stress_interop_client.h
  8. 221
      test/cpp/interop/stress_test.cc
  9. 30
      tools/run_tests/sources_and_headers.json
  10. 18
      tools/run_tests/tests.json
  11. 227
      vsprojects/vcxproj/test/stress_test/stress_test.vcxproj
  12. 47
      vsprojects/vcxproj/test/stress_test/stress_test.vcxproj.filters

6
.gitignore vendored

@ -45,3 +45,9 @@ portlog.txt
# gyp generated make files
*-gyp.mk
out
# YCM config files
.ycm_extra_conf.py
# Core dump files
core

File diff suppressed because one or more lines are too long

@ -2093,6 +2093,27 @@ targets:
- mac
- linux
- posix
- name: stress_test
build: test
language: c++
headers:
- test/cpp/interop/interop_client.h
- test/cpp/interop/stress_interop_client.h
src:
- test/proto/empty.proto
- test/proto/messages.proto
- test/proto/test.proto
- test/cpp/interop/interop_client.cc
- test/cpp/interop/stress_interop_client.cc
- test/cpp/interop/stress_test.cc
deps:
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
- grpc++_test_config
- name: sync_streaming_ping_pong_test
build: test
language: c++

@ -83,7 +83,7 @@ CompressionType GetInteropCompressionTypeFromCompressionAlgorithm(
} // namespace
InteropClient::InteropClient(std::shared_ptr<Channel> channel)
: channel_(channel) {}
: channel_(channel), stub_(TestService::NewStub(channel)) {}
void InteropClient::AssertOkOrPrintErrorStatus(const Status& s) {
if (s.ok()) {
@ -96,13 +96,12 @@ void InteropClient::AssertOkOrPrintErrorStatus(const Status& s) {
void InteropClient::DoEmpty() {
gpr_log(GPR_INFO, "Sending an empty rpc...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
Empty request = Empty::default_instance();
Empty response = Empty::default_instance();
ClientContext context;
Status s = stub->EmptyCall(&context, request, &response);
Status s = stub_->EmptyCall(&context, request, &response);
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Empty rpc done.");
@ -111,7 +110,6 @@ void InteropClient::DoEmpty() {
// Shared code to set large payload, make rpc and check response payload.
void InteropClient::PerformLargeUnary(SimpleRequest* request,
SimpleResponse* response) {
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
InteropClientContextInspector inspector(context);
@ -121,7 +119,7 @@ void InteropClient::PerformLargeUnary(SimpleRequest* request,
grpc::string payload(kLargeRequestSize, '\0');
request->mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
Status s = stub->UnaryCall(&context, *request, response);
Status s = stub_->UnaryCall(&context, *request, response);
// Compression related checks.
GPR_ASSERT(request->response_compression() ==
@ -187,11 +185,10 @@ void InteropClient::DoOauth2AuthToken(const grpc::string& username,
SimpleResponse response;
request.set_fill_username(true);
request.set_fill_oauth_scope(true);
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
Status s = stub->UnaryCall(&context, request, &response);
Status s = stub_->UnaryCall(&context, request, &response);
AssertOkOrPrintErrorStatus(s);
GPR_ASSERT(!response.username().empty());
@ -207,7 +204,6 @@ void InteropClient::DoPerRpcCreds(const grpc::string& json_key) {
SimpleRequest request;
SimpleResponse response;
request.set_fill_username(true);
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
std::chrono::seconds token_lifetime = std::chrono::hours(1);
@ -216,7 +212,7 @@ void InteropClient::DoPerRpcCreds(const grpc::string& json_key) {
context.set_credentials(creds);
Status s = stub->UnaryCall(&context, request, &response);
Status s = stub_->UnaryCall(&context, request, &response);
AssertOkOrPrintErrorStatus(s);
GPR_ASSERT(!response.username().empty());
@ -269,14 +265,13 @@ void InteropClient::DoLargeCompressedUnary() {
void InteropClient::DoRequestStreaming() {
gpr_log(GPR_INFO, "Sending request steaming rpc ...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
StreamingInputCallRequest request;
StreamingInputCallResponse response;
std::unique_ptr<ClientWriter<StreamingInputCallRequest>> stream(
stub->StreamingInputCall(&context, &response));
stub_->StreamingInputCall(&context, &response));
int aggregated_payload_size = 0;
for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
@ -295,7 +290,6 @@ void InteropClient::DoRequestStreaming() {
void InteropClient::DoResponseStreaming() {
gpr_log(GPR_INFO, "Receiving response steaming rpc ...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
StreamingOutputCallRequest request;
@ -305,7 +299,7 @@ void InteropClient::DoResponseStreaming() {
}
StreamingOutputCallResponse response;
std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
stub->StreamingOutputCall(&context, request));
stub_->StreamingOutputCall(&context, request));
unsigned int i = 0;
while (stream->Read(&response)) {
@ -320,7 +314,6 @@ void InteropClient::DoResponseStreaming() {
}
void InteropClient::DoResponseCompressedStreaming() {
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
const CompressionType compression_types[] = {NONE, GZIP, DEFLATE};
const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE, RANDOM};
@ -348,7 +341,7 @@ void InteropClient::DoResponseCompressedStreaming() {
StreamingOutputCallResponse response;
std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
stub->StreamingOutputCall(&context, request));
stub_->StreamingOutputCall(&context, request));
size_t k = 0;
while (stream->Read(&response)) {
@ -401,7 +394,6 @@ void InteropClient::DoResponseCompressedStreaming() {
void InteropClient::DoResponseStreamingWithSlowConsumer() {
gpr_log(GPR_INFO, "Receiving response steaming rpc with slow consumer ...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
StreamingOutputCallRequest request;
@ -412,7 +404,7 @@ void InteropClient::DoResponseStreamingWithSlowConsumer() {
}
StreamingOutputCallResponse response;
std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
stub->StreamingOutputCall(&context, request));
stub_->StreamingOutputCall(&context, request));
int i = 0;
while (stream->Read(&response)) {
@ -431,12 +423,11 @@ void InteropClient::DoResponseStreamingWithSlowConsumer() {
void InteropClient::DoHalfDuplex() {
gpr_log(GPR_INFO, "Sending half-duplex streaming rpc ...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
StreamingOutputCallResponse>>
stream(stub->HalfDuplexCall(&context));
stream(stub_->HalfDuplexCall(&context));
StreamingOutputCallRequest request;
ResponseParameters* response_parameter = request.add_response_parameters();
@ -461,12 +452,11 @@ void InteropClient::DoHalfDuplex() {
void InteropClient::DoPingPong() {
gpr_log(GPR_INFO, "Sending Ping Pong streaming rpc ...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
StreamingOutputCallResponse>>
stream(stub->FullDuplexCall(&context));
stream(stub_->FullDuplexCall(&context));
StreamingOutputCallRequest request;
request.set_response_type(PayloadType::COMPRESSABLE);
@ -491,14 +481,13 @@ void InteropClient::DoPingPong() {
void InteropClient::DoCancelAfterBegin() {
gpr_log(GPR_INFO, "Sending request steaming rpc ...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
StreamingInputCallRequest request;
StreamingInputCallResponse response;
std::unique_ptr<ClientWriter<StreamingInputCallRequest>> stream(
stub->StreamingInputCall(&context, &response));
stub_->StreamingInputCall(&context, &response));
gpr_log(GPR_INFO, "Trying to cancel...");
context.TryCancel();
@ -509,12 +498,11 @@ void InteropClient::DoCancelAfterBegin() {
void InteropClient::DoCancelAfterFirstResponse() {
gpr_log(GPR_INFO, "Sending Ping Pong streaming rpc ...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
StreamingOutputCallResponse>>
stream(stub->FullDuplexCall(&context));
stream(stub_->FullDuplexCall(&context));
StreamingOutputCallRequest request;
request.set_response_type(PayloadType::COMPRESSABLE);
@ -534,7 +522,6 @@ void InteropClient::DoCancelAfterFirstResponse() {
void InteropClient::DoTimeoutOnSleepingServer() {
gpr_log(GPR_INFO, "Sending Ping Pong streaming rpc with a short deadline...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
std::chrono::system_clock::time_point deadline =
@ -542,7 +529,7 @@ void InteropClient::DoTimeoutOnSleepingServer() {
context.set_deadline(deadline);
std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
StreamingOutputCallResponse>>
stream(stub->FullDuplexCall(&context));
stream(stub_->FullDuplexCall(&context));
StreamingOutputCallRequest request;
request.mutable_payload()->set_body(grpc::string(27182, '\0'));
@ -555,12 +542,11 @@ void InteropClient::DoTimeoutOnSleepingServer() {
void InteropClient::DoEmptyStream() {
gpr_log(GPR_INFO, "Starting empty_stream.");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
StreamingOutputCallResponse>>
stream(stub->FullDuplexCall(&context));
stream(stub_->FullDuplexCall(&context));
stream->WritesDone();
StreamingOutputCallResponse response;
GPR_ASSERT(stream->Read(&response) == false);
@ -571,7 +557,6 @@ void InteropClient::DoEmptyStream() {
void InteropClient::DoStatusWithMessage() {
gpr_log(GPR_INFO, "Sending RPC with a request for status code 2 and message");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
SimpleRequest request;
@ -581,7 +566,7 @@ void InteropClient::DoStatusWithMessage() {
grpc::string test_msg = "This is a test message";
requested_status->set_message(test_msg);
Status s = stub->UnaryCall(&context, request, &response);
Status s = stub_->UnaryCall(&context, request, &response);
GPR_ASSERT(s.error_code() == grpc::StatusCode::UNKNOWN);
GPR_ASSERT(s.error_message() == test_msg);

@ -39,6 +39,7 @@
#include <grpc/grpc.h>
#include <grpc++/channel.h>
#include "test/proto/messages.grpc.pb.h"
#include "test/proto/test.grpc.pb.h"
namespace grpc {
namespace testing {
@ -80,6 +81,7 @@ class InteropClient {
void AssertOkOrPrintErrorStatus(const Status& s);
std::shared_ptr<Channel> channel_;
std::unique_ptr<TestService::Stub> stub_;
};
} // namespace testing

@ -0,0 +1,158 @@
/*
*
* 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.
*is % allowed in string
*/
#include <memory>
#include <string>
#include <vector>
#include <grpc++/create_channel.h>
#include "test/cpp/interop/interop_client.h"
#include "test/cpp/interop/stress_interop_client.h"
namespace grpc {
namespace testing {
using std::pair;
using std::string;
using std::vector;
TestSelector::TestSelector(const vector<pair<TestCaseType, int>>& tests)
: tests_(tests) {
total_weight_ = 0;
for (auto it = tests.begin(); it != tests.end(); it++) {
total_weight_ += it->second;
}
}
TestCaseType TestSelector::GetNextTest() const {
int random = 0;
TestCaseType selected_test = UNKNOWN_TEST;
// Get a random number from [0 to the total_weight - 1]
random = rand() % total_weight_;
int weight_sofar = 0;
for (auto it = tests_.begin(); it != tests_.end(); it++) {
weight_sofar += it->second;
if (random < weight_sofar) {
selected_test = it->first;
break;
}
}
// It is a bug in the logic if no test is selected at this point
GPR_ASSERT(selected_test != UNKNOWN_TEST);
return selected_test;
}
StressTestInteropClient::StressTestInteropClient(
int test_id, const string& server_address,
const TestSelector& test_selector, long test_duration_secs,
long sleep_duration_ms)
: test_id_(test_id),
server_address_(server_address),
test_selector_(test_selector),
test_duration_secs_(test_duration_secs),
sleep_duration_ms_(sleep_duration_ms) {
// TODO(sreek): This will change once we add support for other tests
// that won't work with InsecureCredentials()
std::shared_ptr<Channel> channel(
CreateChannel(server_address, InsecureCredentials()));
interop_client_.reset(new InteropClient(channel));
}
void StressTestInteropClient::MainLoop() {
gpr_log(GPR_INFO, "Running test %d. ServerAddr: %s", test_id_,
server_address_.c_str());
gpr_timespec test_end_time =
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_seconds(test_duration_secs_, GPR_TIMESPAN));
gpr_timespec current_time = gpr_now(GPR_CLOCK_REALTIME);
while (test_duration_secs_ < 0 ||
gpr_time_cmp(current_time, test_end_time) < 0) {
// Select the test case to execute based on the weights and execute it
TestCaseType test_case = test_selector_.GetNextTest();
gpr_log(GPR_INFO, "%d - Executing the test case %d", test_id_, test_case);
RunTest(test_case);
// Sleep between successive calls if needed
if (sleep_duration_ms_ > 0) {
gpr_timespec sleep_time = gpr_time_add(
current_time, gpr_time_from_millis(sleep_duration_ms_, GPR_TIMESPAN));
gpr_sleep_until(sleep_time);
}
current_time = gpr_now(GPR_CLOCK_REALTIME);
}
}
// TODO(sree): Add all interop tests
void StressTestInteropClient::RunTest(TestCaseType test_case) {
switch (test_case) {
case EMPTY_UNARY: {
interop_client_->DoEmpty();
break;
}
case LARGE_UNARY: {
interop_client_->DoLargeUnary();
break;
}
case LARGE_COMPRESSED_UNARY: {
interop_client_->DoLargeCompressedUnary();
break;
}
case CLIENT_STREAMING: {
interop_client_->DoRequestStreaming();
break;
}
case SERVER_STREAMING: {
interop_client_->DoResponseStreaming();
break;
}
case EMPTY_STREAM: {
interop_client_->DoEmptyStream();
break;
}
default: {
gpr_log(GPR_ERROR, "Invalid test case (%d)", test_case);
GPR_ASSERT(false);
break;
}
}
}
} // namespace testing
} // namespace grpc

@ -0,0 +1,103 @@
/*
*
* 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.
*is % allowed in string
*/
#ifndef GRPC_TEST_CPP_STRESS_INTEROP_CLIENT_H
#define GRPC_TEST_CPP_STRESS_INTEROP_CLIENT_H
#include <memory>
#include <string>
#include <vector>
#include <grpc++/create_channel.h>
#include "test/cpp/interop/interop_client.h"
namespace grpc {
namespace testing {
using std::pair;
using std::string;
using std::vector;
// TODO(sreek): Add more test cases here in future
enum TestCaseType {
UNKNOWN_TEST = -1,
EMPTY_UNARY = 0,
LARGE_UNARY = 1,
LARGE_COMPRESSED_UNARY = 2,
CLIENT_STREAMING = 3,
SERVER_STREAMING = 4,
EMPTY_STREAM = 5
};
const vector<pair<TestCaseType, string>> kTestCaseList = {
{EMPTY_UNARY, "empty_unary"},
{LARGE_UNARY, "large_unary"},
{LARGE_COMPRESSED_UNARY, "large_compressed_unary"},
{CLIENT_STREAMING, "client_streaming"},
{SERVER_STREAMING, "server_streaming"},
{EMPTY_STREAM, "empty_stream"}};
class TestSelector {
public:
TestSelector(const vector<pair<TestCaseType, int>>& tests);
TestCaseType GetNextTest() const;
private:
const vector<pair<TestCaseType, int>> tests_;
int total_weight_;
};
class StressTestInteropClient {
public:
StressTestInteropClient(int test_id, const string& server_address,
const TestSelector& test_selector,
long test_duration_secs, long sleep_duration_ms);
void MainLoop(); // The main test. Use this as the thread entry point.
private:
void RunTest(TestCaseType test_case);
int test_id_;
std::unique_ptr<InteropClient> interop_client_;
const string& server_address_;
const TestSelector& test_selector_;
long test_duration_secs_;
long sleep_duration_ms_;
};
} // namespace testing
} // namespace grpc
#endif // GRPC_TEST_CPP_STRESS_INTEROP_CLIENT_H

@ -0,0 +1,221 @@
/*
*
* 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.
*is % allowed in string
*/
#include <memory>
#include <string>
#include <thread>
#include <utility>
#include <vector>
#include <gflags/gflags.h>
#include <grpc/support/time.h>
#include <grpc++/create_channel.h>
#include <grpc++/grpc++.h>
#include "test/cpp/interop/interop_client.h"
#include "test/cpp/interop/stress_interop_client.h"
#include "test/cpp/util/test_config.h"
DEFINE_int32(sleep_duration_ms, 0,
"The duration (in millisec) between two"
" consecutive test calls (per server) issued by the server.");
DEFINE_int32(test_duration_secs, -1,
"The length of time (in seconds) to run"
" the test. Enter -1 if the test should run continuously until"
" forcefully terminated.");
DEFINE_string(server_addresses, "localhost:8080",
"The list of server"
" addresses in the format:\n"
" \"<name_1>:<port_1>,<name_2>:<port_1>...<name_N>:<port_N>\"\n"
" Note: <name> can be servername or IP address.");
// TODO(sreek): Add more test cases here in future
DEFINE_string(test_cases, "",
"List of test cases to call along with the"
" relative weights in the following format:\n"
" \"<testcase_1:w_1>,<testcase_2:w_2>...<testcase_n:w_n>\"\n"
" The following testcases are currently supported:\n"
" empty_unary\n"
" large_unary\n"
" large_compressed_unary\n"
" client_streaming\n"
" server_streaming\n"
" empty_stream\n"
" Example: \"empty_unary:20,large_unary:10,empty_stream:70\"\n"
" The above will execute 'empty_unary', 20% of the time,"
" 'large_unary', 10% of the time and 'empty_stream' the remaining"
" 70% of the time");
using std::make_pair;
using std::pair;
using std::string;
using std::thread;
using std::vector;
using grpc::testing::kTestCaseList;
using grpc::testing::StressTestInteropClient;
using grpc::testing::TestCaseType;
using grpc::testing::TestSelector;
using grpc::testing::UNKNOWN_TEST;
TestCaseType get_test_type_from_name(const string& test_name) {
TestCaseType test_case = UNKNOWN_TEST;
for (auto it = kTestCaseList.begin(); it != kTestCaseList.end(); it++) {
if (test_name == it->second) {
test_case = it->first;
break;
}
}
return test_case;
}
bool ParseCommaDelimitedString(const string& comma_delimited_str,
vector<string>& tokens) {
size_t bpos = 0;
size_t epos = string::npos;
while ((epos = comma_delimited_str.find(',', bpos)) != string::npos) {
tokens.emplace_back(comma_delimited_str.substr(bpos, epos - bpos));
bpos = epos + 1;
}
tokens.emplace_back(comma_delimited_str.substr(bpos)); // Last token
return true;
}
// Input: Test case string "<testcase_name:weight>,<testcase_name:weight>...."
// Output:
// - Whether parsing was successful (return value)
// - Vector of (test_type_enum, weight) pairs
bool ParseTestCasesString(const string& test_cases,
vector<pair<TestCaseType, int>>& tests) {
bool is_success = true;
vector<string> tokens;
ParseCommaDelimitedString(test_cases, tokens);
for (auto it = tokens.begin(); it != tokens.end(); it++) {
// Token is in the form <test_name>:<test_weight>
size_t colon_pos = it->find(':');
if (colon_pos == string::npos) {
gpr_log(GPR_ERROR, "Error in parsing test case string: %s", it->c_str());
is_success = false;
break;
}
string test_name = it->substr(0, colon_pos);
int weight = std::stoi(it->substr(colon_pos + 1));
TestCaseType test_case = get_test_type_from_name(test_name);
if (test_case == UNKNOWN_TEST) {
gpr_log(GPR_ERROR, "Unknown test case: %s", test_name.c_str());
is_success = false;
break;
}
tests.emplace_back(std::make_pair(test_case, weight));
}
return is_success;
}
// For debugging purposes
void LogParameterInfo(const vector<string>& addresses,
const vector<pair<TestCaseType, int>>& tests) {
gpr_log(GPR_INFO, "server_addresses: %s", FLAGS_server_addresses.c_str());
gpr_log(GPR_INFO, "test_cases : %s", FLAGS_test_cases.c_str());
gpr_log(GPR_INFO, "sleep_duration_ms: %d", FLAGS_sleep_duration_ms);
gpr_log(GPR_INFO, "test_duration_secs: %d", FLAGS_test_duration_secs);
int num = 0;
for (auto it = addresses.begin(); it != addresses.end(); it++) {
gpr_log(GPR_INFO, "%d:%s", ++num, it->c_str());
}
num = 0;
for (auto it = tests.begin(); it != tests.end(); it++) {
TestCaseType test_case = it->first;
int weight = it->second;
gpr_log(GPR_INFO, "%d. TestCaseType: %d, Weight: %d", ++num, test_case,
weight);
}
}
int main(int argc, char** argv) {
grpc::testing::InitTest(&argc, &argv, true);
gpr_log(GPR_INFO, "starting test..");
srand(time(NULL));
// Parse the server addresses
vector<string> server_addresses;
ParseCommaDelimitedString(FLAGS_server_addresses, server_addresses);
// Parse test cases and weights
if (FLAGS_test_cases.length() == 0) {
gpr_log(GPR_INFO, "Test cases string is empty");
return 1;
}
vector<pair<TestCaseType, int>> tests;
if (!ParseTestCasesString(FLAGS_test_cases, tests)) {
gpr_log(GPR_ERROR, "Error in parsing test cases string %s ",
FLAGS_test_cases.c_str());
return 1;
}
LogParameterInfo(server_addresses, tests);
TestSelector test_selector(tests);
vector<thread> test_threads;
int thread_idx = 0;
for (auto it = server_addresses.begin(); it != server_addresses.end(); it++) {
StressTestInteropClient* client = new StressTestInteropClient(
++thread_idx, *it, test_selector, FLAGS_test_duration_secs,
FLAGS_sleep_duration_ms);
test_threads.emplace_back(
thread(&StressTestInteropClient::MainLoop, client));
}
for (auto it = test_threads.begin(); it != test_threads.end(); it++) {
it->join();
}
return 0;
}

@ -1654,6 +1654,36 @@
"test/cpp/end2end/streaming_throughput_test.cc"
]
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc++",
"grpc++_test_config",
"grpc++_test_util",
"grpc_test_util"
],
"headers": [
"test/cpp/interop/interop_client.h",
"test/cpp/interop/stress_interop_client.h",
"test/proto/empty.grpc.pb.h",
"test/proto/empty.pb.h",
"test/proto/messages.grpc.pb.h",
"test/proto/messages.pb.h",
"test/proto/test.grpc.pb.h",
"test/proto/test.pb.h"
],
"language": "c++",
"name": "stress_test",
"src": [
"test/cpp/interop/interop_client.cc",
"test/cpp/interop/interop_client.h",
"test/cpp/interop/stress_interop_client.cc",
"test/cpp/interop/stress_interop_client.h",
"test/cpp/interop/stress_test.cc"
]
},
{
"deps": [
"gpr",

@ -1599,6 +1599,24 @@
"posix"
]
},
{
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"exclude_configs": [],
"flaky": false,
"language": "c++",
"name": "stress_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
]
},
{
"ci_platforms": [
"linux",

@ -0,0 +1,227 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{09500BEB-9A09-F52E-9A3D-D1D27D7177F0}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
<PlatformToolset>v100</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\..\vsprojects\cpptest.props" />
<Import Project="..\..\..\..\vsprojects\global.props" />
<Import Project="..\..\..\..\vsprojects\openssl.props" />
<Import Project="..\..\..\..\vsprojects\protobuf.props" />
<Import Project="..\..\..\..\vsprojects\winsock.props" />
<Import Project="..\..\..\..\vsprojects\zlib.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<TargetName>stress_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TargetName>stress_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\test\cpp\interop\interop_client.h" />
<ClInclude Include="..\..\..\..\test\cpp\interop\stress_interop_client.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\test\proto\empty.pb.cc">
</ClCompile>
<ClInclude Include="..\..\..\..\test\proto\empty.pb.h">
</ClInclude>
<ClCompile Include="..\..\..\..\test\proto\empty.grpc.pb.cc">
</ClCompile>
<ClInclude Include="..\..\..\..\test\proto\empty.grpc.pb.h">
</ClInclude>
<ClCompile Include="..\..\..\..\test\proto\messages.pb.cc">
</ClCompile>
<ClInclude Include="..\..\..\..\test\proto\messages.pb.h">
</ClInclude>
<ClCompile Include="..\..\..\..\test\proto\messages.grpc.pb.cc">
</ClCompile>
<ClInclude Include="..\..\..\..\test\proto\messages.grpc.pb.h">
</ClInclude>
<ClCompile Include="..\..\..\..\test\proto\test.pb.cc">
</ClCompile>
<ClInclude Include="..\..\..\..\test\proto\test.pb.h">
</ClInclude>
<ClCompile Include="..\..\..\..\test\proto\test.grpc.pb.cc">
</ClCompile>
<ClInclude Include="..\..\..\..\test\proto\test.grpc.pb.h">
</ClInclude>
<ClCompile Include="..\..\..\..\test\cpp\interop\interop_client.cc">
</ClCompile>
<ClCompile Include="..\..\..\..\test\cpp\interop\stress_interop_client.cc">
</ClCompile>
<ClCompile Include="..\..\..\..\test\cpp\interop\stress_test.cc">
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
<Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
<Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
<Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
<Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
<Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
<Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc++_test_config\grpc++_test_config.vcxproj">
<Project>{3F7D093D-11F9-C4BC-BEB7-18EB28E3F290}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
<Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
<Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
<Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
<Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
<Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
<Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
<Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
</Target>
</Project>

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\..\..\..\test\proto\empty.proto">
<Filter>test\proto</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\proto\messages.proto">
<Filter>test\proto</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\proto\test.proto">
<Filter>test\proto</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\cpp\interop\interop_client.cc">
<Filter>test\cpp\interop</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\cpp\interop\stress_interop_client.cc">
<Filter>test\cpp\interop</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\cpp\interop\stress_test.cc">
<Filter>test\cpp\interop</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\test\cpp\interop\interop_client.h">
<Filter>test\cpp\interop</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\test\cpp\interop\stress_interop_client.h">
<Filter>test\cpp\interop</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="test">
<UniqueIdentifier>{0fddcdfd-8fd7-bb4b-e21d-f53728f4a766}</UniqueIdentifier>
</Filter>
<Filter Include="test\cpp">
<UniqueIdentifier>{a5c0e3f9-aa0c-45cd-87b0-b93b83e4ab9e}</UniqueIdentifier>
</Filter>
<Filter Include="test\cpp\interop">
<UniqueIdentifier>{7afcf5a8-556a-6be3-15d4-b00b2518f8fb}</UniqueIdentifier>
</Filter>
<Filter Include="test\proto">
<UniqueIdentifier>{7172a335-47bf-8284-380d-a28a05c07311}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
Loading…
Cancel
Save