-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🐛 Handle unstructured status update with fake client #2495
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1677,6 +1677,52 @@ var _ = Describe("Fake client", func() { | |
Expect(obj.Object["spec"]).To(BeEquivalentTo("original")) | ||
}) | ||
|
||
It("should not change the status of known unstructured objects that have a status subresource on update", func() { | ||
obj := &unstructured.Unstructured{} | ||
obj.SetAPIVersion("v1") | ||
obj.SetKind("Pod") | ||
obj.SetName("pod") | ||
err := unstructured.SetNestedField(obj.Object, "Always", "spec", "restartPolicy") | ||
Expect(err).NotTo(HaveOccurred()) | ||
err = unstructured.SetNestedField(obj.Object, "Pending", "status", "phase") | ||
Expect(err).NotTo(HaveOccurred()) | ||
cl := NewClientBuilder().WithStatusSubresource(obj).WithObjects(obj).Build() | ||
|
||
err = unstructured.SetNestedField(obj.Object, "Never", "spec", "restartPolicy") | ||
Expect(err).NotTo(HaveOccurred()) | ||
err = unstructured.SetNestedField(obj.Object, "Running", "status", "phase") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
Expect(cl.Update(context.Background(), obj)).To(Succeed()) | ||
Expect(cl.Get(context.Background(), client.ObjectKeyFromObject(obj), obj)).To(Succeed()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would you actually mind to do the retrieval and verification using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated the tests. Sorry for the delay, I was traveling last week. |
||
|
||
Expect(obj.Object["spec"].(map[string]any)["restartPolicy"]).To(Equal("Never")) | ||
Expect(obj.Object["status"].(map[string]any)["phase"]).To(Equal("Pending")) | ||
}) | ||
|
||
It("should not change non-status field of known unstructured objects that have a status subresource on status update", func() { | ||
obj := &unstructured.Unstructured{} | ||
obj.SetAPIVersion("v1") | ||
obj.SetKind("Pod") | ||
obj.SetName("pod") | ||
err := unstructured.SetNestedField(obj.Object, "Always", "spec", "restartPolicy") | ||
Expect(err).NotTo(HaveOccurred()) | ||
err = unstructured.SetNestedField(obj.Object, "Pending", "status", "phase") | ||
Expect(err).NotTo(HaveOccurred()) | ||
cl := NewClientBuilder().WithStatusSubresource(obj).WithObjects(obj).Build() | ||
|
||
err = unstructured.SetNestedField(obj.Object, "Never", "spec", "restartPolicy") | ||
Expect(err).NotTo(HaveOccurred()) | ||
err = unstructured.SetNestedField(obj.Object, "Running", "status", "phase") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
Expect(cl.Status().Update(context.Background(), obj)).To(Succeed()) | ||
Expect(cl.Get(context.Background(), client.ObjectKeyFromObject(obj), obj)).To(Succeed()) | ||
|
||
Expect(obj.Object["spec"].(map[string]any)["restartPolicy"]).To(Equal("Always")) | ||
Expect(obj.Object["status"].(map[string]any)["phase"]).To(Equal("Running")) | ||
}) | ||
|
||
It("should not change the status of unstructured objects that are configured to have a status subresource on patch", func() { | ||
obj := &unstructured.Unstructured{} | ||
obj.SetAPIVersion("foo/v1") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original reason for not doing this anymore is that it might leave stale data in the target. I am confused as to why this isn't a problem anymore. Maybe we just didn't add sufficient test coverage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't changing existing behavior. No tests were modified or removed. What it does is handle a mix of typed and unstructured objects gracefully, instead of panicing.
What stale data is left behind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What @alvaroaleman is referring to I believe is that before this function was added, we removed a function similar to this where we were doing a
copyFrom
because of the issues with that function leaving stale data around.#2479
#2479 (comment)
If this being added doesn't impact what is already there (covers previous tests and your new test case) and handles the new case to fix the regression, the new test coverage should be sufficient to have this fix be in and resolve the issue with unstructured stuff.
I believe we have unstructured.Unstructured tests cases and if not being caught in testing, it begs the question how did those tests pass, if this problem still presented itself.
IANAM, (I am not a maintainer)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the previous tests and code handled both
typed->typed
andunstructured->unstructured
, but triggered a panic withtyped->unstructured
. The mix can happen when the GVK is registered in the scheme, so the resource in the tracker is always converted to the typed form, and then the user performs a status update using an unstructured object.It's a bit esoteric as most users will favor a typed resource when available, but we hit it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, we also added code to zero the target, that is why it works. Thanks for the patch and sorry for the review delay