-
Notifications
You must be signed in to change notification settings - Fork 780
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
Remove PodOwnership option #1585
Remove PodOwnership option #1585
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1585 +/- ##
==========================================
- Coverage 54.25% 53.92% -0.33%
==========================================
Files 93 93
Lines 8082 8070 -12
==========================================
- Hits 4385 4352 -33
- Misses 3356 3374 +18
- Partials 341 344 +3
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
g.Expect(err).NotTo(gomega.HaveOccurred()) | ||
|
||
createInstance := func() client.Object { | ||
return configFor([]schema.GroupVersionKind{nsGVK, configMapGVK}) |
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.
Isn't this redefining instance
? How do these declarations compare?
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.
We need a fresh copy of Instance each time we send one to a call to client.Create
/client.Delete
as they modify instance.
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.
Perhaps use instance.DeepCopy()
then? So we know they are the same?
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.
Ok. I don't see a distinction in the approaches. All that matters is that for each call to a client.Client
method, we have a new copy.
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.
To Max's suggestion - no, we can't just ensureCreated(instance.DeepCopy())
as this would use the same object for multiple client.Client
calls. Each time we want to make a new call to any client.Client
method, we must be using a completely fresh copy of instance
. Thus, we must instance.DeepCopy
every single time we are about to run a client.Client
method.
ensureCreated(instance.DeepCopy())
only copies instance
once. Instead, we must pass a reference of instance
to ensureCreated
and then copy instance
within ensureCreated
so the method can guarantee that a fresh copy is supplied each time Eventually
invokes the functor ensureCreated
returns.
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.
Thanks for hunting that down.
I'm mostly just concerned about comprehensibility in the tests because the setup ends up being a big part of explaining what's actually being tested. For example, the re-use of the API server across tests isn't obvious until you've experienced the pain it causes.
Recording the lesson you've learned in the code is (IMO) very valuable, as it saves a future engineer from walking the same (I'm sure time consuming) path. If you see a good way to do that, that future engineer would appreciate it!
Perhaps you'd rather change this in a subsequent PR, but this feels to me like we're sprinkling some complexity throughout the codebase. If we were to move the pod generation into one package for generating test fakes, that single place could hold this useful lesson you derived (that a fake UID will make ownerrefs work, preventing you from having to disable them during testing). |
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.
LGTM, with some nits on ensureCreated
FYI added |
96ddaae
to
0a376cc
Compare
5e910a4
to
32b75fb
Compare
32b75fb
to
f248000
Compare
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.
minor non-blocking comments in test code, lgtm 👍🏻
return nil, err | ||
} | ||
|
||
if err = controllerutil.SetOwnerReference(pod, obj, scheme); err != nil { |
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.
I missed the conversation that motivated this PR so don't have full context.
When working on GK, I often run the code locally on my machine pointed at a remote cluster. If I read correctly, this will only be possible by setting POD_NAME
and POD_NAMESPACE
to point to a valid pod on the cluster?
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.
No. If you are running the code locally (i.e. there is no real "Pod" on the cluster) then you do not need to set these environment variables.
The original code sort of obfuscated how this works.
- To function properly,
SetOwnerReference
requires its first argument (pod
in this case) to havemetadata.name
andmetadata.uid
set. Otherwise future API Server calls withobj
fail with confusing errors. - If
--debug-use-fake-pod
is enabled, then we unconditionally set thePOD_NAME
env variable to a valid value before instantiating the fake Pod. So Pod is guaranteed to be a valid object. util.GetPodNamespace
falls back togatekeeper-system
if the env variable is not set. This prevents various crashes which can happen if the controller's Pod does not havemetadata.namespace
set.- Finally, the new
fakes.Pod
method sets a dummymetadata.uid
which satisfies the fake API Server used in testing. The fake API Server validates that requests havemetadata.uid
, but does not ensure the UID is meaningful or valid.
Thus, all information required for the Pod to be used in debug mode is set.
This was introduced for tests, but is unnecessary. All that is needed for setting ownerreferences to work properly is to set the UID of fake Pods used in testing. This is because ownerreference validation requires that UID be set on the reference (to deduplicate objects with identical names/namespaces which existed at different points in time). This raises the point that we should probably have a general-purpose method for instantiating a fake Pod for use in testing and debugging. It isn't obvious to me where that is. Feel free to suggest a location. Do note that it would be in production code since the debug setting is compiled in non-test files. Signed-off-by: Will Beason <willbeason@google.com>
Signed-off-by: Will Beason <willbeason@google.com>
Signed-off-by: Will Beason <willbeason@google.com>
Signed-off-by: Will Beason <willbeason@google.com>
Also split ensureDeleted out of ensureCreated. Signed-off-by: Will Beason <willbeason@google.com>
Signed-off-by: Will Beason <willbeason@google.com>
f248000
to
25f49c3
Compare
This was introduced for tests, but is unnecessary. All that is needed
for setting ownerreferences to work properly is to set the UID of fake
Pods used in testing.
This is because ownerreference validation requires that UID be set on
the reference (to deduplicate objects with identical names/namespaces
which existed at different points in time).
This raises the point that we should probably have a general-purpose
method for instantiating a fake Pod for use in testing and debugging. It
isn't obvious to me where that is. Feel free to suggest a location. Do
note that it would be in production code since the debug setting is
compiled in non-test files.
Note: the fake Pod UID I've added for tests is arbitrary - it just has to be
something, but the specific value is meaningless.
This PR is a follow-up based on suggestions ritazh and julianKatz made on #1569
Signed-off-by: Will Beason willbeason@google.com