Skip to content

Commit f55eac0

Browse files
authored
Merge pull request kubernetes#94055 from liggitt/subresource-flake
Deflake TestSubresourcePatch
2 parents 0d1d656 + 6ca6565 commit f55eac0

File tree

1 file changed

+26
-36
lines changed

1 file changed

+26
-36
lines changed

staging/src/k8s.io/apiextensions-apiserver/test/integration/subresources_test.go

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -772,34 +772,35 @@ func TestSubresourcePatch(t *testing.T) {
772772

773773
expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 999, "status", "num") // .status.num should be 999
774774
expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 10, "spec", "num") // .spec.num should remain 10
775-
rv, found, err := unstructured.NestedString(patchedNoxuInstance.UnstructuredContent(), "metadata", "resourceVersion")
776-
if err != nil {
777-
t.Fatal(err)
778-
}
779-
if !found {
780-
t.Fatalf("metadata.resourceVersion not found")
781-
}
782-
783-
// this call waits for the resourceVersion to be reached in the cache before returning.
784-
// We need to do this because the patch gets its initial object from the storage, and the cache serves that.
785-
// If it is out of date, then our initial patch is applied to an old resource version, which conflicts
786-
// and then the updated object shows a conflicting diff, which permanently fails the patch.
787-
// This gives expected stability in the patch without retrying on an known number of conflicts below in the test.
788-
// See https://issue.k8s.io/42644
789-
_, err = noxuResourceClient.Get(context.TODO(), "foo", metav1.GetOptions{ResourceVersion: patchedNoxuInstance.GetResourceVersion()})
790-
if err != nil {
791-
t.Fatalf("unexpected error: %v", err)
792-
}
793775

794776
// no-op patch
795-
t.Logf("Patching .status.num again to 999")
796-
patchedNoxuInstance, err = noxuResourceClient.Patch(context.TODO(), "foo", types.MergePatchType, patch, metav1.PatchOptions{}, "status")
797-
if err != nil {
798-
t.Fatalf("unexpected error: %v", err)
777+
rv := ""
778+
found := false
779+
// TODO: remove this retry once http://issue.k8s.io/75564 is resolved, and expect the resourceVersion to remain unchanged 100% of the time.
780+
// server-side-apply incorrectly considers spec fields in patches submitted to /status when updating managedFields timestamps, so this patch is racy:
781+
// if it spans a 1-second boundary from the last write, server-side-apply updates the managedField timestamp and increments resourceVersion.
782+
for i := 0; i < 10; i++ {
783+
rv, found, err = unstructured.NestedString(patchedNoxuInstance.UnstructuredContent(), "metadata", "resourceVersion")
784+
if err != nil {
785+
t.Fatal(err)
786+
}
787+
if !found {
788+
t.Fatalf("metadata.resourceVersion not found")
789+
}
790+
791+
t.Logf("Patching .status.num again to 999")
792+
patchedNoxuInstance, err = noxuResourceClient.Patch(context.TODO(), "foo", types.MergePatchType, patch, metav1.PatchOptions{}, "status")
793+
if err != nil {
794+
t.Fatalf("unexpected error: %v", err)
795+
}
796+
// make sure no-op patch does not increment resourceVersion
797+
expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 999, "status", "num")
798+
expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 10, "spec", "num")
799+
if patchedNoxuInstance.GetResourceVersion() == rv {
800+
break
801+
}
802+
t.Logf("resource version changed - retrying")
799803
}
800-
// make sure no-op patch does not increment resourceVersion
801-
expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 999, "status", "num")
802-
expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 10, "spec", "num")
803804
expectString(t, patchedNoxuInstance.UnstructuredContent(), rv, "metadata", "resourceVersion")
804805

805806
// empty patch
@@ -831,17 +832,6 @@ func TestSubresourcePatch(t *testing.T) {
831832
t.Fatalf("metadata.resourceVersion not found")
832833
}
833834

834-
// this call waits for the resourceVersion to be reached in the cache before returning.
835-
// We need to do this because the patch gets its initial object from the storage, and the cache serves that.
836-
// If it is out of date, then our initial patch is applied to an old resource version, which conflicts
837-
// and then the updated object shows a conflicting diff, which permanently fails the patch.
838-
// This gives expected stability in the patch without retrying on an known number of conflicts below in the test.
839-
// See https://issue.k8s.io/42644
840-
_, err = noxuResourceClient.Get(context.TODO(), "foo", metav1.GetOptions{ResourceVersion: patchedNoxuInstance.GetResourceVersion()})
841-
if err != nil {
842-
t.Fatalf("unexpected error: %v", err)
843-
}
844-
845835
// Scale.Spec.Replicas = 7 but Scale.Status.Replicas should remain 0
846836
gottenScale, err := scaleClient.Scales("not-the-default").Get(context.TODO(), groupResource, "foo", metav1.GetOptions{})
847837
if err != nil {

0 commit comments

Comments
 (0)