From 47dd3895dc581dd94070b8d791e6d00632f731f3 Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Thu, 8 Jun 2017 12:13:17 -0700 Subject: [PATCH] Making the controller handle unexpected provision results Fixes https://github.com/kubernetes-incubator/service-catalog/issues/914 --- pkg/controller/controller_instance_test.go | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/pkg/controller/controller_instance_test.go b/pkg/controller/controller_instance_test.go index 1d812375667..b176d248c66 100644 --- a/pkg/controller/controller_instance_test.go +++ b/pkg/controller/controller_instance_test.go @@ -29,6 +29,7 @@ import ( checksum "github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/checksum/versioned/v1alpha1" "github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/v1alpha1" "github.com/kubernetes-incubator/service-catalog/pkg/brokerapi" + fakebrokerserver "github.com/kubernetes-incubator/service-catalog/pkg/brokerapi/fake/server" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -558,6 +559,80 @@ func TestReconcileInstanceAsynchronousNoOperation(t *testing.T) { assertInstanceLastOperation(t, updatedInstance, "") } +// TestReconcileInstanceAsynchronousUnsupportedBrokerError tests to ensure that, on an asynchronous +// provision, an Instance's conditions get set with a Broker failure that is not one of the +// "expected" response codes in the OSB API spec for provision. +// See https://github.com/openservicebrokerapi/servicebroker/blob/master/spec.md#response-2 for +// the list of expected codes and a description of what we should do if another code is returned +func TestReconcileInstanceAsynchronousUnsupportedBrokerError(t *testing.T) { + const ( + brokerUsername = "testbrokeruser" + brokerPassword = "testbrokerpass" + ) + controllerItems, err := newTestControllerWithBrokerServer(brokerUsername, brokerPassword) + + if err != nil { + t.Fatal(err) + } + defer controllerItems.Close() + + fakeKubeClient := controllerItems.FakeKubeClient + fakeCatalogClient := controllerItems.FakeCatalogClient + fakeBrokerServerHandler := controllerItems.BrokerServerHandler + testController := controllerItems.Controller + sharedInformers := controllerItems.Informers + + fakeBrokerServerHandler.Catalog = fakebrokerserver.ConvertCatalog(getTestCatalog()) + + fakeKubeClient.AddReactor("get", "namespaces", func(action clientgotesting.Action) (bool, runtime.Object, error) { + return true, &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + UID: types.UID("test_uid_foo"), + }, + }, nil + }) + + sharedInformers.Brokers().Informer().GetStore().Add(getTestBroker()) + sharedInformers.ServiceClasses().Informer().GetStore().Add(getTestServiceClass()) + + // Make the provision return an error that is "unexpected" + fakeBrokerServerHandler.ProvisionRespError = errors.New("test provision error") + instance := getTestInstance() + + if testController.pollingQueue.Len() != 0 { + t.Fatalf("Expected the polling queue to be empty") + } + + testController.reconcileInstance(instance) + + actions := fakeCatalogClient.Actions() + assertNumberOfActions(t, actions, 1) + + // verify no kube resources created. + // One single action comes from getting namespace uid + kubeActions := fakeKubeClient.Actions() + if e, a := 1, len(kubeActions); e != a { + t.Fatalf("Unexpected number of actions: expected %v, got %v", e, a) + } + + updatedInstance := assertUpdateStatus(t, actions[0], instance) + assertInstanceReadyFalse(t, updatedInstance) + + // ensure that no requests to the provision endpoint were made + numProvReqs := len(fakeBrokerServerHandler.ProvisionRequests) + if numProvReqs != 1 { + t.Fatalf("%d provision requests were made, expected 1", numProvReqs) + } + + // The item should not have been added to the polling queue for later processing + if testController.pollingQueue.Len() != 0 { + t.Fatalf("Expected polling queue to be empty") + } + assertAsyncOpInProgressFalse(t, updatedInstance) + assertInstanceReadyFalse(t, updatedInstance) + assertInstanceReadyCondition(t, updatedInstance, v1alpha1.ConditionFalse) +} + func TestReconcileInstanceNamespaceError(t *testing.T) { fakeKubeClient, fakeCatalogClient, fakeBrokerClient, testController, sharedInformers := newTestController(t)