mirror of
https://github.com/kubernetes/kubernetes.git
synced 2026-06-08 16:30:57 -04:00
Merge pull request #133604 from serathius/watchcache-count
Fix storage counting all objects instead of objects for resource
This commit is contained in:
commit
4e8b192b66
2 changed files with 114 additions and 2 deletions
|
|
@ -634,7 +634,14 @@ func (s *store) Stats(ctx context.Context) (stats storage.Stats, err error) {
|
|||
return s.stats.Stats(ctx)
|
||||
}
|
||||
startTime := time.Now()
|
||||
count, err := s.client.Kubernetes.Count(ctx, s.pathPrefix, kubernetes.CountOptions{})
|
||||
prefix, err := s.prepareKey(s.resourcePrefix)
|
||||
if err != nil {
|
||||
return storage.Stats{}, err
|
||||
}
|
||||
if !strings.HasSuffix(prefix, "/") {
|
||||
prefix += "/"
|
||||
}
|
||||
count, err := s.client.Kubernetes.Count(ctx, prefix, kubernetes.CountOptions{})
|
||||
metrics.RecordEtcdRequest("listWithCount", s.groupResource, err, startTime)
|
||||
if err != nil {
|
||||
return storage.Stats{}, err
|
||||
|
|
@ -652,7 +659,14 @@ func (s *store) SetKeysFunc(keys storage.KeysFunc) {
|
|||
|
||||
func (s *store) getKeys(ctx context.Context) ([]string, error) {
|
||||
startTime := time.Now()
|
||||
resp, err := s.client.KV.Get(ctx, s.pathPrefix, clientv3.WithPrefix(), clientv3.WithKeysOnly())
|
||||
prefix, err := s.prepareKey(s.resourcePrefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !strings.HasSuffix(prefix, "/") {
|
||||
prefix += "/"
|
||||
}
|
||||
resp, err := s.client.KV.Get(ctx, prefix, clientv3.WithPrefix(), clientv3.WithKeysOnly())
|
||||
metrics.RecordEtcdRequest("listOnlyKeys", s.groupResource, err, startTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/require"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/client/v3/kubernetes"
|
||||
|
|
@ -588,6 +589,12 @@ func withPrefix(prefix string) setupOption {
|
|||
}
|
||||
}
|
||||
|
||||
func withResourcePrefix(prefix string) setupOption {
|
||||
return func(options *setupOptions) {
|
||||
options.resourcePrefix = prefix
|
||||
}
|
||||
}
|
||||
|
||||
func withLeaseConfig(leaseConfig LeaseManagerConfig) setupOption {
|
||||
return func(options *setupOptions) {
|
||||
options.leaseConfig = leaseConfig
|
||||
|
|
@ -996,3 +1003,94 @@ func BenchmarkStatsCacheCleanKeys(b *testing.B) {
|
|||
b.Fatalf("Unexpected number of keys in stats, want: %d, got: %d", namespaceCount*podPerNamespaceCount, len(store.stats.keys))
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrefixGetKeys(t *testing.T) {
|
||||
ctx, store, c := testSetup(t, withPrefix("/registry"), withResourcePrefix("pods"))
|
||||
_, err := c.KV.Put(ctx, "key", "a")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = c.KV.Put(ctx, "/registry/key", "b")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = c.KV.Put(ctx, "/registry/pods/key", "c")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = c.KV.Put(ctx, "/registry/podskey", "d")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
gotKeys, err := store.getKeys(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
wantKeys := []string{"/registry/pods/key"}
|
||||
if diff := cmp.Diff(wantKeys, gotKeys); diff != "" {
|
||||
t.Errorf("getKeys diff:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrefixStats(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
estimate bool
|
||||
expectStats storage.Stats
|
||||
}{
|
||||
{
|
||||
name: "SizeBasedListCostEstimate=false",
|
||||
estimate: false,
|
||||
expectStats: storage.Stats{ObjectCount: 1},
|
||||
},
|
||||
{
|
||||
name: "SizeBasedListCostEstimate=true",
|
||||
estimate: true,
|
||||
expectStats: storage.Stats{ObjectCount: 1, EstimatedAverageObjectSizeBytes: 3},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SizeBasedListCostEstimate, tc.estimate)
|
||||
ctx, store, c := testSetup(t, withPrefix("/registry"), withResourcePrefix("pods"))
|
||||
_, err := c.KV.Put(ctx, "key", "a")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = c.KV.Put(ctx, "/registry/key", "ab")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = c.KV.Put(ctx, "/registry/pods/key", "abc")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = c.KV.Put(ctx, "/registry/podskey", "abcd")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
listOut := &example.PodList{}
|
||||
// Ignore error as decode is expected to fail
|
||||
_ = store.GetList(ctx, "pods", storage.ListOptions{Predicate: storage.Everything, Recursive: true}, listOut)
|
||||
|
||||
gotStats, err := store.Stats(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(tc.expectStats, gotStats); diff != "" {
|
||||
t.Errorf("Stats diff:\n%s", diff)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue