Backfill tests to OIDCProviderConfig controller
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
This commit is contained in:
parent
fac4d074d0
commit
bb015adf4e
@ -86,7 +86,7 @@ func (c *oidcProviderConfigWatcherController) Sync(ctx controllerlib.Context) er
|
|||||||
opc.Namespace,
|
opc.Namespace,
|
||||||
opc.Name,
|
opc.Name,
|
||||||
configv1alpha1.DuplicateOIDCProviderStatus,
|
configv1alpha1.DuplicateOIDCProviderStatus,
|
||||||
"Duplicate issuer",
|
"Duplicate issuer: "+opc.Spec.Issuer,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
errs.Add(fmt.Errorf("could not update status: %w", err))
|
errs.Add(fmt.Errorf("could not update status: %w", err))
|
||||||
}
|
}
|
||||||
@ -107,7 +107,6 @@ func (c *oidcProviderConfigWatcherController) Sync(ctx controllerlib.Context) er
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
oidcProviders = append(oidcProviders, oidcProvider)
|
|
||||||
if err := c.updateStatus(
|
if err := c.updateStatus(
|
||||||
ctx.Context,
|
ctx.Context,
|
||||||
opc.Namespace,
|
opc.Namespace,
|
||||||
@ -116,7 +115,9 @@ func (c *oidcProviderConfigWatcherController) Sync(ctx controllerlib.Context) er
|
|||||||
"Provider successfully created",
|
"Provider successfully created",
|
||||||
); err != nil {
|
); err != nil {
|
||||||
errs.Add(fmt.Errorf("could not update status: %w", err))
|
errs.Add(fmt.Errorf("could not update status: %w", err))
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
oidcProviders = append(oidcProviders, oidcProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.providerSetter.SetProviders(oidcProviders...)
|
c.providerSetter.SetProviders(oidcProviders...)
|
||||||
|
@ -5,19 +5,27 @@ package supervisorconfig
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sclevine/spec"
|
"github.com/sclevine/spec"
|
||||||
"github.com/sclevine/spec/report"
|
"github.com/sclevine/spec/report"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/util/clock"
|
"k8s.io/apimachinery/pkg/util/clock"
|
||||||
|
coretesting "k8s.io/client-go/testing"
|
||||||
|
|
||||||
"go.pinniped.dev/generated/1.19/apis/config/v1alpha1"
|
"go.pinniped.dev/generated/1.19/apis/config/v1alpha1"
|
||||||
pinnipedfake "go.pinniped.dev/generated/1.19/client/clientset/versioned/fake"
|
pinnipedfake "go.pinniped.dev/generated/1.19/client/clientset/versioned/fake"
|
||||||
pinnipedinformers "go.pinniped.dev/generated/1.19/client/informers/externalversions"
|
pinnipedinformers "go.pinniped.dev/generated/1.19/client/informers/externalversions"
|
||||||
"go.pinniped.dev/internal/controllerlib"
|
"go.pinniped.dev/internal/controllerlib"
|
||||||
|
"go.pinniped.dev/internal/here"
|
||||||
"go.pinniped.dev/internal/oidc/provider"
|
"go.pinniped.dev/internal/oidc/provider"
|
||||||
"go.pinniped.dev/internal/testutil"
|
"go.pinniped.dev/internal/testutil"
|
||||||
)
|
)
|
||||||
@ -85,6 +93,8 @@ func (f *fakeProvidersSetter) SetProviders(oidcProviders ...*provider.OIDCProvid
|
|||||||
|
|
||||||
func TestSync(t *testing.T) {
|
func TestSync(t *testing.T) {
|
||||||
spec.Run(t, "Sync", func(t *testing.T, when spec.G, it spec.S) {
|
spec.Run(t, "Sync", func(t *testing.T, when spec.G, it spec.S) {
|
||||||
|
const namespace = "some-namespace"
|
||||||
|
|
||||||
var r *require.Assertions
|
var r *require.Assertions
|
||||||
|
|
||||||
var subject controllerlib.Controller
|
var subject controllerlib.Controller
|
||||||
@ -96,6 +106,7 @@ func TestSync(t *testing.T) {
|
|||||||
var syncContext *controllerlib.Context
|
var syncContext *controllerlib.Context
|
||||||
var frozenNow time.Time
|
var frozenNow time.Time
|
||||||
var providersSetter *fakeProvidersSetter
|
var providersSetter *fakeProvidersSetter
|
||||||
|
var oidcProviderConfigGVR schema.GroupVersionResource
|
||||||
|
|
||||||
// Defer starting the informers until the last possible moment so that the
|
// Defer starting the informers until the last possible moment so that the
|
||||||
// nested Before's can keep adding things to the informer caches.
|
// nested Before's can keep adding things to the informer caches.
|
||||||
@ -114,7 +125,7 @@ func TestSync(t *testing.T) {
|
|||||||
Context: timeoutContext,
|
Context: timeoutContext,
|
||||||
Name: subject.Name(),
|
Name: subject.Name(),
|
||||||
Key: controllerlib.Key{
|
Key: controllerlib.Key{
|
||||||
Namespace: "some-namespace",
|
Namespace: namespace,
|
||||||
Name: "config-name",
|
Name: "config-name",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -135,6 +146,12 @@ func TestSync(t *testing.T) {
|
|||||||
opcInformerClient = pinnipedfake.NewSimpleClientset()
|
opcInformerClient = pinnipedfake.NewSimpleClientset()
|
||||||
opcInformers = pinnipedinformers.NewSharedInformerFactory(opcInformerClient, 0)
|
opcInformers = pinnipedinformers.NewSharedInformerFactory(opcInformerClient, 0)
|
||||||
pinnipedAPIClient = pinnipedfake.NewSimpleClientset()
|
pinnipedAPIClient = pinnipedfake.NewSimpleClientset()
|
||||||
|
|
||||||
|
oidcProviderConfigGVR = schema.GroupVersionResource{
|
||||||
|
Group: v1alpha1.SchemeGroupVersion.Group,
|
||||||
|
Version: v1alpha1.SchemeGroupVersion.Version,
|
||||||
|
Resource: "oidcproviderconfigs",
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it.After(func() {
|
it.After(func() {
|
||||||
@ -142,45 +159,632 @@ func TestSync(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
when("there are some valid OIDCProviderConfigs in the informer", func() {
|
when("there are some valid OIDCProviderConfigs in the informer", func() {
|
||||||
|
var (
|
||||||
|
oidcProviderConfig1 *v1alpha1.OIDCProviderConfig
|
||||||
|
oidcProviderConfig2 *v1alpha1.OIDCProviderConfig
|
||||||
|
)
|
||||||
|
|
||||||
it.Before(func() {
|
it.Before(func() {
|
||||||
oidcProviderConfig1 := &v1alpha1.OIDCProviderConfig{
|
oidcProviderConfig1 = &v1alpha1.OIDCProviderConfig{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "config1", Namespace: "some-namespace"},
|
ObjectMeta: metav1.ObjectMeta{Name: "config1", Namespace: namespace},
|
||||||
Spec: v1alpha1.OIDCProviderConfigSpec{Issuer: "https://issuer1.com"},
|
Spec: v1alpha1.OIDCProviderConfigSpec{Issuer: "https://issuer1.com"},
|
||||||
}
|
}
|
||||||
r.NoError(pinnipedAPIClient.Tracker().Add(oidcProviderConfig1))
|
r.NoError(pinnipedAPIClient.Tracker().Add(oidcProviderConfig1))
|
||||||
r.NoError(opcInformerClient.Tracker().Add(oidcProviderConfig1))
|
r.NoError(opcInformerClient.Tracker().Add(oidcProviderConfig1))
|
||||||
|
|
||||||
oidcProviderConfig2 := &v1alpha1.OIDCProviderConfig{
|
oidcProviderConfig2 = &v1alpha1.OIDCProviderConfig{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "config2", Namespace: "some-namespace"},
|
ObjectMeta: metav1.ObjectMeta{Name: "config2", Namespace: namespace},
|
||||||
Spec: v1alpha1.OIDCProviderConfigSpec{Issuer: "https://issuer2.com"},
|
Spec: v1alpha1.OIDCProviderConfigSpec{Issuer: "https://issuer2.com"},
|
||||||
}
|
}
|
||||||
r.NoError(pinnipedAPIClient.Tracker().Add(oidcProviderConfig2))
|
r.NoError(pinnipedAPIClient.Tracker().Add(oidcProviderConfig2))
|
||||||
r.NoError(opcInformerClient.Tracker().Add(oidcProviderConfig2))
|
r.NoError(opcInformerClient.Tracker().Add(oidcProviderConfig2))
|
||||||
})
|
})
|
||||||
|
|
||||||
it("calls the ProvidersSetter and updates the OIDCProviderConfigs", func() {
|
it("calls the ProvidersSetter", func() {
|
||||||
startInformersAndController()
|
startInformersAndController()
|
||||||
err := controllerlib.TestSync(t, subject, *syncContext)
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
|
|
||||||
r.True(providersSetter.SetProvidersWasCalled)
|
provider1, err := provider.NewOIDCProvider(oidcProviderConfig1.Spec.Issuer)
|
||||||
r.Len(providersSetter.OIDCProvidersReceived, 2)
|
r.NoError(err)
|
||||||
|
|
||||||
// TODO make more assertions about the OIDCProvidersReceived
|
provider2, err := provider.NewOIDCProvider(oidcProviderConfig2.Spec.Issuer)
|
||||||
// TODO make assertions about the expected pinnipedAPIClient.Actions()
|
r.NoError(err)
|
||||||
|
|
||||||
|
r.True(providersSetter.SetProvidersWasCalled)
|
||||||
|
r.ElementsMatch(
|
||||||
|
[]*provider.OIDCProvider{
|
||||||
|
provider1,
|
||||||
|
provider2,
|
||||||
|
},
|
||||||
|
providersSetter.OIDCProvidersReceived,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("updates the status to success in the OIDCProviderConfigs", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
oidcProviderConfig1.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
oidcProviderConfig1.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
oidcProviderConfig2.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
oidcProviderConfig2.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
expectedActions := []coretesting.Action{
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig1.Namespace,
|
||||||
|
oidcProviderConfig1.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig1.Namespace,
|
||||||
|
oidcProviderConfig1,
|
||||||
|
),
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig2.Namespace,
|
||||||
|
oidcProviderConfig2.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig2.Namespace,
|
||||||
|
oidcProviderConfig2,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
r.ElementsMatch(expectedActions, pinnipedAPIClient.Actions())
|
||||||
|
})
|
||||||
|
|
||||||
|
when("one OIDCProviderConfig is already up to date", func() {
|
||||||
|
it.Before(func() {
|
||||||
|
oidcProviderConfig1.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
oidcProviderConfig1.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
r.NoError(pinnipedAPIClient.Tracker().Update(oidcProviderConfigGVR, oidcProviderConfig1, oidcProviderConfig1.Namespace))
|
||||||
|
r.NoError(opcInformerClient.Tracker().Update(oidcProviderConfigGVR, oidcProviderConfig1, oidcProviderConfig1.Namespace))
|
||||||
|
})
|
||||||
|
|
||||||
|
it("only updates the out-of-date OIDCProviderConfig", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
oidcProviderConfig2.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
oidcProviderConfig2.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
expectedActions := []coretesting.Action{
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig1.Namespace,
|
||||||
|
oidcProviderConfig1.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig2.Namespace,
|
||||||
|
oidcProviderConfig2.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig2.Namespace,
|
||||||
|
oidcProviderConfig2,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
r.ElementsMatch(expectedActions, pinnipedAPIClient.Actions())
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls the ProvidersSetter with both OIDCProviderConfig's", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
provider1, err := provider.NewOIDCProvider(oidcProviderConfig1.Spec.Issuer)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
provider2, err := provider.NewOIDCProvider(oidcProviderConfig2.Spec.Issuer)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
r.True(providersSetter.SetProvidersWasCalled)
|
||||||
|
r.ElementsMatch(
|
||||||
|
[]*provider.OIDCProvider{
|
||||||
|
provider1,
|
||||||
|
provider2,
|
||||||
|
},
|
||||||
|
providersSetter.OIDCProvidersReceived,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
when("updating only one OIDCProviderConfig fails for a reason other than conflict", func() {
|
||||||
|
it.Before(func() {
|
||||||
|
once := sync.Once{}
|
||||||
|
pinnipedAPIClient.PrependReactor(
|
||||||
|
"update",
|
||||||
|
"oidcproviderconfigs",
|
||||||
|
func(_ coretesting.Action) (bool, runtime.Object, error) {
|
||||||
|
var err error
|
||||||
|
once.Do(func() {
|
||||||
|
err = errors.New("some update error")
|
||||||
|
})
|
||||||
|
return true, nil, err
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("sets the provider that it could actually update in the API", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.EqualError(err, "1 error(s):\n- could not update status: some update error")
|
||||||
|
|
||||||
|
provider1, err := provider.NewOIDCProvider(oidcProviderConfig1.Spec.Issuer)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
provider2, err := provider.NewOIDCProvider(oidcProviderConfig2.Spec.Issuer)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
r.True(providersSetter.SetProvidersWasCalled)
|
||||||
|
r.Len(providersSetter.OIDCProvidersReceived, 1)
|
||||||
|
r.True(
|
||||||
|
reflect.DeepEqual(providersSetter.OIDCProvidersReceived[0], provider1) ||
|
||||||
|
reflect.DeepEqual(providersSetter.OIDCProvidersReceived[0], provider2),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns an error", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.EqualError(err, "1 error(s):\n- could not update status: some update error")
|
||||||
|
|
||||||
|
oidcProviderConfig1.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
oidcProviderConfig1.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
oidcProviderConfig2.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
oidcProviderConfig2.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
expectedActions := []coretesting.Action{
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig1.Namespace,
|
||||||
|
oidcProviderConfig1.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig1.Namespace,
|
||||||
|
oidcProviderConfig1,
|
||||||
|
),
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig2.Namespace,
|
||||||
|
oidcProviderConfig2.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig2.Namespace,
|
||||||
|
oidcProviderConfig2,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
r.ElementsMatch(expectedActions, pinnipedAPIClient.Actions())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
when("there are errors updating the OIDCProviderConfigs", func() {
|
||||||
|
var (
|
||||||
|
oidcProviderConfig *v1alpha1.OIDCProviderConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
it.Before(func() {
|
||||||
|
oidcProviderConfig = &v1alpha1.OIDCProviderConfig{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "config", Namespace: namespace},
|
||||||
|
Spec: v1alpha1.OIDCProviderConfigSpec{Issuer: "https://issuer.com"},
|
||||||
|
}
|
||||||
|
r.NoError(pinnipedAPIClient.Tracker().Add(oidcProviderConfig))
|
||||||
|
r.NoError(opcInformerClient.Tracker().Add(oidcProviderConfig))
|
||||||
})
|
})
|
||||||
|
|
||||||
when("there is a conflict while updating an OIDCProviderConfig", func() {
|
when("there is a conflict while updating an OIDCProviderConfig", func() {
|
||||||
// TODO write this test
|
it.Before(func() {
|
||||||
|
once := sync.Once{}
|
||||||
|
pinnipedAPIClient.PrependReactor(
|
||||||
|
"update",
|
||||||
|
"oidcproviderconfigs",
|
||||||
|
func(_ coretesting.Action) (bool, runtime.Object, error) {
|
||||||
|
var err error
|
||||||
|
once.Do(func() {
|
||||||
|
err = k8serrors.NewConflict(schema.GroupResource{}, "", nil)
|
||||||
|
})
|
||||||
|
return true, nil, err
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("retries updating the OIDCProviderConfig", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
oidcProviderConfig.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
oidcProviderConfig.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
expectedActions := []coretesting.Action{
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig.Namespace,
|
||||||
|
oidcProviderConfig.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig.Namespace,
|
||||||
|
oidcProviderConfig,
|
||||||
|
),
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig.Namespace,
|
||||||
|
oidcProviderConfig.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig.Namespace,
|
||||||
|
oidcProviderConfig,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
r.Equal(expectedActions, pinnipedAPIClient.Actions())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
when("updating the OIDCProviderConfig fails for a reason other than conflict", func() {
|
||||||
|
it.Before(func() {
|
||||||
|
pinnipedAPIClient.PrependReactor(
|
||||||
|
"update",
|
||||||
|
"oidcproviderconfigs",
|
||||||
|
func(_ coretesting.Action) (bool, runtime.Object, error) {
|
||||||
|
return true, nil, errors.New("some update error")
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns an error", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.EqualError(err, "1 error(s):\n- could not update status: some update error")
|
||||||
|
|
||||||
|
oidcProviderConfig.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
oidcProviderConfig.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
expectedActions := []coretesting.Action{
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig.Namespace,
|
||||||
|
oidcProviderConfig.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig.Namespace,
|
||||||
|
oidcProviderConfig,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
r.Equal(expectedActions, pinnipedAPIClient.Actions())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
when("there is an error when getting the OIDCProviderConfig", func() {
|
||||||
|
it.Before(func() {
|
||||||
|
pinnipedAPIClient.PrependReactor(
|
||||||
|
"get",
|
||||||
|
"oidcproviderconfigs",
|
||||||
|
func(_ coretesting.Action) (bool, runtime.Object, error) {
|
||||||
|
return true, nil, errors.New("some get error")
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns the get error", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.EqualError(err, "1 error(s):\n- could not update status: get failed: some get error")
|
||||||
|
|
||||||
|
oidcProviderConfig.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
oidcProviderConfig.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
expectedActions := []coretesting.Action{
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig.Namespace,
|
||||||
|
oidcProviderConfig.Name,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
r.Equal(expectedActions, pinnipedAPIClient.Actions())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
when("there are both valid and invalid OIDCProviderConfigs in the informer", func() {
|
when("there are both valid and invalid OIDCProviderConfigs in the informer", func() {
|
||||||
// TODO write this test
|
var (
|
||||||
|
validOIDCProviderConfig *v1alpha1.OIDCProviderConfig
|
||||||
|
invalidOIDCProviderConfig *v1alpha1.OIDCProviderConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
it.Before(func() {
|
||||||
|
validOIDCProviderConfig = &v1alpha1.OIDCProviderConfig{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "valid-config", Namespace: namespace},
|
||||||
|
Spec: v1alpha1.OIDCProviderConfigSpec{Issuer: "https://valid-issuer.com"},
|
||||||
|
}
|
||||||
|
r.NoError(pinnipedAPIClient.Tracker().Add(validOIDCProviderConfig))
|
||||||
|
r.NoError(opcInformerClient.Tracker().Add(validOIDCProviderConfig))
|
||||||
|
|
||||||
|
invalidOIDCProviderConfig = &v1alpha1.OIDCProviderConfig{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "invalid-config", Namespace: namespace},
|
||||||
|
Spec: v1alpha1.OIDCProviderConfigSpec{Issuer: "https://invalid-issuer.com?some=query"},
|
||||||
|
}
|
||||||
|
r.NoError(pinnipedAPIClient.Tracker().Add(invalidOIDCProviderConfig))
|
||||||
|
r.NoError(opcInformerClient.Tracker().Add(invalidOIDCProviderConfig))
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls the ProvidersSetter with the valid provider", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
validProvider, err := provider.NewOIDCProvider(validOIDCProviderConfig.Spec.Issuer)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
r.True(providersSetter.SetProvidersWasCalled)
|
||||||
|
r.Equal(
|
||||||
|
[]*provider.OIDCProvider{
|
||||||
|
validProvider,
|
||||||
|
},
|
||||||
|
providersSetter.OIDCProvidersReceived,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("updates the status to success/invalid in the OIDCProviderConfigs", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
validOIDCProviderConfig.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
validOIDCProviderConfig.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
invalidOIDCProviderConfig.Status.Status = v1alpha1.InvalidOIDCProviderStatus
|
||||||
|
invalidOIDCProviderConfig.Status.Message = "Invalid: issuer must not have query"
|
||||||
|
|
||||||
|
expectedActions := []coretesting.Action{
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
invalidOIDCProviderConfig.Namespace,
|
||||||
|
invalidOIDCProviderConfig.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
invalidOIDCProviderConfig.Namespace,
|
||||||
|
invalidOIDCProviderConfig,
|
||||||
|
),
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
validOIDCProviderConfig.Namespace,
|
||||||
|
validOIDCProviderConfig.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
validOIDCProviderConfig.Namespace,
|
||||||
|
validOIDCProviderConfig,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
r.ElementsMatch(expectedActions, pinnipedAPIClient.Actions())
|
||||||
|
})
|
||||||
|
|
||||||
|
when("updating only the invalid OIDCProviderConfig fails for a reason other than conflict", func() {
|
||||||
|
it.Before(func() {
|
||||||
|
pinnipedAPIClient.PrependReactor(
|
||||||
|
"update",
|
||||||
|
"oidcproviderconfigs",
|
||||||
|
func(action coretesting.Action) (bool, runtime.Object, error) {
|
||||||
|
updateAction := action.(coretesting.UpdateActionImpl)
|
||||||
|
opc := updateAction.Object.(*v1alpha1.OIDCProviderConfig)
|
||||||
|
if opc.Name == validOIDCProviderConfig.Name {
|
||||||
|
return true, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil, errors.New("some update error")
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("sets the provider that it could actually update in the API", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.EqualError(err, "1 error(s):\n- could not update status: some update error")
|
||||||
|
|
||||||
|
validProvider, err := provider.NewOIDCProvider(validOIDCProviderConfig.Spec.Issuer)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
r.True(providersSetter.SetProvidersWasCalled)
|
||||||
|
r.Equal(
|
||||||
|
[]*provider.OIDCProvider{
|
||||||
|
validProvider,
|
||||||
|
},
|
||||||
|
providersSetter.OIDCProvidersReceived,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns an error", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.EqualError(err, "1 error(s):\n- could not update status: some update error")
|
||||||
|
|
||||||
|
validOIDCProviderConfig.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
validOIDCProviderConfig.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
invalidOIDCProviderConfig.Status.Status = v1alpha1.InvalidOIDCProviderStatus
|
||||||
|
invalidOIDCProviderConfig.Status.Message = "Invalid: issuer must not have query"
|
||||||
|
|
||||||
|
expectedActions := []coretesting.Action{
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
invalidOIDCProviderConfig.Namespace,
|
||||||
|
invalidOIDCProviderConfig.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
invalidOIDCProviderConfig.Namespace,
|
||||||
|
invalidOIDCProviderConfig,
|
||||||
|
),
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
validOIDCProviderConfig.Namespace,
|
||||||
|
validOIDCProviderConfig.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
validOIDCProviderConfig.Namespace,
|
||||||
|
validOIDCProviderConfig,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
r.ElementsMatch(expectedActions, pinnipedAPIClient.Actions())
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
when("they there are OIDCProviderConfigs with duplicate issuer names in the informer", func() {
|
when("there are OIDCProviderConfigs with duplicate issuer names in the informer", func() {
|
||||||
// TODO write this test
|
var (
|
||||||
|
oidcProviderConfigDuplicate1 *v1alpha1.OIDCProviderConfig
|
||||||
|
oidcProviderConfigDuplicate2 *v1alpha1.OIDCProviderConfig
|
||||||
|
oidcProviderConfig *v1alpha1.OIDCProviderConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
it.Before(func() {
|
||||||
|
oidcProviderConfigDuplicate1 = &v1alpha1.OIDCProviderConfig{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "duplicate1", Namespace: namespace},
|
||||||
|
Spec: v1alpha1.OIDCProviderConfigSpec{Issuer: "https://issuer-duplicate.com"},
|
||||||
|
}
|
||||||
|
r.NoError(pinnipedAPIClient.Tracker().Add(oidcProviderConfigDuplicate1))
|
||||||
|
r.NoError(opcInformerClient.Tracker().Add(oidcProviderConfigDuplicate1))
|
||||||
|
oidcProviderConfigDuplicate2 = &v1alpha1.OIDCProviderConfig{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "duplicate2", Namespace: namespace},
|
||||||
|
Spec: v1alpha1.OIDCProviderConfigSpec{Issuer: "https://issuer-duplicate.com"},
|
||||||
|
}
|
||||||
|
r.NoError(pinnipedAPIClient.Tracker().Add(oidcProviderConfigDuplicate2))
|
||||||
|
r.NoError(opcInformerClient.Tracker().Add(oidcProviderConfigDuplicate2))
|
||||||
|
|
||||||
|
oidcProviderConfig = &v1alpha1.OIDCProviderConfig{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "not-duplicate", Namespace: namespace},
|
||||||
|
Spec: v1alpha1.OIDCProviderConfigSpec{Issuer: "https://issuer-not-duplicate.com"},
|
||||||
|
}
|
||||||
|
r.NoError(pinnipedAPIClient.Tracker().Add(oidcProviderConfig))
|
||||||
|
r.NoError(opcInformerClient.Tracker().Add(oidcProviderConfig))
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls the ProvidersSetter with the non-duplicate", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
nonDuplicateProvider, err := provider.NewOIDCProvider(oidcProviderConfig.Spec.Issuer)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
r.True(providersSetter.SetProvidersWasCalled)
|
||||||
|
r.Equal(
|
||||||
|
[]*provider.OIDCProvider{
|
||||||
|
nonDuplicateProvider,
|
||||||
|
},
|
||||||
|
providersSetter.OIDCProvidersReceived,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("updates the statuses", func() {
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
oidcProviderConfig.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
oidcProviderConfig.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
oidcProviderConfigDuplicate1.Status.Status = v1alpha1.DuplicateOIDCProviderStatus
|
||||||
|
oidcProviderConfigDuplicate1.Status.Message = "Duplicate issuer: https://issuer-duplicate.com"
|
||||||
|
|
||||||
|
oidcProviderConfigDuplicate2.Status.Status = v1alpha1.DuplicateOIDCProviderStatus
|
||||||
|
oidcProviderConfigDuplicate2.Status.Message = "Duplicate issuer: https://issuer-duplicate.com"
|
||||||
|
|
||||||
|
expectedActions := []coretesting.Action{
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfigDuplicate1.Namespace,
|
||||||
|
oidcProviderConfigDuplicate1.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfigDuplicate1.Namespace,
|
||||||
|
oidcProviderConfigDuplicate1,
|
||||||
|
),
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfigDuplicate2.Namespace,
|
||||||
|
oidcProviderConfigDuplicate2.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfigDuplicate2.Namespace,
|
||||||
|
oidcProviderConfigDuplicate2,
|
||||||
|
),
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig.Namespace,
|
||||||
|
oidcProviderConfig.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewUpdateAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig.Namespace,
|
||||||
|
oidcProviderConfig,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
r.ElementsMatch(expectedActions, pinnipedAPIClient.Actions())
|
||||||
|
})
|
||||||
|
|
||||||
|
when("we cannot talk to the API", func() {
|
||||||
|
it.Before(func() {
|
||||||
|
pinnipedAPIClient.PrependReactor(
|
||||||
|
"get",
|
||||||
|
"oidcproviderconfigs",
|
||||||
|
func(_ coretesting.Action) (bool, runtime.Object, error) {
|
||||||
|
return true, nil, errors.New("some get error")
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns the get errors", func() {
|
||||||
|
expectedError := here.Doc(`
|
||||||
|
3 error(s):
|
||||||
|
- could not update status: get failed: some get error
|
||||||
|
- could not update status: get failed: some get error
|
||||||
|
- could not update status: get failed: some get error`)
|
||||||
|
startInformersAndController()
|
||||||
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
|
r.EqualError(err, expectedError)
|
||||||
|
|
||||||
|
oidcProviderConfig.Status.Status = v1alpha1.SuccessOIDCProviderStatus
|
||||||
|
oidcProviderConfig.Status.Message = "Provider successfully created"
|
||||||
|
|
||||||
|
expectedActions := []coretesting.Action{
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfigDuplicate1.Namespace,
|
||||||
|
oidcProviderConfigDuplicate1.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfigDuplicate2.Namespace,
|
||||||
|
oidcProviderConfigDuplicate2.Name,
|
||||||
|
),
|
||||||
|
coretesting.NewGetAction(
|
||||||
|
oidcProviderConfigGVR,
|
||||||
|
oidcProviderConfig.Namespace,
|
||||||
|
oidcProviderConfig.Name,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
r.ElementsMatch(expectedActions, pinnipedAPIClient.Actions())
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
when("there are no OIDCProviderConfigs in the informer", func() {
|
when("there are no OIDCProviderConfigs in the informer", func() {
|
||||||
|
@ -17,6 +17,14 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// formatFunc is a function used to format the string representing of a MultiError. It is used in the
|
||||||
|
// Error() function.
|
||||||
|
//
|
||||||
|
// It is marked out here to indicate how we could potentially extend MultiError in the future to
|
||||||
|
// support more styles of converting from a list of error's to a string.
|
||||||
|
//nolint: gochecknoglobals
|
||||||
|
var formatFunc func(errs MultiError, sb *strings.Builder) = defaultFormat
|
||||||
|
|
||||||
// MultiError holds a list of error's, that could potentially be empty.
|
// MultiError holds a list of error's, that could potentially be empty.
|
||||||
//
|
//
|
||||||
// Use New() to create a MultiError.
|
// Use New() to create a MultiError.
|
||||||
@ -35,10 +43,7 @@ func (m *MultiError) Add(err error) {
|
|||||||
// Error implements the error.Error() interface method.
|
// Error implements the error.Error() interface method.
|
||||||
func (m MultiError) Error() string {
|
func (m MultiError) Error() string {
|
||||||
sb := strings.Builder{}
|
sb := strings.Builder{}
|
||||||
_, _ = fmt.Fprintf(&sb, "%d error(s):", len(m))
|
formatFunc(m, &sb)
|
||||||
for _, err := range m {
|
|
||||||
_, _ = fmt.Fprintf(&sb, "\n- %s", err.Error())
|
|
||||||
}
|
|
||||||
return sb.String()
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,3 +54,10 @@ func (m MultiError) ErrOrNil() error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func defaultFormat(errs MultiError, sb *strings.Builder) {
|
||||||
|
_, _ = fmt.Fprintf(sb, "%d error(s):", len(errs))
|
||||||
|
for _, err := range errs {
|
||||||
|
_, _ = fmt.Fprintf(sb, "\n- %s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user