Skip to content

Commit 343b53a

Browse files
Merge remote-tracking branch 'origin/master' into release-1.34
2 parents 4feac13 + 4e8b192 commit 343b53a

File tree

2 files changed

+114
-2
lines changed

2 files changed

+114
-2
lines changed

staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,14 @@ func (s *store) Stats(ctx context.Context) (stats storage.Stats, err error) {
634634
return s.stats.Stats(ctx)
635635
}
636636
startTime := time.Now()
637-
count, err := s.client.Kubernetes.Count(ctx, s.pathPrefix, kubernetes.CountOptions{})
637+
prefix, err := s.prepareKey(s.resourcePrefix)
638+
if err != nil {
639+
return storage.Stats{}, err
640+
}
641+
if !strings.HasSuffix(prefix, "/") {
642+
prefix += "/"
643+
}
644+
count, err := s.client.Kubernetes.Count(ctx, prefix, kubernetes.CountOptions{})
638645
metrics.RecordEtcdRequest("listWithCount", s.groupResource, err, startTime)
639646
if err != nil {
640647
return storage.Stats{}, err
@@ -652,7 +659,14 @@ func (s *store) SetKeysFunc(keys storage.KeysFunc) {
652659

653660
func (s *store) getKeys(ctx context.Context) ([]string, error) {
654661
startTime := time.Now()
655-
resp, err := s.client.KV.Get(ctx, s.pathPrefix, clientv3.WithPrefix(), clientv3.WithKeysOnly())
662+
prefix, err := s.prepareKey(s.resourcePrefix)
663+
if err != nil {
664+
return nil, err
665+
}
666+
if !strings.HasSuffix(prefix, "/") {
667+
prefix += "/"
668+
}
669+
resp, err := s.client.KV.Get(ctx, prefix, clientv3.WithPrefix(), clientv3.WithKeysOnly())
656670
metrics.RecordEtcdRequest("listOnlyKeys", s.groupResource, err, startTime)
657671
if err != nil {
658672
return nil, err

staging/src/k8s.io/apiserver/pkg/storage/etcd3/store_test.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"time"
2929

3030
"github.com/go-logr/logr"
31+
"github.com/google/go-cmp/cmp"
3132
"github.com/stretchr/testify/require"
3233
clientv3 "go.etcd.io/etcd/client/v3"
3334
"go.etcd.io/etcd/client/v3/kubernetes"
@@ -588,6 +589,12 @@ func withPrefix(prefix string) setupOption {
588589
}
589590
}
590591

592+
func withResourcePrefix(prefix string) setupOption {
593+
return func(options *setupOptions) {
594+
options.resourcePrefix = prefix
595+
}
596+
}
597+
591598
func withLeaseConfig(leaseConfig LeaseManagerConfig) setupOption {
592599
return func(options *setupOptions) {
593600
options.leaseConfig = leaseConfig
@@ -996,3 +1003,94 @@ func BenchmarkStatsCacheCleanKeys(b *testing.B) {
9961003
b.Fatalf("Unexpected number of keys in stats, want: %d, got: %d", namespaceCount*podPerNamespaceCount, len(store.stats.keys))
9971004
}
9981005
}
1006+
1007+
func TestPrefixGetKeys(t *testing.T) {
1008+
ctx, store, c := testSetup(t, withPrefix("/registry"), withResourcePrefix("pods"))
1009+
_, err := c.KV.Put(ctx, "key", "a")
1010+
if err != nil {
1011+
t.Fatal(err)
1012+
}
1013+
1014+
_, err = c.KV.Put(ctx, "/registry/key", "b")
1015+
if err != nil {
1016+
t.Fatal(err)
1017+
}
1018+
1019+
_, err = c.KV.Put(ctx, "/registry/pods/key", "c")
1020+
if err != nil {
1021+
t.Fatal(err)
1022+
}
1023+
1024+
_, err = c.KV.Put(ctx, "/registry/podskey", "d")
1025+
if err != nil {
1026+
t.Fatal(err)
1027+
}
1028+
1029+
gotKeys, err := store.getKeys(ctx)
1030+
if err != nil {
1031+
t.Fatal(err)
1032+
}
1033+
1034+
wantKeys := []string{"/registry/pods/key"}
1035+
if diff := cmp.Diff(wantKeys, gotKeys); diff != "" {
1036+
t.Errorf("getKeys diff:\n%s", diff)
1037+
}
1038+
}
1039+
1040+
func TestPrefixStats(t *testing.T) {
1041+
tcs := []struct {
1042+
name string
1043+
estimate bool
1044+
expectStats storage.Stats
1045+
}{
1046+
{
1047+
name: "SizeBasedListCostEstimate=false",
1048+
estimate: false,
1049+
expectStats: storage.Stats{ObjectCount: 1},
1050+
},
1051+
{
1052+
name: "SizeBasedListCostEstimate=true",
1053+
estimate: true,
1054+
expectStats: storage.Stats{ObjectCount: 1, EstimatedAverageObjectSizeBytes: 3},
1055+
},
1056+
}
1057+
for _, tc := range tcs {
1058+
t.Run(tc.name, func(t *testing.T) {
1059+
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SizeBasedListCostEstimate, tc.estimate)
1060+
ctx, store, c := testSetup(t, withPrefix("/registry"), withResourcePrefix("pods"))
1061+
_, err := c.KV.Put(ctx, "key", "a")
1062+
if err != nil {
1063+
t.Fatal(err)
1064+
}
1065+
1066+
_, err = c.KV.Put(ctx, "/registry/key", "ab")
1067+
if err != nil {
1068+
t.Fatal(err)
1069+
}
1070+
1071+
_, err = c.KV.Put(ctx, "/registry/pods/key", "abc")
1072+
if err != nil {
1073+
t.Fatal(err)
1074+
}
1075+
1076+
_, err = c.KV.Put(ctx, "/registry/podskey", "abcd")
1077+
if err != nil {
1078+
t.Fatal(err)
1079+
}
1080+
1081+
listOut := &example.PodList{}
1082+
// Ignore error as decode is expected to fail
1083+
_ = store.GetList(ctx, "pods", storage.ListOptions{Predicate: storage.Everything, Recursive: true}, listOut)
1084+
1085+
gotStats, err := store.Stats(ctx)
1086+
if err != nil {
1087+
t.Fatal(err)
1088+
}
1089+
1090+
if diff := cmp.Diff(tc.expectStats, gotStats); diff != "" {
1091+
t.Errorf("Stats diff:\n%s", diff)
1092+
}
1093+
1094+
})
1095+
}
1096+
}

0 commit comments

Comments
 (0)