Skip to content

Commit

Permalink
UPSTREAM: 110652: fix --chunk-size with selector returns missing result
Browse files Browse the repository at this point in the history
Bug 2094012

Signed-off-by: Abirdcfly <[email protected]>
  • Loading branch information
Abirdcfly authored and aojea committed Jun 30, 2022
1 parent 9ddc8b1 commit de74c89
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 3 deletions.
2 changes: 1 addition & 1 deletion staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ func growSlice(v reflect.Value, maxCapacity int, sizes ...int) {
return
}
if v.Len() > 0 {
extra := reflect.MakeSlice(v.Type(), 0, max)
extra := reflect.MakeSlice(v.Type(), v.Len(), max)
reflect.Copy(extra, v)
v.Set(extra)
} else {
Expand Down
33 changes: 31 additions & 2 deletions staging/src/k8s.io/apiserver/pkg/storage/etcd3/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2240,6 +2240,7 @@ func Test_decodeContinue(t *testing.T) {
func Test_growSlice(t *testing.T) {
type args struct {
initialCapacity int
initialLen int
v reflect.Value
maxCapacity int
sizes []int
Expand All @@ -2248,6 +2249,7 @@ func Test_growSlice(t *testing.T) {
name string
args args
cap int
len int
}{
{
name: "empty",
Expand Down Expand Up @@ -2279,13 +2281,29 @@ func Test_growSlice(t *testing.T) {
args: args{initialCapacity: 5, maxCapacity: 10, sizes: []int{8, 4}},
cap: 8,
},
{
name: "with existing capacity and length above max",
args: args{initialCapacity: 12, initialLen: 5, maxCapacity: 10, sizes: []int{8, 4}},
cap: 12,
len: 5,
},
{
name: "with existing capacity and length below max",
args: args{initialCapacity: 5, initialLen: 3, maxCapacity: 10, sizes: []int{8, 4}},
cap: 8,
len: 3,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.args.initialCapacity > 0 {
tt.args.v = reflect.ValueOf(make([]example.Pod, 0, tt.args.initialCapacity))
val := make([]example.Pod, tt.args.initialLen, tt.args.initialCapacity)
for i := 0; i < tt.args.initialLen; i++ {
val[i].Name = fmt.Sprintf("test-%d", i)
}
tt.args.v = reflect.ValueOf(val)
}
// reflection requires that the value be addressible in order to call set,
// reflection requires that the value be addressable in order to call set,
// so we must ensure the value we created is available on the heap (not a problem
// for normal usage)
if !tt.args.v.CanAddr() {
Expand All @@ -2297,6 +2315,17 @@ func Test_growSlice(t *testing.T) {
if tt.cap != tt.args.v.Cap() {
t.Errorf("Unexpected capacity: got=%d want=%d", tt.args.v.Cap(), tt.cap)
}
if tt.len != tt.args.v.Len() {
t.Errorf("Unexpected length: got=%d want=%d", tt.args.v.Len(), tt.len)
}
for i := 0; i < tt.args.v.Len(); i++ {
nameWanted := fmt.Sprintf("test-%d", i)
val := tt.args.v.Index(i).Interface()
pod, ok := val.(example.Pod)
if !ok || pod.Name != nameWanted {
t.Errorf("Unexpected element value: got=%s, want=%s", pod.Name, nameWanted)
}
}
})
}
}
Expand Down
63 changes: 63 additions & 0 deletions test/integration/apiserver/apiserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,69 @@ func TestAPIListChunking(t *testing.T) {
}
}

func TestAPIListChunkingWithLabelSelector(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.APIListChunking, true)()
s, clientSet, closeFn := setup(t)
defer closeFn()

ns := framework.CreateTestingNamespace("list-paging-with-label-selector", s, t)
defer framework.DeleteTestingNamespace(ns, s, t)

rsClient := clientSet.AppsV1().ReplicaSets(ns.Name)

for i := 0; i < 10; i++ {
rs := newRS(ns.Name)
rs.Name = fmt.Sprintf("test-%d", i)
odd := i%2 != 0
rs.Labels = map[string]string{"odd-index": strconv.FormatBool(odd)}
if _, err := rsClient.Create(context.TODO(), rs, metav1.CreateOptions{}); err != nil {
t.Fatal(err)
}
}

calls := 0
firstRV := ""
p := &pager.ListPager{
PageSize: 1,
PageFn: pager.SimplePageFunc(func(opts metav1.ListOptions) (runtime.Object, error) {
calls++
list, err := rsClient.List(context.TODO(), opts)
if err != nil {
return nil, err
}
if calls == 1 {
firstRV = list.ResourceVersion
}
return list, err
}),
}
listObj, _, err := p.List(context.Background(), metav1.ListOptions{LabelSelector: "odd-index=true", Limit: 3})
if err != nil {
t.Fatal(err)
}
if calls != 2 {
t.Errorf("unexpected list invocations: %d", calls)
}
list := listObj.(metav1.ListInterface)
if len(list.GetContinue()) != 0 {
t.Errorf("unexpected continue: %s", list.GetContinue())
}
if list.GetResourceVersion() != firstRV {
t.Errorf("unexpected resource version: %s instead of %s", list.GetResourceVersion(), firstRV)
}
var names []string
if err := meta.EachListItem(listObj, func(obj runtime.Object) error {
rs := obj.(*apps.ReplicaSet)
names = append(names, rs.Name)
return nil
}); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(names, []string{"test-1", "test-3", "test-5", "test-7", "test-9"}) {
t.Errorf("unexpected items: %#v", list)
}
}

func makeSecret(name string) *v1.Secret {
return &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Expand Down

0 comments on commit de74c89

Please sign in to comment.