ContainerImage.Pinniped/internal/controller/issuerconfig/issuerconfig_test.go

251 lines
7.4 KiB
Go
Raw Permalink Normal View History

// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package issuerconfig
import (
"math/rand"
"sort"
"testing"
"testing/quick"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
)
func TestMergeStrategy(t *testing.T) {
t1 := metav1.Now()
t2 := metav1.NewTime(metav1.Now().Add(-1 * time.Hour))
tests := []struct {
name string
configToUpdate v1alpha1.CredentialIssuerStatus
strategy v1alpha1.CredentialIssuerStrategy
expected v1alpha1.CredentialIssuerStatus
}{
{
name: "new entry",
configToUpdate: v1alpha1.CredentialIssuerStatus{
Strategies: nil,
},
strategy: v1alpha1.CredentialIssuerStrategy{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
},
expected: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
},
},
},
},
{
name: "new entry updating deprecated kubeConfigInfo",
configToUpdate: v1alpha1.CredentialIssuerStatus{
Strategies: nil,
},
strategy: v1alpha1.CredentialIssuerStrategy{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
Frontend: &v1alpha1.CredentialIssuerFrontend{
Type: "TokenCredentialRequestAPI",
TokenCredentialRequestAPIInfo: &v1alpha1.TokenCredentialRequestAPIInfo{
Server: "https://test-server",
CertificateAuthorityData: "test-ca-bundle",
},
},
},
expected: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
Frontend: &v1alpha1.CredentialIssuerFrontend{
Type: "TokenCredentialRequestAPI",
TokenCredentialRequestAPIInfo: &v1alpha1.TokenCredentialRequestAPIInfo{
Server: "https://test-server",
CertificateAuthorityData: "test-ca-bundle",
},
},
},
},
KubeConfigInfo: &v1alpha1.CredentialIssuerKubeConfigInfo{
Server: "https://test-server",
CertificateAuthorityData: "test-ca-bundle",
},
},
},
{
name: "existing entry to update",
configToUpdate: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
{
Type: "Type1",
Status: v1alpha1.ErrorStrategyStatus,
Reason: "some starting reason",
Message: "some starting message",
LastUpdateTime: t2,
},
},
},
strategy: v1alpha1.CredentialIssuerStrategy{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
},
expected: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
},
},
},
},
{
name: "existing entry matches except for LastUpdated time",
configToUpdate: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
{
Type: "Type1",
Status: v1alpha1.ErrorStrategyStatus,
Reason: "some starting reason",
Message: "some starting message",
LastUpdateTime: t1,
},
},
},
strategy: v1alpha1.CredentialIssuerStrategy{
Type: "Type1",
Status: v1alpha1.ErrorStrategyStatus,
Reason: "some starting reason",
Message: "some starting message",
LastUpdateTime: t2,
},
expected: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
{
Type: "Type1",
Status: v1alpha1.ErrorStrategyStatus,
Reason: "some starting reason",
Message: "some starting message",
LastUpdateTime: t1,
},
},
},
},
{
name: "new entry among others",
configToUpdate: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
{
Type: "Type0",
Status: v1alpha1.ErrorStrategyStatus,
Reason: "some starting reason 0",
Message: "some starting message 0",
LastUpdateTime: t2,
},
{
Type: "Type2",
Status: v1alpha1.ErrorStrategyStatus,
Reason: "some starting reason 0",
Message: "some starting message 0",
LastUpdateTime: t2,
},
},
},
strategy: v1alpha1.CredentialIssuerStrategy{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
},
expected: v1alpha1.CredentialIssuerStatus{
Strategies: []v1alpha1.CredentialIssuerStrategy{
{
Type: "Type0",
Status: v1alpha1.ErrorStrategyStatus,
Reason: "some starting reason 0",
Message: "some starting message 0",
LastUpdateTime: t2,
},
// Expect the Type1 entry to be sorted alphanumerically between the existing entries.
{
Type: "Type1",
Status: v1alpha1.SuccessStrategyStatus,
Reason: "some reason",
Message: "some message",
LastUpdateTime: t1,
},
{
Type: "Type2",
Status: v1alpha1.ErrorStrategyStatus,
Reason: "some starting reason 0",
Message: "some starting message 0",
LastUpdateTime: t2,
},
},
},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
updated := tt.configToUpdate.DeepCopy()
mergeStrategy(updated, tt.strategy)
require.Equal(t, &tt.expected, updated)
})
}
}
func TestStrategySorting(t *testing.T) {
expected := []v1alpha1.CredentialIssuerStrategy{
{Type: v1alpha1.KubeClusterSigningCertificateStrategyType},
{Type: v1alpha1.ImpersonationProxyStrategyType},
{Type: "Type1"},
{Type: "Type2"},
{Type: "Type3"},
}
require.NoError(t, quick.Check(func(seed int64) bool {
// Create a randomly shuffled copy of the expected output.
//nolint:gosec // this is not meant to be a secure random, just a seeded RNG for shuffling deterministically
rng := rand.New(rand.NewSource(seed))
output := make([]v1alpha1.CredentialIssuerStrategy, len(expected))
copy(output, expected)
rng.Shuffle(
len(output),
func(i, j int) { output[i], output[j] = output[j], output[i] },
)
// Sort it using the code under test.
sort.Stable(sortableStrategies(output))
// Assert that it's sorted back to the expected output order.
return assert.Equal(t, expected, output)
}, nil))
}