mirror of
https://github.com/stakater/Reloader.git
synced 2026-05-17 22:26:54 +00:00
feat: Initial e2e tests and migrate old ones into e2e
This commit is contained in:
358
internal/pkg/handler/create_test.go
Normal file
358
internal/pkg/handler/create_test.go
Normal file
@@ -0,0 +1,358 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stakater/Reloader/internal/pkg/constants"
|
||||
"github.com/stakater/Reloader/internal/pkg/metrics"
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestResourceCreatedHandler_GetConfig(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
resource interface{}
|
||||
expectedName string
|
||||
expectedNS string
|
||||
expectedType string
|
||||
expectSHANotEmpty bool
|
||||
expectOldSHAEmpty bool
|
||||
}{
|
||||
{
|
||||
name: "ConfigMap with data",
|
||||
resource: &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-configmap",
|
||||
Namespace: "test-ns",
|
||||
},
|
||||
Data: map[string]string{
|
||||
"key1": "value1",
|
||||
"key2": "value2",
|
||||
},
|
||||
},
|
||||
expectedName: "my-configmap",
|
||||
expectedNS: "test-ns",
|
||||
expectedType: constants.ConfigmapEnvVarPostfix,
|
||||
expectSHANotEmpty: true,
|
||||
expectOldSHAEmpty: true,
|
||||
},
|
||||
{
|
||||
name: "ConfigMap with empty data",
|
||||
resource: &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "empty-configmap",
|
||||
Namespace: "default",
|
||||
},
|
||||
Data: map[string]string{},
|
||||
},
|
||||
expectedName: "empty-configmap",
|
||||
expectedNS: "default",
|
||||
expectedType: constants.ConfigmapEnvVarPostfix,
|
||||
expectSHANotEmpty: true,
|
||||
expectOldSHAEmpty: true,
|
||||
},
|
||||
{
|
||||
name: "ConfigMap with binary data",
|
||||
resource: &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "binary-configmap",
|
||||
Namespace: "default",
|
||||
},
|
||||
BinaryData: map[string][]byte{
|
||||
"binary-key": []byte("binary-value"),
|
||||
},
|
||||
},
|
||||
expectedName: "binary-configmap",
|
||||
expectedNS: "default",
|
||||
expectedType: constants.ConfigmapEnvVarPostfix,
|
||||
expectSHANotEmpty: true,
|
||||
expectOldSHAEmpty: true,
|
||||
},
|
||||
{
|
||||
name: "ConfigMap with annotations",
|
||||
resource: &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "annotated-configmap",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
"reloader.stakater.com/match": "true",
|
||||
},
|
||||
},
|
||||
Data: map[string]string{"key": "value"},
|
||||
},
|
||||
expectedName: "annotated-configmap",
|
||||
expectedNS: "default",
|
||||
expectedType: constants.ConfigmapEnvVarPostfix,
|
||||
expectSHANotEmpty: true,
|
||||
expectOldSHAEmpty: true,
|
||||
},
|
||||
{
|
||||
name: "Secret with data",
|
||||
resource: &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-secret",
|
||||
Namespace: "secret-ns",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"password": []byte("secret-password"),
|
||||
},
|
||||
},
|
||||
expectedName: "my-secret",
|
||||
expectedNS: "secret-ns",
|
||||
expectedType: constants.SecretEnvVarPostfix,
|
||||
expectSHANotEmpty: true,
|
||||
expectOldSHAEmpty: true,
|
||||
},
|
||||
{
|
||||
name: "Secret with empty data",
|
||||
resource: &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "empty-secret",
|
||||
Namespace: "default",
|
||||
},
|
||||
Data: map[string][]byte{},
|
||||
},
|
||||
expectedName: "empty-secret",
|
||||
expectedNS: "default",
|
||||
expectedType: constants.SecretEnvVarPostfix,
|
||||
expectSHANotEmpty: true,
|
||||
expectOldSHAEmpty: true,
|
||||
},
|
||||
{
|
||||
name: "Secret with StringData",
|
||||
resource: &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "stringdata-secret",
|
||||
Namespace: "default",
|
||||
},
|
||||
StringData: map[string]string{
|
||||
"username": "admin",
|
||||
},
|
||||
},
|
||||
expectedName: "stringdata-secret",
|
||||
expectedNS: "default",
|
||||
expectedType: constants.SecretEnvVarPostfix,
|
||||
expectSHANotEmpty: true,
|
||||
expectOldSHAEmpty: true,
|
||||
},
|
||||
{
|
||||
name: "Secret with labels",
|
||||
resource: &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "labeled-secret",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{
|
||||
"app": "test",
|
||||
},
|
||||
},
|
||||
Data: map[string][]byte{"key": []byte("value")},
|
||||
},
|
||||
expectedName: "labeled-secret",
|
||||
expectedNS: "default",
|
||||
expectedType: constants.SecretEnvVarPostfix,
|
||||
expectSHANotEmpty: true,
|
||||
expectOldSHAEmpty: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid resource type - string",
|
||||
resource: "invalid-string",
|
||||
expectedName: "",
|
||||
expectedNS: "",
|
||||
expectedType: "",
|
||||
expectSHANotEmpty: false,
|
||||
expectOldSHAEmpty: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid resource type - int",
|
||||
resource: 123,
|
||||
expectedName: "",
|
||||
expectedNS: "",
|
||||
expectedType: "",
|
||||
expectSHANotEmpty: false,
|
||||
expectOldSHAEmpty: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid resource type - struct",
|
||||
resource: struct{ Name string }{Name: "test"},
|
||||
expectedName: "",
|
||||
expectedNS: "",
|
||||
expectedType: "",
|
||||
expectSHANotEmpty: false,
|
||||
expectOldSHAEmpty: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
handler := ResourceCreatedHandler{
|
||||
Resource: tt.resource,
|
||||
Collectors: metrics.NewCollectors(),
|
||||
}
|
||||
|
||||
config, oldSHA := handler.GetConfig()
|
||||
|
||||
assert.Equal(t, tt.expectedName, config.ResourceName)
|
||||
assert.Equal(t, tt.expectedNS, config.Namespace)
|
||||
assert.Equal(t, tt.expectedType, config.Type)
|
||||
|
||||
if tt.expectSHANotEmpty {
|
||||
assert.NotEmpty(t, config.SHAValue, "SHA should not be empty")
|
||||
}
|
||||
|
||||
if tt.expectOldSHAEmpty {
|
||||
assert.Empty(t, oldSHA, "oldSHA should always be empty for create handler")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourceCreatedHandler_GetConfig_Annotations(t *testing.T) {
|
||||
// Test that annotations are properly captured in config
|
||||
cm := &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "annotated-cm",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
"reloader.stakater.com/match": "true",
|
||||
"reloader.stakater.com/search": "true",
|
||||
},
|
||||
},
|
||||
Data: map[string]string{"key": "value"},
|
||||
}
|
||||
|
||||
handler := ResourceCreatedHandler{
|
||||
Resource: cm,
|
||||
Collectors: metrics.NewCollectors(),
|
||||
}
|
||||
|
||||
config, _ := handler.GetConfig()
|
||||
|
||||
assert.NotNil(t, config.ResourceAnnotations)
|
||||
assert.Equal(t, "true", config.ResourceAnnotations["reloader.stakater.com/match"])
|
||||
assert.Equal(t, "true", config.ResourceAnnotations["reloader.stakater.com/search"])
|
||||
}
|
||||
|
||||
func TestResourceCreatedHandler_GetConfig_Labels(t *testing.T) {
|
||||
// Test that labels are properly captured in config
|
||||
secret := &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "labeled-secret",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{
|
||||
"app": "myapp",
|
||||
"version": "v1",
|
||||
},
|
||||
},
|
||||
Data: map[string][]byte{"key": []byte("value")},
|
||||
}
|
||||
|
||||
handler := ResourceCreatedHandler{
|
||||
Resource: secret,
|
||||
Collectors: metrics.NewCollectors(),
|
||||
}
|
||||
|
||||
config, _ := handler.GetConfig()
|
||||
|
||||
assert.NotNil(t, config.Labels)
|
||||
assert.Equal(t, "myapp", config.Labels["app"])
|
||||
assert.Equal(t, "v1", config.Labels["version"])
|
||||
}
|
||||
|
||||
func TestResourceCreatedHandler_Handle(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
resource interface{}
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "Nil resource",
|
||||
resource: nil,
|
||||
expectError: false, // logs error but returns nil
|
||||
},
|
||||
{
|
||||
name: "Valid ConfigMap - no workloads to update",
|
||||
resource: &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-cm",
|
||||
Namespace: "default",
|
||||
},
|
||||
Data: map[string]string{"key": "value"},
|
||||
},
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "Valid Secret - no workloads to update",
|
||||
resource: &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-secret",
|
||||
Namespace: "default",
|
||||
},
|
||||
Data: map[string][]byte{"key": []byte("value")},
|
||||
},
|
||||
expectError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
handler := ResourceCreatedHandler{
|
||||
Resource: tt.resource,
|
||||
Collectors: metrics.NewCollectors(),
|
||||
}
|
||||
|
||||
err := handler.Handle()
|
||||
|
||||
if tt.expectError {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourceCreatedHandler_SHAConsistency(t *testing.T) {
|
||||
// Test that same data produces same SHA
|
||||
data := map[string]string{"key": "value"}
|
||||
|
||||
cm1 := &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "cm1", Namespace: "default"},
|
||||
Data: data,
|
||||
}
|
||||
cm2 := &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "cm2", Namespace: "default"},
|
||||
Data: data,
|
||||
}
|
||||
|
||||
handler1 := ResourceCreatedHandler{Resource: cm1, Collectors: metrics.NewCollectors()}
|
||||
handler2 := ResourceCreatedHandler{Resource: cm2, Collectors: metrics.NewCollectors()}
|
||||
|
||||
config1, _ := handler1.GetConfig()
|
||||
config2, _ := handler2.GetConfig()
|
||||
|
||||
// Same data should produce same SHA
|
||||
assert.Equal(t, config1.SHAValue, config2.SHAValue)
|
||||
}
|
||||
|
||||
func TestResourceCreatedHandler_SHADifference(t *testing.T) {
|
||||
// Test that different data produces different SHA
|
||||
cm1 := &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "cm", Namespace: "default"},
|
||||
Data: map[string]string{"key": "value1"},
|
||||
}
|
||||
cm2 := &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "cm", Namespace: "default"},
|
||||
Data: map[string]string{"key": "value2"},
|
||||
}
|
||||
|
||||
handler1 := ResourceCreatedHandler{Resource: cm1, Collectors: metrics.NewCollectors()}
|
||||
handler2 := ResourceCreatedHandler{Resource: cm2, Collectors: metrics.NewCollectors()}
|
||||
|
||||
config1, _ := handler1.GetConfig()
|
||||
config2, _ := handler2.GetConfig()
|
||||
|
||||
// Different data should produce different SHA
|
||||
assert.NotEqual(t, config1.SHAValue, config2.SHAValue)
|
||||
}
|
||||
Reference in New Issue
Block a user