-
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
Cannot Get after Create using Client with Custom Resource #343
Comments
In a controller, you always write to the API server and read from the cache (unless you manually construct a Client). You can't expect to read the object you wrote immediately (and, in fact, there's generally a bit of delay). What are you trying to accomplish with the immediate EDIT: clarification for posterity |
@DirectXMan12: This was a snippet of something that's happening in an integration test that's failing. I would have expected read-after-write to be strongly consistent. If this is not a guarantee, I can always drop a |
how did you get the client for the integration test? |
direct clients ( |
The client comes from A rough snippet: import (
"sigs.k8s.io/controller-runtime/pkg/client/config"
"sigs.k8s.io/controller-runtime/pkg/manager"
)
mgrOptions := &manager.Options{
MetricsBindAddress: *metricsAddr,
Scheme: scheme.Scheme,
}
...
clientConfig, err := config.GetConfig()
mgr, err := manager.New(clientConfig, *managerOptions)
...
client := mgr.GetClient() |
ah, yeah, this is probably a bit of a confusing statement, but don't use the manager client in tests. The manager-provided client is designed to do the right thing for controllers by default (which is to read from caches, meaning that it's not strongly consistent), which means it probably does the wrong thing for tests (which almost certainly want strong consistency). The suggested pattern is to construct a new client using This is something that we need to document better, but generally, my var testenv *envtest.Environment
var cfg *rest.Config
var client client.Client
var _ = BeforeSuite(func() {
logf.SetLogger(zap.LoggerTo(GinkgoWriter, true))
testenv = &envtest.Environment{}
var err error
cfg, err = testenv.Start()
Expect(err).NotTo(HaveOccurred())
client, err = client.New(cfg, client.Options{Scheme: myscheme.Scheme})
Expect(err).NotTo(HaveOccurred())
})
var _ = AfterSuite(func() {
testenv.Stop()
}) (this is very similar to a lot of the test suite setup files in controller-runtime itself) |
Might be easier to document if we can instead tell folks to use thoughts? |
yeah, once we get that merged, we can recommend that as well, although constructing a new client may be easier in some circumstances. |
(also, in case it wasn't clear, while it's fine (and generally preferable) to write tests expecting read-after-write consistency, you shouldn't do that for controllers. Kubernetes favors a kind-of 2-phase approach -- do your reads, process, do some writes, and return, letting the requeuing deal with the next cycle of reads if they're necessary, but don't try to read an object after you've written it). |
@michaelkipper does that answer your question? |
My first Reconciler completed the creation of the job and triggered the second Reconciler. |
if it's actually the create that's triggering the second reconciler, that shouldn't happen. |
In my case, I can not get the CRD resource, but list returns correct values. // this works fine
myCRDList := &foov1beta1.FooList{}
g.Eventually(func() error { return c.List(context.TODO(), &client.ListOptions{}, myCRDList) }).Should(gomega.Succeed())
// this returns 404 not found error
foo := &foov1beta1.Foo{}
depKey := types.NamespacedName{Name: "foo-1")}
g.Eventually(func() error { return c.Get(context.TODO(), depKey, foo) }, timeout).Should(gomega.Succeed()) Is cache-reading relevant here? |
you shouldn't be reading from the cache in a test -- don't use |
Issues go stale after 90d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
closing this as no response |
@DirectXMan12 Sorry about interrupting this closed issue. I had the same situation that we can list resources but could not get the resource, and these actions were not happening after creations. Do we have any different path from local cache between
|
No, that shouldn't happen. Is Aside: I'd highly reccomend using a live client in the test bodies themselves, otherwise you'll get flaky tests (the standard caching client is fine in the controllers themselves, but for your test assertions, the live client is much better generally). |
@DirectXMan12 Hi, they're kube native resources. I could not get specified StatefulSet but can list them. And yes, them are namespaced resources. And it's in our reconciliation loop. |
since they're namespaced, you'll need |
@DirectXMan12 Sorry for late. correct my sentence that my request had right namespace. The point is that I could As the issue suggested, I got the resource from the direct client for a workaround. |
Fix domain resource issues in controller
I have the same issue. Now I have my operator,based on operator-sdk 0.15.1. I try to get/list the controller CRD from my controller. But I can not. The operator uses this api. The result is empty, both of them as below:
Get:
But I can use the clientset of the controller get the right result. What confuses me is I can get/list all the CRD with kubectl, but not with this api. Not sure if I missed something? |
* Use a KubeClient in EnvTest that always hits APIServer to avoid cache latency and inconsistency issues that can cause races and intermittent test failures. See kubernetes-sigs/controller-runtime#1464 and kubernetes-sigs/controller-runtime#343 for details. * Write Status after Spec. This ensures that tests waiting for a status update cannot possibly see it so fast that they go on to perform a write that conflicts with the Spec write of the controller. * Improve log messages to be clearer (aids in test debugging).
* Use a KubeClient in EnvTest that always hits APIServer to avoid cache latency and inconsistency issues that can cause races and intermittent test failures. See kubernetes-sigs/controller-runtime#1464 and kubernetes-sigs/controller-runtime#343 for details. * Write Status after Spec. This ensures that tests waiting for a status update cannot possibly see it so fast that they go on to perform a write that conflicts with the Spec write of the controller. * Improve log messages to be clearer (aids in test debugging).
* Use a KubeClient in EnvTest that always hits APIServer to avoid cache latency and inconsistency issues that can cause races and intermittent test failures. See kubernetes-sigs/controller-runtime#1464 and kubernetes-sigs/controller-runtime#343 for details. * Write Status after Spec. This ensures that tests waiting for a status update cannot possibly see it so fast that they go on to perform a write that conflicts with the Spec write of the controller. * Improve log messages to be clearer (aids in test debugging).
* Use a KubeClient in EnvTest that always hits APIServer to avoid cache latency and inconsistency issues that can cause races and intermittent test failures. See kubernetes-sigs/controller-runtime#1464 and kubernetes-sigs/controller-runtime#343 for details. * Write Status after Spec. This ensures that tests waiting for a status update cannot possibly see it so fast that they go on to perform a write that conflicts with the Spec write of the controller. * Improve log messages to be clearer (aids in test debugging).
* Use a KubeClient in EnvTest that always hits APIServer to avoid cache latency and inconsistency issues that can cause races and intermittent test failures. See kubernetes-sigs/controller-runtime#1464 and kubernetes-sigs/controller-runtime#343 for details. * Write Status after Spec. This ensures that tests waiting for a status update cannot possibly see it so fast that they go on to perform a write that conflicts with the Spec write of the controller. * Improve log messages to be clearer (aids in test debugging).
* Reduce test flakiness * Use a KubeClient in EnvTest that always hits APIServer to avoid cache latency and inconsistency issues that can cause races and intermittent test failures. See kubernetes-sigs/controller-runtime#1464 and kubernetes-sigs/controller-runtime#343 for details. * Write Status after Spec. This ensures that tests waiting for a status update cannot possibly see it so fast that they go on to perform a write that conflicts with the Spec write of the controller. * Improve log messages to be clearer (aids in test debugging). * Verify that finalizer is set before delete Prior to performing any deletion actions (either monitoring or deletion), verify that the finalizer is still set. If it's not set, immediately allow the k8s resource to be deleted. Don't take any action on the Azure resource in this instance.
Hi!
I'm tearing my hair out trying to debug this issue.
When run, I get this error:
Outside the program, though:
Stepping through the code, my theory is that the
Create
call doesn't store the object in the cache, and theGet
call only looks at the cache.How should I go about debugging this?
Is this because
CuscoServiceConfig
is a CustomResource?The text was updated successfully, but these errors were encountered: