Mooncake/mooncake-store/tests/client_metrics_test.cpp

271 lines
9.8 KiB
C++

#include <glog/logging.h>
#include <gtest/gtest.h>
#include <cstdlib>
#include <string>
#include "client_metric.h"
namespace mooncake::test {
class ClientMetricsTest : public ::testing::Test {
protected:
void SetUp() override {
google::InitGoogleLogging("ClientMetricsTest");
FLAGS_logtostderr = true;
}
void TearDown() override { google::ShutdownGoogleLogging(); }
};
TEST_F(ClientMetricsTest, TransferMetricsSummaryTest) {
TransferMetric metrics;
// Test empty metrics
std::string summary = metrics.summary_metrics();
EXPECT_TRUE(summary.find("Total Read: 0 B") != std::string::npos);
EXPECT_TRUE(summary.find("Total Write: 0 B") != std::string::npos);
EXPECT_TRUE(summary.find("Get: No data") != std::string::npos);
EXPECT_TRUE(summary.find("Put: No data") != std::string::npos);
// Add some data
metrics.total_read_bytes.inc(1024); // 1KB
metrics.total_write_bytes.inc(2 * 1024 * 1024); // 2MB
// Add latency observations
metrics.get_latency_us.observe(150); // 150 microseconds
metrics.get_latency_us.observe(200); // 200 microseconds
metrics.get_latency_us.observe(300); // 300 microseconds
metrics.put_latency_us.observe(500); // 500 microseconds
metrics.put_latency_us.observe(750); // 750 microseconds
summary = metrics.summary_metrics();
// Check byte formatting
EXPECT_TRUE(summary.find("Total Read: 1.00 KB") != std::string::npos);
EXPECT_TRUE(summary.find("Total Write: 2.00 MB") != std::string::npos);
// Check latency summaries
EXPECT_TRUE(summary.find("Get: count=3") != std::string::npos);
EXPECT_TRUE(summary.find("Put: count=2") != std::string::npos);
// Check percentiles are present
EXPECT_TRUE(summary.find("p95<") != std::string::npos);
EXPECT_TRUE(summary.find("max<") != std::string::npos);
std::cout << "Transfer Metrics Summary:\n" << summary << std::endl;
}
TEST_F(ClientMetricsTest, MasterClientMetricsSummaryTest) {
MasterClientMetric metrics;
// Test empty metrics
std::string summary = metrics.summary_metrics();
EXPECT_TRUE(summary.find("No RPC calls recorded") != std::string::npos);
// Add some RPC calls
std::array<std::string, 1> get_replica_label = {"GetReplicaList"};
std::array<std::string, 1> mount_segment_label = {"MountSegment"};
std::array<std::string, 1> unmount_segment_label = {"UnmountSegment"};
// Simulate RPC calls
metrics.rpc_count.inc(get_replica_label);
metrics.rpc_count.inc(get_replica_label);
metrics.rpc_count.inc(mount_segment_label);
metrics.rpc_count.inc(unmount_segment_label);
// Add latency observations
metrics.rpc_latency.observe(get_replica_label, 200); // 200 microseconds
metrics.rpc_latency.observe(get_replica_label, 250); // 250 microseconds
metrics.rpc_latency.observe(mount_segment_label, 37789); // 37.789 ms
metrics.rpc_latency.observe(unmount_segment_label, 7536); // 7.536 ms
summary = metrics.summary_metrics();
// Check that RPC calls are recorded
EXPECT_TRUE(summary.find("GetReplicaList: count=2") != std::string::npos);
EXPECT_TRUE(summary.find("MountSegment: count=1") != std::string::npos);
EXPECT_TRUE(summary.find("UnmountSegment: count=1") != std::string::npos);
// Check percentiles are present for RPCs with data
EXPECT_TRUE(summary.find("p95<") != std::string::npos);
EXPECT_TRUE(summary.find("max<") != std::string::npos);
std::cout << "Master Client Metrics Summary:\n" << summary << std::endl;
}
TEST_F(ClientMetricsTest, ClientMetricsSummaryTest) {
ClientMetric metrics;
// Add some transfer data
metrics.transfer_metric.total_read_bytes.inc(5 * 1024 * 1024); // 5MB
metrics.transfer_metric.total_write_bytes.inc(10 * 1024 * 1024); // 10MB
metrics.transfer_metric.batch_get_latency_us.observe(1500); // 1.5ms
metrics.transfer_metric.batch_put_latency_us.observe(2000); // 2ms
// Add some RPC data
std::array<std::string, 1> exist_key_label = {"ExistKey"};
metrics.master_client_metric.rpc_count.inc(exist_key_label);
metrics.master_client_metric.rpc_latency.observe(exist_key_label, 180);
std::string summary = metrics.summary_metrics();
// Should contain both transfer and RPC metrics
EXPECT_TRUE(summary.find("Transfer Metrics Summary") != std::string::npos);
EXPECT_TRUE(summary.find("RPC Metrics Summary") != std::string::npos);
EXPECT_TRUE(summary.find("Total Read: 5.00 MB") != std::string::npos);
EXPECT_TRUE(summary.find("Total Write: 10.00 MB") != std::string::npos);
EXPECT_TRUE(summary.find("ExistKey: count=1") != std::string::npos);
std::cout << "Full Client Metrics Summary:\n" << summary << std::endl;
}
TEST_F(ClientMetricsTest, ByteFormattingTest) {
TransferMetric metrics;
// Test different byte sizes
metrics.total_read_bytes.inc(512); // 512 B
std::string summary = metrics.summary_metrics();
EXPECT_TRUE(summary.find("512 B") != std::string::npos);
metrics.total_read_bytes.inc(1024 - 512); // Total 1024 B = 1 KB
summary = metrics.summary_metrics();
EXPECT_TRUE(summary.find("1.00 KB") != std::string::npos);
metrics.total_read_bytes.inc(1024 * 1024 - 1024); // Total 1 MB
summary = metrics.summary_metrics();
EXPECT_TRUE(summary.find("1.00 MB") != std::string::npos);
metrics.total_read_bytes.inc(1024LL * 1024 * 1024 -
1024 * 1024); // Total 1 GB
summary = metrics.summary_metrics();
EXPECT_TRUE(summary.find("1.00 GB") != std::string::npos);
}
TEST_F(ClientMetricsTest, CompareWithSerializedMetrics) {
ClientMetric metrics;
// Add some data
metrics.transfer_metric.total_read_bytes.inc(1024 * 1024);
metrics.transfer_metric.get_latency_us.observe(200);
std::array<std::string, 1> get_replica_label = {"GetReplicaList"};
metrics.master_client_metric.rpc_count.inc(get_replica_label);
metrics.master_client_metric.rpc_latency.observe(get_replica_label, 250);
// Get both summary and full serialized metrics
std::string summary = metrics.summary_metrics();
std::string serialized;
metrics.serialize(serialized);
std::cout << "\n=== Summary Metrics ===" << std::endl;
std::cout << summary << std::endl;
std::cout << "\n=== Full Serialized Metrics ===" << std::endl;
std::cout << serialized << std::endl;
// Summary should be much shorter and more readable
EXPECT_LT(summary.length(), serialized.length());
EXPECT_TRUE(summary.find("count=") != std::string::npos);
EXPECT_TRUE(summary.find("p95<") != std::string::npos ||
summary.find("No data") != std::string::npos);
EXPECT_TRUE(summary.find("max<") != std::string::npos ||
summary.find("No data") != std::string::npos);
}
TEST_F(ClientMetricsTest, SerializeWithDynamicLabels) {
auto verify = [](const std::string& str) {
EXPECT_TRUE(str.find("instance_id=\"12345\"") != std::string::npos);
EXPECT_TRUE(str.find("cluster_id=\"cluster1\"") != std::string::npos);
EXPECT_TRUE(str.find("replica_id=\"replica1\"") != std::string::npos);
EXPECT_TRUE(str.find("mount_segment_id=\"mount1\"") !=
std::string::npos);
};
std::map<std::string, std::string> static_labels = {
{"instance_id", "12345"},
{"cluster_id", "cluster1"},
{"replica_id", "replica1"},
{"mount_segment_id", "mount1"}};
std::array<std::string, 1> get_replica_label = {"GetReplicaList"};
{
ClientMetric metrics(0, static_labels);
metrics.transfer_metric.total_read_bytes.inc(1024 * 1024);
std::string serialized;
metrics.serialize(serialized);
verify(serialized);
}
{
ClientMetric metrics(0, static_labels);
metrics.transfer_metric.get_latency_us.observe(200);
std::string serialized;
metrics.serialize(serialized);
verify(serialized);
}
{
ClientMetric metrics(0, static_labels);
metrics.master_client_metric.rpc_count.inc(get_replica_label);
std::string serialized;
metrics.serialize(serialized);
verify(serialized);
}
{
ClientMetric metrics(0, static_labels);
metrics.master_client_metric.rpc_latency.observe(get_replica_label,
250);
std::string serialized;
metrics.serialize(serialized);
verify(serialized);
}
}
TEST_F(ClientMetricsTest, SerializeWithoutDynamicLabels) {
auto verify = [](const std::string& str) {
EXPECT_TRUE(str.find("instance_id") == std::string::npos);
EXPECT_TRUE(str.find("cluster_id") == std::string::npos);
EXPECT_TRUE(str.find("replica_id") == std::string::npos);
EXPECT_TRUE(str.find("mount_segment_id") == std::string::npos);
};
std::array<std::string, 1> get_replica_label = {"GetReplicaList"};
{
ClientMetric metrics(0);
metrics.transfer_metric.total_read_bytes.inc(1024 * 1024);
std::string serialized;
metrics.serialize(serialized);
verify(serialized);
}
{
ClientMetric metrics(0);
metrics.transfer_metric.get_latency_us.observe(200);
std::string serialized;
metrics.serialize(serialized);
verify(serialized);
}
{
ClientMetric metrics(0);
metrics.master_client_metric.rpc_count.inc(get_replica_label);
std::string serialized;
metrics.serialize(serialized);
verify(serialized);
}
{
ClientMetric metrics(0);
metrics.master_client_metric.rpc_latency.observe(get_replica_label,
250);
std::string serialized;
metrics.serialize(serialized);
verify(serialized);
}
}
} // namespace mooncake::test