add test for error when informers are not ready

This commit is contained in:
Alexander Zielenski 2022-11-09 15:28:37 -08:00
parent df315f347c
commit acf571fcbe

View File

@ -227,7 +227,7 @@ func (f *fakeCompiler) RegisterBinding(binding *v1alpha1.ValidatingAdmissionPoli
} }
func setupFakeTest(t *testing.T, comp *fakeCompiler) (plugin admission.ValidationInterface, paramTracker, policyTracker clienttesting.ObjectTracker, controller *celAdmissionController) { func setupFakeTest(t *testing.T, comp *fakeCompiler) (plugin admission.ValidationInterface, paramTracker, policyTracker clienttesting.ObjectTracker, controller *celAdmissionController) {
return setupTestCommon(t, comp) return setupTestCommon(t, comp, true)
} }
// Starts CEL admission controller and sets up a plugin configured with it as well // Starts CEL admission controller and sets up a plugin configured with it as well
@ -237,7 +237,9 @@ func setupFakeTest(t *testing.T, comp *fakeCompiler) (plugin admission.Validatio
// support multiple types of params this function needs to be augmented // support multiple types of params this function needs to be augmented
// //
// PolicyTracker expects FakePolicyDefinition and FakePolicyBinding types // PolicyTracker expects FakePolicyDefinition and FakePolicyBinding types
func setupTestCommon(t *testing.T, compiler ValidatorCompiler) (plugin admission.ValidationInterface, paramTracker, policyTracker clienttesting.ObjectTracker, controller *celAdmissionController) { // !TODO: refactor this test/framework to remove startInformers argument and
// clean up the return args, and in general make it more accessible.
func setupTestCommon(t *testing.T, compiler ValidatorCompiler, shouldStartInformers bool) (plugin admission.ValidationInterface, paramTracker, policyTracker clienttesting.ObjectTracker, controller *celAdmissionController) {
testContext, testContextCancel := context.WithCancel(context.Background()) testContext, testContextCancel := context.WithCancel(context.Background())
t.Cleanup(testContextCancel) t.Cleanup(testContextCancel)
@ -259,7 +261,11 @@ func setupTestCommon(t *testing.T, compiler ValidatorCompiler) (plugin admission
panic("Unexpected error.") panic("Unexpected error.")
} }
handler := &celAdmissionPlugin{enabled: true} plug, err := NewPlugin()
require.NoError(t, err)
handler := plug.(*celAdmissionPlugin)
handler.enabled = true
genericInitializer := initializer.New(fakeClient, dynamicClient, fakeInformerFactory, nil, featureGate, testContext.Done()) genericInitializer := initializer.New(fakeClient, dynamicClient, fakeInformerFactory, nil, featureGate, testContext.Done())
genericInitializer.Initialize(handler) genericInitializer.Initialize(handler)
@ -272,14 +278,19 @@ func setupTestCommon(t *testing.T, compiler ValidatorCompiler) (plugin admission
controller = handler.evaluator.(*celAdmissionController) controller = handler.evaluator.(*celAdmissionController)
controller.validatorCompiler = compiler controller.validatorCompiler = compiler
// Make sure to start the fake informers
fakeInformerFactory.Start(testContext.Done())
t.Cleanup(func() { t.Cleanup(func() {
testContextCancel() testContextCancel()
// wait for informer factory to shutdown // wait for informer factory to shutdown
fakeInformerFactory.Shutdown() fakeInformerFactory.Shutdown()
}) })
if !shouldStartInformers {
return handler, dynamicClient.Tracker(), fakeClient.Tracker(), controller
}
// Make sure to start the fake informers
fakeInformerFactory.Start(testContext.Done())
// Wait for admission controller to begin its object watches // Wait for admission controller to begin its object watches
// This is because there is a very rare (0.05% on my machine) race doing the // This is because there is a very rare (0.05% on my machine) race doing the
// initial List+Watch if an object is added after the list, but before the // initial List+Watch if an object is added after the list, but before the
@ -532,6 +543,38 @@ func must3[T any, I any](val T, _ I, err error) T {
// Functionality Tests // Functionality Tests
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
func TestPluginNotReady(t *testing.T) {
compiler := &fakeCompiler{
// Match everything by default
DefaultMatch: true,
}
// Show that an unstarted informer (or one that has failed its listwatch)
// will show proper error from plugin
handler, _, _, _ := setupTestCommon(t, compiler, false)
err := handler.Validate(
context.Background(),
// Object is irrelevant/unchecked for this test. Just test that
// the evaluator is executed, and returns a denial
attributeRecord(nil, fakeParams, admission.Create),
&admission.RuntimeObjectInterfaces{},
)
require.ErrorContains(t, err, "not yet ready to handle request")
// Show that by now starting the informer, the error is dissipated
handler, _, _, _ = setupTestCommon(t, compiler, true)
err = handler.Validate(
context.Background(),
// Object is irrelevant/unchecked for this test. Just test that
// the evaluator is executed, and returns a denial
attributeRecord(nil, fakeParams, admission.Create),
&admission.RuntimeObjectInterfaces{},
)
require.NoError(t, err)
}
func TestBasicPolicyDefinitionFailure(t *testing.T) { func TestBasicPolicyDefinitionFailure(t *testing.T) {
testContext, testContextCancel := context.WithCancel(context.Background()) testContext, testContextCancel := context.WithCancel(context.Background())
defer testContextCancel() defer testContextCancel()