Skip to content

Commit

Permalink
Merge pull request #2013 from Nordix/lentzi90/unit-tests
Browse files Browse the repository at this point in the history
🌱  Improve test coverage
  • Loading branch information
metal3-io-bot authored Nov 6, 2024
2 parents 8717842 + 3e70e73 commit 76884f0
Show file tree
Hide file tree
Showing 3 changed files with 306 additions and 1 deletion.
8 changes: 8 additions & 0 deletions controllers/metal3.io/preprovisioningimage_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,20 @@ func (r *PreprovisioningImageReconciler) Reconcile(ctx context.Context, req ctrl
return result, err
}

// configChanged checks if the image configuration has changed since the last update.
// It compares the current format, architecture, and network data status with the
// values stored in the image status.
func configChanged(img *metal3api.PreprovisioningImage, format metal3api.ImageFormat, networkDataStatus metal3api.SecretStatus) bool {
return !(img.Status.Format == format &&
img.Status.Architecture == img.Spec.Architecture &&
img.Status.NetworkData == networkDataStatus)
}

// update updates the PreprovisioningImage resource with the latest image information.
// It checks if the image configuration has changed since the last update, and if so,
// it discards the existing image, sets up the new image data, and triggers a new
// image build. If the image configuration has not changed, it simply updates the
// image status with the latest information.
func (r *PreprovisioningImageReconciler) update(ctx context.Context, img *metal3api.PreprovisioningImage, log logr.Logger) (bool, error) {
generation := img.GetGeneration()

Expand Down
204 changes: 204 additions & 0 deletions controllers/metal3.io/preprovisioningimage_controller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
package controllers

import (
"testing"

"github.com/go-logr/logr"
metal3api "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
"github.com/metal3-io/baremetal-operator/pkg/imageprovider"
"github.com/stretchr/testify/assert"
ctrl "sigs.k8s.io/controller-runtime"
)

type mockImageProvider struct {
supportedFormats map[metal3api.ImageFormat]bool
}

func (m *mockImageProvider) SupportsFormat(format metal3api.ImageFormat) bool {
return m.supportedFormats[format]
}

func (m *mockImageProvider) SupportsArchitecture(arch string) bool {
return true
}

func (m *mockImageProvider) BuildImage(_ imageprovider.ImageData, _ imageprovider.NetworkData, _ logr.Logger) (imageprovider.GeneratedImage, error) {
return imageprovider.GeneratedImage{}, nil
}

func (m *mockImageProvider) DiscardImage(_ imageprovider.ImageData) error {
return nil
}

func TestCanStart(t *testing.T) {
testCases := []struct {
name string
supportedFmts map[metal3api.ImageFormat]bool
expectedResult bool
}{
{
name: "supports iso only",
supportedFmts: map[metal3api.ImageFormat]bool{
metal3api.ImageFormatISO: true,
},
expectedResult: true,
},
{
name: "supports initrd only",
supportedFmts: map[metal3api.ImageFormat]bool{
metal3api.ImageFormatInitRD: true,
},
expectedResult: true,
},
{
name: "supports both formats",
supportedFmts: map[metal3api.ImageFormat]bool{
metal3api.ImageFormatISO: true,
metal3api.ImageFormatInitRD: true,
},
expectedResult: true,
},
{
name: "cannot start with no formats",
supportedFmts: map[metal3api.ImageFormat]bool{},
expectedResult: false,
},
{
name: "cannot start with unknown format",
supportedFmts: map[metal3api.ImageFormat]bool{
"unknown": true,
},
expectedResult: false,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
r := &PreprovisioningImageReconciler{
ImageProvider: &mockImageProvider{supportedFormats: tc.supportedFmts},
Log: ctrl.Log.WithName("test"),
}
assert.Equal(t, tc.expectedResult, r.CanStart())
})
}
}
func TestConfigChanged(t *testing.T) {
testCases := []struct {
name string
img *metal3api.PreprovisioningImage
format metal3api.ImageFormat
networkDataStatus metal3api.SecretStatus
expectedHasChanged bool
}{
{
name: "no changes",
img: &metal3api.PreprovisioningImage{
Status: metal3api.PreprovisioningImageStatus{
Format: metal3api.ImageFormatISO,
Architecture: "x86_64",
NetworkData: metal3api.SecretStatus{
Name: "test-net",
Version: "1",
},
},
Spec: metal3api.PreprovisioningImageSpec{
Architecture: "x86_64",
},
},
format: metal3api.ImageFormatISO,
networkDataStatus: metal3api.SecretStatus{
Name: "test-net",
Version: "1",
},
expectedHasChanged: false,
},
{
name: "format changed",
img: &metal3api.PreprovisioningImage{
Status: metal3api.PreprovisioningImageStatus{
Format: metal3api.ImageFormatISO,
Architecture: "x86_64",
NetworkData: metal3api.SecretStatus{
Name: "test-net",
Version: "1",
},
},
Spec: metal3api.PreprovisioningImageSpec{
Architecture: "x86_64",
},
},
format: metal3api.ImageFormatInitRD,
networkDataStatus: metal3api.SecretStatus{
Name: "test-net",
Version: "1",
},
expectedHasChanged: true,
},
{
name: "architecture changed",
img: &metal3api.PreprovisioningImage{
Status: metal3api.PreprovisioningImageStatus{
Format: metal3api.ImageFormatISO,
Architecture: "x86_64",
NetworkData: metal3api.SecretStatus{
Name: "test-net",
Version: "1",
},
},
Spec: metal3api.PreprovisioningImageSpec{
Architecture: "arm64",
},
},
format: metal3api.ImageFormatISO,
networkDataStatus: metal3api.SecretStatus{
Name: "test-net",
Version: "1",
},
expectedHasChanged: true,
},
{
name: "network data changed",
img: &metal3api.PreprovisioningImage{
Status: metal3api.PreprovisioningImageStatus{
Format: metal3api.ImageFormatISO,
Architecture: "x86_64",
NetworkData: metal3api.SecretStatus{
Name: "test-net",
Version: "1",
},
},
Spec: metal3api.PreprovisioningImageSpec{
Architecture: "x86_64",
},
},
format: metal3api.ImageFormatISO,
networkDataStatus: metal3api.SecretStatus{
Name: "test-net",
Version: "2",
},
expectedHasChanged: true,
},
{
name: "empty status",
img: &metal3api.PreprovisioningImage{
Status: metal3api.PreprovisioningImageStatus{},
Spec: metal3api.PreprovisioningImageSpec{
Architecture: "x86_64",
},
},
format: metal3api.ImageFormatISO,
networkDataStatus: metal3api.SecretStatus{
Name: "test-net",
Version: "1",
},
expectedHasChanged: true,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := configChanged(tc.img, tc.format, tc.networkDataStatus)
assert.Equal(t, tc.expectedHasChanged, result)
})
}
}
95 changes: 94 additions & 1 deletion pkg/provisioner/ironic/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"os"
"testing"

"github.com/metal3-io/baremetal-operator/pkg/provisioner/ironic/clients"
"github.com/stretchr/testify/assert"
)

Expand All @@ -13,6 +14,11 @@ type EnvFixture struct {
ramdiskURL string
isoURL string
liveISOForcePersistentBootDevice string
ironicCACertFile string
ironicClientCertFile string
ironicClientPrivateKeyFile string
ironicInsecure string
ironicSkipClientSANVerify string

origEnv map[string]string
}
Expand Down Expand Up @@ -43,8 +49,12 @@ func (f *EnvFixture) SetUp() {
f.replace("DEPLOY_RAMDISK_URL", f.ramdiskURL)
f.replace("DEPLOY_ISO_URL", f.isoURL)
f.replace("LIVE_ISO_FORCE_PERSISTENT_BOOT_DEVICE", f.liveISOForcePersistentBootDevice)
f.replace("IRONIC_CACERT_FILE", f.ironicCACertFile)
f.replace("IRONIC_CLIENT_CERT_FILE", f.ironicClientCertFile)
f.replace("IRONIC_CLIENT_PRIVATE_KEY_FILE", f.ironicClientPrivateKeyFile)
f.replace("IRONIC_INSECURE", f.ironicInsecure)
f.replace("IRONIC_SKIP_CLIENT_SAN_VERIFY", f.ironicSkipClientSANVerify)
}

func (f EnvFixture) VerifyConfig(t *testing.T, c ironicConfig, _ string) {
t.Helper()
assert.Equal(t, f.kernelURL, c.deployKernelURL)
Expand Down Expand Up @@ -213,3 +223,86 @@ func TestLoadEndpointsFromEnv(t *testing.T) {
})
}
}
func TestLoadTLSConfigFromEnv(t *testing.T) {
cases := []struct {
name string
env EnvFixture
expectedTLSConfig clients.TLSConfig
}{
{
name: "default values",
env: EnvFixture{},
expectedTLSConfig: clients.TLSConfig{
TrustedCAFile: "/opt/metal3/certs/ca/tls.crt",
ClientCertificateFile: "/opt/metal3/certs/client/tls.crt",
ClientPrivateKeyFile: "/opt/metal3/certs/client/tls.key",
InsecureSkipVerify: false,
SkipClientSANVerify: false,
},
},
{
name: "custom file paths",
env: EnvFixture{
ironicCACertFile: "/custom/ca.crt",
ironicClientCertFile: "/custom/client.crt",
ironicClientPrivateKeyFile: "/custom/client.key",
},
expectedTLSConfig: clients.TLSConfig{
TrustedCAFile: "/custom/ca.crt",
ClientCertificateFile: "/custom/client.crt",
ClientPrivateKeyFile: "/custom/client.key",
InsecureSkipVerify: false,
SkipClientSANVerify: false,
},
},
{
name: "insecure true",
env: EnvFixture{
ironicInsecure: "true",
},
expectedTLSConfig: clients.TLSConfig{
TrustedCAFile: "/opt/metal3/certs/ca/tls.crt",
ClientCertificateFile: "/opt/metal3/certs/client/tls.crt",
ClientPrivateKeyFile: "/opt/metal3/certs/client/tls.key",
InsecureSkipVerify: true,
SkipClientSANVerify: false,
},
},
{
name: "skip client SAN verify true",
env: EnvFixture{
ironicSkipClientSANVerify: "true",
},
expectedTLSConfig: clients.TLSConfig{
TrustedCAFile: "/opt/metal3/certs/ca/tls.crt",
ClientCertificateFile: "/opt/metal3/certs/client/tls.crt",
ClientPrivateKeyFile: "/opt/metal3/certs/client/tls.key",
InsecureSkipVerify: false,
SkipClientSANVerify: true,
},
},
{
name: "case insensitive boolean values",
env: EnvFixture{
ironicInsecure: "TRUE",
ironicSkipClientSANVerify: "True",
}, expectedTLSConfig: clients.TLSConfig{
TrustedCAFile: "/opt/metal3/certs/ca/tls.crt",
ClientCertificateFile: "/opt/metal3/certs/client/tls.crt",
ClientPrivateKeyFile: "/opt/metal3/certs/client/tls.key",
InsecureSkipVerify: true,
SkipClientSANVerify: true,
},
},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
defer tc.env.TearDown()
tc.env.SetUp()

result := loadTLSConfigFromEnv()
assert.Equal(t, tc.expectedTLSConfig, result)
})
}
}

0 comments on commit 76884f0

Please sign in to comment.