[PSM Interop] Extend headers matching. (#34082)

1. Headers will now be matched ignoring the case.
2. "*" can now be set to return all metadata values.
pull/34054/head^2
Eugene Ostroukhov 1 year ago committed by GitHub
parent a526a091ae
commit 89209debad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      CMakeLists.txt
  2. 1
      build_autogenerated.yaml
  3. 35
      test/cpp/interop/xds_stats_watcher.cc
  4. 4
      test/cpp/interop/xds_stats_watcher.h
  5. 43
      test/cpp/interop/xds_stats_watcher_test.cc

4
CMakeLists.txt generated

@ -26095,8 +26095,6 @@ if(gRPC_BUILD_TESTS)
add_executable(wait_for_callback_test
src/core/lib/promise/activity.cc
test/core/promise/wait_for_callback_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_compile_features(wait_for_callback_test PUBLIC cxx_std_14)
target_include_directories(wait_for_callback_test
@ -26121,8 +26119,8 @@ target_include_directories(wait_for_callback_test
target_link_libraries(wait_for_callback_test
${_gRPC_BASELIB_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ZLIB_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
absl::type_traits
absl::statusor
gpr

@ -16459,6 +16459,7 @@ targets:
- src/core/lib/promise/activity.cc
- test/core/promise/wait_for_callback_test.cc
deps:
- gtest
- absl/meta:type_traits
- absl/status:statusor
- gpr

@ -16,27 +16,40 @@
#include <map>
#include "absl/algorithm/container.h"
#include "absl/strings/ascii.h"
namespace grpc {
namespace testing {
namespace {
LoadBalancerStatsResponse::RpcMetadata BuildRpcMetadata(
absl::Span<const std::string> metadata_keys,
const std::unordered_set<std::string>& included_keys, bool include_all_keys,
const std::multimap<grpc::string_ref, grpc::string_ref>& initial_metadata) {
LoadBalancerStatsResponse::RpcMetadata rpc_metadata;
for (const auto& key : metadata_keys) {
auto matching = initial_metadata.equal_range(key);
for (auto value = matching.first; value != matching.second; ++value) {
for (const auto& key_value : initial_metadata) {
absl::string_view key(key_value.first.data(), key_value.first.length());
if (include_all_keys ||
included_keys.find(absl::AsciiStrToLower(key)) != included_keys.end()) {
auto entry = rpc_metadata.add_metadata();
entry->set_key(key);
entry->set_value(
absl::string_view(value->second.data(), value->second.length()));
entry->set_value(absl::string_view(key_value.second.data(),
key_value.second.length()));
}
}
return rpc_metadata;
}
std::unordered_set<std::string> ToLowerCase(
absl::Span<const std::string> strings) {
std::unordered_set<std::string> result;
for (const auto& str : strings) {
result.emplace(absl::AsciiStrToLower(str));
}
return result;
}
} // namespace
XdsStatsWatcher::XdsStatsWatcher(int start_id, int end_id,
@ -44,7 +57,11 @@ XdsStatsWatcher::XdsStatsWatcher(int start_id, int end_id,
: start_id_(start_id),
end_id_(end_id),
rpcs_needed_(end_id - start_id),
metadata_keys_(metadata_keys.begin(), metadata_keys.end()) {}
metadata_keys_(ToLowerCase(metadata_keys)),
include_all_metadata_(
absl::c_any_of(metadata_keys, [](absl::string_view key) {
return absl::StripAsciiWhitespace(key) == "*";
})) {}
void XdsStatsWatcher::RpcCompleted(
const AsyncClientCallResult& call, const std::string& peer,
@ -62,8 +79,8 @@ void XdsStatsWatcher::RpcCompleted(
// RPC is counted into both per-peer bin and per-method-per-peer bin.
rpcs_by_peer_[peer]++;
rpcs_by_type_[call.rpc_type][peer]++;
*metadata_by_peer_[peer].add_rpc_metadata() =
BuildRpcMetadata(metadata_keys_, initial_metadata);
*metadata_by_peer_[peer].add_rpc_metadata() = BuildRpcMetadata(
metadata_keys_, include_all_metadata_, initial_metadata);
}
rpcs_needed_--;
// Report accumulated stats.

@ -29,6 +29,7 @@
#include <sstream>
#include <string>
#include <thread>
#include <unordered_set>
#include <vector>
#include "absl/status/status.h"
@ -99,7 +100,8 @@ class XdsStatsWatcher {
LoadBalancerAccumulatedStatsResponse accumulated_stats_;
std::mutex m_;
std::condition_variable cv_;
std::vector<std::string> metadata_keys_;
std::unordered_set<std::string> metadata_keys_;
bool include_all_metadata_ = false;
std::map<std::string, LoadBalancerStatsResponse::MetadataByPeer>
metadata_by_peer_;
};

@ -73,6 +73,49 @@ TEST(XdsStatsWatcherTest, WaitForRpcStatsResponse) {
expected.DebugString());
}
TEST(XdsStatsWatcherTest, WaitForRpcStatsResponseIgnoresCase) {
// "k3" will be ignored
XdsStatsWatcher watcher(0, 3, {"k1", "K2"});
watcher.RpcCompleted(BuildCallResult(0), "peer1",
{{"K1", "v1"}, {"k2", "v2"}, {"k3", "v3"}});
watcher.RpcCompleted(BuildCallResult(1), "peer1", {{"k1", "v4"}});
watcher.RpcCompleted(BuildCallResult(2), "peer2",
{{"k1", "v5"}, {"K2", "v6"}, {"k3", "v7"}});
LoadBalancerStatsResponse expected;
expected.mutable_rpcs_by_peer()->insert({{"peer1", 2}, {"peer2", 1}});
expected.mutable_metadatas_by_peer()->insert({
{"peer1", BuildMetadatas({{{"K1", "v1"}, {"k2", "v2"}}, {{"k1", "v4"}}})},
{"peer2", BuildMetadatas({{{"K2", "v6"}, {"k1", "v5"}}})},
});
(*expected.mutable_rpcs_by_method())["UnaryCall"]
.mutable_rpcs_by_peer()
->insert({{"peer1", 2}, {"peer2", 1}});
EXPECT_EQ(watcher.WaitForRpcStatsResponse(0).DebugString(),
expected.DebugString());
}
TEST(XdsStatsWatcherTest, WaitForRpcStatsResponseReturnsAll) {
// "k3" will be ignored
XdsStatsWatcher watcher(0, 3, {"*"});
watcher.RpcCompleted(BuildCallResult(0), "peer1",
{{"K1", "v1"}, {"k2", "v2"}, {"k3", "v3"}});
watcher.RpcCompleted(BuildCallResult(1), "peer1", {{"k1", "v4"}});
watcher.RpcCompleted(BuildCallResult(2), "peer2",
{{"k1", "v5"}, {"K2", "v6"}, {"k3", "v7"}});
LoadBalancerStatsResponse expected;
expected.mutable_rpcs_by_peer()->insert({{"peer1", 2}, {"peer2", 1}});
expected.mutable_metadatas_by_peer()->insert({
{"peer1", BuildMetadatas({{{"K1", "v1"}, {"k2", "v2"}, {"k3", "v3"}},
{{"k1", "v4"}}})},
{"peer2", BuildMetadatas({{{"K2", "v6"}, {"k1", "v5"}, {"k3", "v7"}}})},
});
(*expected.mutable_rpcs_by_method())["UnaryCall"]
.mutable_rpcs_by_peer()
->insert({{"peer1", 2}, {"peer2", 1}});
EXPECT_EQ(watcher.WaitForRpcStatsResponse(0).DebugString(),
expected.DebugString());
}
TEST(XdsStatsWatcherTest, WaitForRpcStatsResponseIgnoresMetadata) {
XdsStatsWatcher watcher(0, 3, {});
// RPC had metadata - but watcher should ignore it

Loading…
Cancel
Save