Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion kv_cache_manager/service/meta_service_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -964,8 +964,10 @@ void MetaServiceImpl::GetHostCacheState(RequestContext *request_context,
const proto::meta::GetHostCacheStateRequest *request,
proto::meta::GetHostCacheStateResponse *response) {
SPAN_TRACER(request_context);
// This is a best-effort read of the node's local ReportEvent view. Followers may
// serve a stale view, while ReportEvent mutations remain leader-only.
API_CALL_GUARD_WITH_DEBUG("GetHostCacheState",
true,
false,
BuildGetHostCacheStateRequestAccessLogSummary(request),
BuildGetHostCacheStateResponseAccessLogSummary(response));
auto *header = response->mutable_header();
Expand Down
15 changes: 15 additions & 0 deletions kv_cache_manager/service/test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ cc_test(
],
)

cc_test(
name = "MetaServiceImplTest",
srcs = [
"meta_service_impl_test.cc",
],
copts = ["-fno-access-control"],
deps = [
"//kv_cache_manager/common:unittest",
"//kv_cache_manager/config",
"//kv_cache_manager/manager:cache_manager",
"//kv_cache_manager/metrics:metrics_registry",
"//kv_cache_manager/service:meta_service_impl",
],
)

cc_test(
name = "CommandLineTest",
srcs = [
Expand Down
51 changes: 51 additions & 0 deletions kv_cache_manager/service/test/meta_service_impl_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include <memory>

#include "kv_cache_manager/common/request_context.h"
#include "kv_cache_manager/common/unittest.h"
#include "kv_cache_manager/config/registry_manager.h"
#include "kv_cache_manager/manager/cache_manager.h"
#include "kv_cache_manager/metrics/metrics_registry.h"
#include "kv_cache_manager/protocol/protobuf/meta_service.pb.h"
#include "kv_cache_manager/service/meta_service_impl.h"

namespace kv_cache_manager {

class MetaServiceImplTest : public TESTBASE {
protected:
void SetUp() override {
metrics_registry_ = std::make_shared<MetricsRegistry>();
registry_manager_ = std::make_shared<RegistryManager>("", metrics_registry_);
cache_manager_ = std::make_shared<CacheManager>(metrics_registry_, registry_manager_);
service_ = std::make_unique<MetaServiceImpl>(cache_manager_, nullptr, nullptr);
service_->DisableLeaderOnlyRequests();
}

std::shared_ptr<MetricsRegistry> metrics_registry_;
std::shared_ptr<RegistryManager> registry_manager_;
std::shared_ptr<CacheManager> cache_manager_;
std::unique_ptr<MetaServiceImpl> service_;
};

TEST_F(MetaServiceImplTest, FollowerAllowsReportEventQueryButRejectsWrite) {
RequestContext query_context("follower-query");
proto::meta::GetHostCacheStateRequest query_request;
query_request.set_trace_id(query_context.trace_id());
proto::meta::GetHostCacheStateResponse query_response;

service_->GetHostCacheState(&query_context, &query_request, &query_response);

// INVALID_ARGUMENT proves the read passed the follower gate and reached
// normal request validation instead of being rejected as SERVER_NOT_LEADER.
EXPECT_EQ(proto::meta::INVALID_ARGUMENT, query_response.header().status().code());

RequestContext write_context("follower-write");
proto::meta::ReportEventRequest write_request;
write_request.set_trace_id(write_context.trace_id());
proto::meta::ReportEventResponse write_response;

service_->ReportEvent(&write_context, &write_request, &write_response);

EXPECT_EQ(proto::meta::SERVER_NOT_LEADER, write_response.header().status().code());
}

} // namespace kv_cache_manager
Loading