operator/pkg: unit test cert tasks
Signed-off-by: Mohamed Awnallah <mohamedmohey2352@gmail.com>
This commit is contained in:
parent
517cb0d3a9
commit
33b75f7b08
|
@ -127,7 +127,7 @@ func runCertTask(cc, caCert *certs.CertConfig) func(d workflow.RunData) error {
|
|||
}
|
||||
|
||||
if cc.CAName != caCert.Name {
|
||||
return fmt.Errorf("expected CAname for %s, but was %s", cc.CAName, cc.Name)
|
||||
return fmt.Errorf("mismatched CA name: expected %s but got %s", cc.CAName, caCert.Name)
|
||||
}
|
||||
|
||||
if err := mutateCertConfig(data, cc); err != nil {
|
||||
|
|
|
@ -0,0 +1,427 @@
|
|||
/*
|
||||
Copyright 2024 The Karmada Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
fakeclientset "k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"github.com/karmada-io/karmada/operator/pkg/apis/operator/v1alpha1"
|
||||
"github.com/karmada-io/karmada/operator/pkg/certs"
|
||||
"github.com/karmada-io/karmada/operator/pkg/constants"
|
||||
"github.com/karmada-io/karmada/operator/pkg/util"
|
||||
"github.com/karmada-io/karmada/operator/pkg/workflow"
|
||||
)
|
||||
|
||||
func TestNewCertTask(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
wantTask workflow.Task
|
||||
}{
|
||||
{
|
||||
name: "TestNewCertTask_IsCalled_ExpectedWorkflowTask",
|
||||
wantTask: workflow.Task{
|
||||
Name: "Certs",
|
||||
Run: runCerts,
|
||||
Skip: skipCerts,
|
||||
RunSubTasks: true,
|
||||
Tasks: newCertSubTasks(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
certTask := NewCertTask()
|
||||
err := util.DeepEqualTasks(certTask, test.wantTask)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error, got %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunCerts(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
runData workflow.RunData
|
||||
wantErr bool
|
||||
errMsg string
|
||||
}{
|
||||
{
|
||||
name: "RunCerts_InvalidTypeAssertion_TypeAssertionFailed",
|
||||
runData: MyTestData{Data: "test"},
|
||||
wantErr: true,
|
||||
errMsg: "certs task invoked with an invalid data struct",
|
||||
},
|
||||
{
|
||||
name: "RunCerts_ValidTypeAssertion_TypeAssertionSuceeded",
|
||||
runData: &TestInitData{},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
err := runCerts(test.runData)
|
||||
if err == nil && test.wantErr {
|
||||
t.Errorf("expected error, but got none")
|
||||
}
|
||||
if err != nil && !test.wantErr {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if err != nil && test.wantErr && !strings.Contains(err.Error(), test.errMsg) {
|
||||
t.Errorf("expected %s error msg to contain %s", err.Error(), test.errMsg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSkipCerts(t *testing.T) {
|
||||
client := fakeclientset.NewSimpleClientset()
|
||||
tests := []struct {
|
||||
name string
|
||||
runData workflow.RunData
|
||||
prep func() error
|
||||
cleanup func() error
|
||||
wantErr bool
|
||||
wantSkip bool
|
||||
errMsg string
|
||||
}{
|
||||
{
|
||||
name: "SkipCerts_InvalidTypeAssertion_TypeAssertionFailed",
|
||||
runData: MyTestData{Data: "test"},
|
||||
prep: func() error { return nil },
|
||||
cleanup: func() error { return nil },
|
||||
wantErr: true,
|
||||
wantSkip: false,
|
||||
errMsg: "certs task invoked with an invalid data struct",
|
||||
},
|
||||
{
|
||||
name: "SkipCerts_ValidTypeAssertion_TypeAssertionSuceeded",
|
||||
runData: &TestInitData{
|
||||
Name: "karmada-demo",
|
||||
Namespace: "test",
|
||||
RemoteClientConnector: client,
|
||||
},
|
||||
prep: func() error { return nil },
|
||||
cleanup: func() error { return nil },
|
||||
wantErr: false,
|
||||
wantSkip: false,
|
||||
},
|
||||
{
|
||||
name: "SkipCerts_WithEmptySecretData_ErrorReturned",
|
||||
runData: &TestInitData{
|
||||
Name: "karmada-demo",
|
||||
Namespace: "test",
|
||||
RemoteClientConnector: client,
|
||||
},
|
||||
prep: func() error {
|
||||
_, err := client.CoreV1().Secrets("test").Create(
|
||||
context.TODO(), &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: util.KarmadaCertSecretName("karmada-demo"),
|
||||
Namespace: "test",
|
||||
},
|
||||
Data: map[string][]byte{},
|
||||
},
|
||||
metav1.CreateOptions{},
|
||||
)
|
||||
return err
|
||||
},
|
||||
cleanup: func() error {
|
||||
err := client.CoreV1().Secrets("test").Delete(
|
||||
context.TODO(), util.KarmadaCertSecretName("karmada-demo"),
|
||||
metav1.DeleteOptions{},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete %s secret", "test")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
wantErr: true,
|
||||
wantSkip: false,
|
||||
},
|
||||
{
|
||||
name: "SkipCerts_SecertCertDataExist_CertsSkipped",
|
||||
runData: &TestInitData{
|
||||
Name: "karmada-demo",
|
||||
Namespace: "test",
|
||||
RemoteClientConnector: client,
|
||||
},
|
||||
prep: func() error {
|
||||
var err error
|
||||
_, err = client.CoreV1().Secrets("test").Create(
|
||||
context.TODO(), &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: util.KarmadaCertSecretName("karmada-demo"),
|
||||
Namespace: "test",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"ca.crt": []byte("ca-crt-data"),
|
||||
"ca.key": []byte("ca-key-data"),
|
||||
},
|
||||
},
|
||||
metav1.CreateOptions{},
|
||||
)
|
||||
return err
|
||||
},
|
||||
cleanup: func() error {
|
||||
err := client.CoreV1().Secrets("test").Delete(
|
||||
context.TODO(), util.KarmadaCertSecretName("karmada-demo"),
|
||||
metav1.DeleteOptions{},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete %s secret", "test")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
wantErr: false,
|
||||
wantSkip: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
err := test.prep()
|
||||
if err != nil {
|
||||
t.Errorf("failed to prep test: %v", err)
|
||||
}
|
||||
|
||||
skip, err := skipCerts(test.runData)
|
||||
if err == nil && test.wantErr {
|
||||
t.Errorf("expected error, but got none")
|
||||
}
|
||||
if err != nil && !test.wantErr {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if err != nil && test.wantErr && !strings.Contains(err.Error(), test.errMsg) {
|
||||
t.Errorf("expected %s error msg to contain %s", err.Error(), test.errMsg)
|
||||
}
|
||||
if skip != test.wantSkip {
|
||||
t.Errorf("expected %t skip, but got %t", test.wantSkip, skip)
|
||||
}
|
||||
err = test.cleanup()
|
||||
if err != nil {
|
||||
t.Errorf("failed to clean up test: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunCATask(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
kc *certs.CertConfig
|
||||
runData workflow.RunData
|
||||
prep func(*certs.CertConfig) error
|
||||
verify func(workflow.RunData) error
|
||||
wantErr bool
|
||||
errMsg string
|
||||
}{
|
||||
{
|
||||
name: "RunCATask_InvalidTypeAssertion_TypeAssertionFailed",
|
||||
kc: certs.KarmadaCertRootCA(),
|
||||
runData: MyTestData{Data: "test"},
|
||||
prep: func(*certs.CertConfig) error { return nil },
|
||||
verify: func(workflow.RunData) error { return nil },
|
||||
wantErr: true,
|
||||
errMsg: "certs task invoked with an invalid data struct",
|
||||
},
|
||||
{
|
||||
name: "RunCATask_WithNonCACertificate_CACertificateExpected",
|
||||
kc: certs.KarmadaCertAdmin(),
|
||||
runData: &TestInitData{
|
||||
Name: "karmada-demo",
|
||||
Namespace: "test",
|
||||
},
|
||||
prep: func(*certs.CertConfig) error { return nil },
|
||||
verify: func(workflow.RunData) error { return nil },
|
||||
wantErr: true,
|
||||
errMsg: fmt.Sprintf("this function should only be used for CAs, but cert %s has CA %s", constants.KarmadaCertAndKeyName, constants.CaCertAndKeyName),
|
||||
},
|
||||
{
|
||||
name: "RunCATask_WithEd25519UnsupportedPublicKeyAlgorithm_UnsupportedKeyType",
|
||||
kc: certs.KarmadaCertRootCA(),
|
||||
runData: &TestInitData{
|
||||
Name: "karmada-demo",
|
||||
Namespace: "test",
|
||||
},
|
||||
prep: func(cc *certs.CertConfig) error {
|
||||
cc.PublicKeyAlgorithm = x509.Ed25519
|
||||
return nil
|
||||
},
|
||||
verify: func(workflow.RunData) error { return nil },
|
||||
wantErr: true,
|
||||
errMsg: fmt.Sprintf("unsupported key type: %T", x509.Ed25519),
|
||||
},
|
||||
{
|
||||
name: "RunCATask_GenerateCACertificate_CACertificateSuccessfullyGenerated",
|
||||
kc: certs.KarmadaCertRootCA(),
|
||||
runData: &TestInitData{
|
||||
Name: "karmada-demo",
|
||||
Namespace: "test",
|
||||
},
|
||||
prep: func(*certs.CertConfig) error { return nil },
|
||||
verify: func(rd workflow.RunData) error {
|
||||
certData := rd.(*TestInitData).CertList()
|
||||
if len(certData) != 1 {
|
||||
return fmt.Errorf("expected cert store to contain the generated CA certificate but found %d certs", len(certData))
|
||||
}
|
||||
return nil
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if err := test.prep(test.kc); err != nil {
|
||||
t.Errorf("failed to prep cert config data: %v", err)
|
||||
}
|
||||
caTask := runCATask(test.kc)
|
||||
err := caTask(test.runData)
|
||||
if err == nil && test.wantErr {
|
||||
t.Errorf("expected error, but got none")
|
||||
}
|
||||
if err != nil && !test.wantErr {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if err != nil && test.wantErr && !strings.Contains(err.Error(), test.errMsg) {
|
||||
t.Errorf("expected %s error msg to contain %s", err.Error(), test.errMsg)
|
||||
}
|
||||
if err := test.verify(test.runData); err != nil {
|
||||
t.Errorf("failed to verify run data: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunCertTask(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
kc *certs.CertConfig
|
||||
caCert *certs.CertConfig
|
||||
runData workflow.RunData
|
||||
prep func(*certs.CertConfig, *certs.CertConfig, workflow.RunData) error
|
||||
verify func(workflow.RunData) error
|
||||
wantErr bool
|
||||
errMsg string
|
||||
}{
|
||||
{
|
||||
name: "RunCertTask_InvalidTypeAssertion_TypeAssertionFailed",
|
||||
kc: certs.KarmadaCertAdmin(),
|
||||
runData: MyTestData{Data: "test"},
|
||||
prep: func(*certs.CertConfig, *certs.CertConfig, workflow.RunData) error { return nil },
|
||||
verify: func(workflow.RunData) error { return nil },
|
||||
caCert: nil,
|
||||
wantErr: true,
|
||||
errMsg: "certs task invoked with an invalid data struct",
|
||||
},
|
||||
{
|
||||
name: "RunCertTask_NilCACert_CACertIsNil",
|
||||
kc: certs.KarmadaCertAdmin(),
|
||||
runData: &TestInitData{
|
||||
Name: "karmada-demo",
|
||||
Namespace: "test",
|
||||
},
|
||||
prep: func(*certs.CertConfig, *certs.CertConfig, workflow.RunData) error { return nil },
|
||||
verify: func(workflow.RunData) error { return nil },
|
||||
caCert: nil,
|
||||
wantErr: true,
|
||||
errMsg: fmt.Sprintf("unexpected empty ca cert for %s", constants.KarmadaCertAndKeyName),
|
||||
},
|
||||
{
|
||||
name: "RunCertTask_MismatchCAName_CANameIsMismatch",
|
||||
kc: certs.KarmadaCertAdmin(),
|
||||
runData: &TestInitData{
|
||||
Name: "karmada-demo",
|
||||
Namespace: "test",
|
||||
},
|
||||
prep: func(*certs.CertConfig, *certs.CertConfig, workflow.RunData) error { return nil },
|
||||
verify: func(workflow.RunData) error { return nil },
|
||||
caCert: &certs.CertConfig{
|
||||
Name: "invalid",
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: fmt.Sprintf("mismatched CA name: expected %s but got %s", constants.CaCertAndKeyName, "invalid"),
|
||||
},
|
||||
{
|
||||
name: "RunCertTask_CreateCertAndKeyFileWithCA_SuccessfullyGeneratedCertificate",
|
||||
kc: certs.KarmadaCertAdmin(),
|
||||
caCert: certs.KarmadaCertRootCA(),
|
||||
runData: &TestInitData{
|
||||
Name: "karmada-demo",
|
||||
Namespace: "test",
|
||||
ComponentsUnits: &v1alpha1.KarmadaComponents{
|
||||
KarmadaAPIServer: &v1alpha1.KarmadaAPIServer{},
|
||||
},
|
||||
},
|
||||
prep: func(ca *certs.CertConfig, _ *certs.CertConfig, rd workflow.RunData) error {
|
||||
newCA, err := certs.NewCertificateAuthority(ca)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create certificate authority: %v", err)
|
||||
}
|
||||
rd.(*TestInitData).AddCert(newCA)
|
||||
return nil
|
||||
},
|
||||
verify: func(rd workflow.RunData) error {
|
||||
certData := rd.(*TestInitData).CertList()
|
||||
if len(certData) != 2 {
|
||||
return fmt.Errorf("expected cert store to contain the Certificate Authority and the associated certificate but found %d certs", len(certData))
|
||||
}
|
||||
if rd.(*TestInitData).GetCert(constants.CaCertAndKeyName) == nil {
|
||||
return fmt.Errorf("expected %s Karmada Root CA to exist in the certificates store", constants.CaCertAndKeyName)
|
||||
}
|
||||
if rd.(*TestInitData).GetCert(constants.KarmadaCertAndKeyName) == nil {
|
||||
return fmt.Errorf("expected %s karmada admin certificate to exist in the certificate store", constants.KarmadaCertAndKeyName)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if err := test.prep(test.caCert, test.kc, test.runData); err != nil {
|
||||
t.Errorf("failed to prep cert config data: %v", err)
|
||||
}
|
||||
certTask := runCertTask(test.kc, test.caCert)
|
||||
err := certTask(test.runData)
|
||||
if err == nil && test.wantErr {
|
||||
t.Errorf("expected error, but got none")
|
||||
}
|
||||
if err != nil && !test.wantErr {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if err != nil && test.wantErr && !strings.Contains(err.Error(), test.errMsg) {
|
||||
t.Errorf("expected %s error msg to contain %s", err.Error(), test.errMsg)
|
||||
}
|
||||
if err := test.verify(test.runData); err != nil {
|
||||
t.Errorf("failed to verify run data: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue