feat: Improve test coverage of important packages

This commit is contained in:
TheiLLeniumStudios
2025-12-28 08:47:57 +01:00
parent fa60c1d853
commit 841f6f3868
8 changed files with 2702 additions and 0 deletions
+197
View File
@@ -0,0 +1,197 @@
package controller
import (
"testing"
"github.com/stakater/Reloader/internal/pkg/config"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/event"
)
func TestCreateEventPredicate_CreateEvent(t *testing.T) {
tests := []struct {
name string
reloadOnCreate bool
syncAfterRestart bool
initialized bool
expectedResult bool
}{
{
name: "reload on create enabled, initialized",
reloadOnCreate: true,
syncAfterRestart: false,
initialized: true,
expectedResult: true,
},
{
name: "reload on create disabled, initialized",
reloadOnCreate: false,
syncAfterRestart: false,
initialized: true,
expectedResult: false,
},
{
name: "not initialized, sync after restart enabled",
reloadOnCreate: true,
syncAfterRestart: true,
initialized: false,
expectedResult: true,
},
{
name: "not initialized, sync after restart disabled",
reloadOnCreate: true,
syncAfterRestart: false,
initialized: false,
expectedResult: false,
},
{
name: "not initialized, sync after restart disabled, reload on create disabled",
reloadOnCreate: false,
syncAfterRestart: false,
initialized: false,
expectedResult: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := &config.Config{
ReloadOnCreate: tt.reloadOnCreate,
SyncAfterRestart: tt.syncAfterRestart,
}
initialized := tt.initialized
pred := createEventPredicate(cfg, &initialized)
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"},
}
e := event.CreateEvent{Object: cm}
result := pred.Create(e)
if result != tt.expectedResult {
t.Errorf("CreateFunc() = %v, want %v", result, tt.expectedResult)
}
})
}
}
func TestCreateEventPredicate_UpdateEvent(t *testing.T) {
cfg := &config.Config{}
initialized := true
pred := createEventPredicate(cfg, &initialized)
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"},
}
e := event.UpdateEvent{ObjectOld: cm, ObjectNew: cm}
result := pred.Update(e)
// Update events should always return true
if !result {
t.Error("UpdateFunc() should always return true")
}
}
func TestCreateEventPredicate_DeleteEvent(t *testing.T) {
tests := []struct {
name string
reloadOnDelete bool
expectedResult bool
}{
{
name: "reload on delete enabled",
reloadOnDelete: true,
expectedResult: true,
},
{
name: "reload on delete disabled",
reloadOnDelete: false,
expectedResult: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := &config.Config{
ReloadOnDelete: tt.reloadOnDelete,
}
initialized := true
pred := createEventPredicate(cfg, &initialized)
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"},
}
e := event.DeleteEvent{Object: cm}
result := pred.Delete(e)
if result != tt.expectedResult {
t.Errorf("DeleteFunc() = %v, want %v", result, tt.expectedResult)
}
})
}
}
func TestCreateEventPredicate_GenericEvent(t *testing.T) {
cfg := &config.Config{}
initialized := true
pred := createEventPredicate(cfg, &initialized)
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"},
}
e := event.GenericEvent{Object: cm}
result := pred.Generic(e)
// Generic events should always return false
if result {
t.Error("GenericFunc() should always return false")
}
}
func TestBuildEventFilter(t *testing.T) {
cfg := &config.Config{
ReloadOnCreate: true,
ReloadOnDelete: true,
}
initialized := true
// Create a simple always-true predicate as the resource predicate
resourcePred := &alwaysTruePredicate{}
filter := BuildEventFilter(resourcePred, cfg, &initialized)
// The filter should be created without error
if filter == nil {
t.Fatal("BuildEventFilter() should return a non-nil predicate")
}
// Test update event passes (since resourcePred returns true and update always returns true)
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"},
}
e := event.UpdateEvent{ObjectOld: cm, ObjectNew: cm}
result := filter.Update(e)
// Since namespace filter is empty (all namespaces allowed), this should pass
if !result {
t.Error("UpdateFunc() should return true when all predicates pass")
}
}
// alwaysTruePredicate is a helper predicate for testing
type alwaysTruePredicate struct{}
func (p *alwaysTruePredicate) Create(_ event.CreateEvent) bool { return true }
func (p *alwaysTruePredicate) Delete(_ event.DeleteEvent) bool { return true }
func (p *alwaysTruePredicate) Update(_ event.UpdateEvent) bool { return true }
func (p *alwaysTruePredicate) Generic(_ event.GenericEvent) bool { return true }
+131
View File
@@ -0,0 +1,131 @@
package controller
import (
"testing"
"github.com/stakater/Reloader/internal/pkg/reload"
"github.com/stakater/Reloader/internal/pkg/workload"
appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestUpdateWorkloadWithRetry_SwitchCases(t *testing.T) {
// Test that the switch statement correctly identifies workload types
// Note: Full integration tests require a fake k8s client, so we just test type detection
tests := []struct {
name string
workload workload.WorkloadAccessor
expectedKind workload.Kind
}{
{
name: "deployment workload",
workload: workload.NewDeploymentWorkload(&appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"},
}),
expectedKind: workload.KindDeployment,
},
{
name: "daemonset workload",
workload: workload.NewDaemonSetWorkload(&appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"},
}),
expectedKind: workload.KindDaemonSet,
},
{
name: "statefulset workload",
workload: workload.NewStatefulSetWorkload(&appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"},
}),
expectedKind: workload.KindStatefulSet,
},
{
name: "job workload",
workload: workload.NewJobWorkload(&batchv1.Job{
ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"},
}),
expectedKind: workload.KindJob,
},
{
name: "cronjob workload",
workload: workload.NewCronJobWorkload(&batchv1.CronJob{
ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"},
}),
expectedKind: workload.KindCronJob,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Verify the workload kind is correctly identified
if tt.workload.Kind() != tt.expectedKind {
t.Errorf("workload.Kind() = %v, want %v", tt.workload.Kind(), tt.expectedKind)
}
})
}
}
func TestJobWorkloadTypeCast(t *testing.T) {
// Test that JobWorkload type cast works correctly
job := &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{Name: "test-job", Namespace: "default"},
}
jobWl := workload.NewJobWorkload(job)
if jobWl.GetName() != "test-job" {
t.Errorf("JobWorkload.GetName() = %v, want test-job", jobWl.GetName())
}
// Test GetJob method
gotJob := jobWl.GetJob()
if gotJob.Name != "test-job" {
t.Errorf("JobWorkload.GetJob().Name = %v, want test-job", gotJob.Name)
}
// Verify it satisfies WorkloadAccessor interface
var _ workload.WorkloadAccessor = jobWl
}
func TestCronJobWorkloadTypeCast(t *testing.T) {
// Test that CronJobWorkload type cast works correctly
cronJob := &batchv1.CronJob{
ObjectMeta: metav1.ObjectMeta{Name: "test-cronjob", Namespace: "default"},
Spec: batchv1.CronJobSpec{
Schedule: "*/5 * * * *",
},
}
cronJobWl := workload.NewCronJobWorkload(cronJob)
if cronJobWl.GetName() != "test-cronjob" {
t.Errorf("CronJobWorkload.GetName() = %v, want test-cronjob", cronJobWl.GetName())
}
// Test GetCronJob method
gotCronJob := cronJobWl.GetCronJob()
if gotCronJob.Name != "test-cronjob" {
t.Errorf("CronJobWorkload.GetCronJob().Name = %v, want test-cronjob", gotCronJob.Name)
}
// Verify it satisfies WorkloadAccessor interface
var _ workload.WorkloadAccessor = cronJobWl
}
func TestResourceTypeKind(t *testing.T) {
// Test that ResourceType.Kind() returns correct values
tests := []struct {
resourceType reload.ResourceType
expectedKind string
}{
{reload.ResourceTypeConfigMap, "ConfigMap"},
{reload.ResourceTypeSecret, "Secret"},
}
for _, tt := range tests {
t.Run(string(tt.resourceType), func(t *testing.T) {
if got := tt.resourceType.Kind(); got != tt.expectedKind {
t.Errorf("ResourceType.Kind() = %v, want %v", got, tt.expectedKind)
}
})
}
}