Skip to content

Commit d64c467

Browse files
committed
Add unit tests for PodEnvironmentConfigMap and PodEnvironmentSecret - highly inspired by @kupson and his very similar PR #481
1 parent 66ac2f5 commit d64c467

File tree

1 file changed

+208
-0
lines changed

1 file changed

+208
-0
lines changed

pkg/cluster/k8sres_test.go

+208
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cluster
22

33
import (
4+
"context"
45
"errors"
56
"fmt"
67
"reflect"
@@ -10,6 +11,7 @@ import (
1011
"github.com/stretchr/testify/assert"
1112

1213
acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
14+
"github.com/zalando/postgres-operator/pkg/spec"
1315
"github.com/zalando/postgres-operator/pkg/util"
1416
"github.com/zalando/postgres-operator/pkg/util/config"
1517
"github.com/zalando/postgres-operator/pkg/util/constants"
@@ -22,6 +24,7 @@ import (
2224
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2325
"k8s.io/apimachinery/pkg/types"
2426
"k8s.io/apimachinery/pkg/util/intstr"
27+
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
2528
)
2629

2730
// For testing purposes
@@ -713,6 +716,211 @@ func TestSecretVolume(t *testing.T) {
713716
}
714717
}
715718

719+
const (
720+
testPodEnvironmentConfigMapName = "pod_env_cm"
721+
testPodEnvironmentSecretName = "pod_env_sc"
722+
)
723+
724+
type mockSecret struct {
725+
v1core.SecretInterface
726+
}
727+
728+
type mockConfigMap struct {
729+
v1core.ConfigMapInterface
730+
}
731+
732+
func (c *mockSecret) Get(ctx context.Context, name string, options metav1.GetOptions) (*v1.Secret, error) {
733+
if name != testPodEnvironmentSecretName {
734+
return nil, fmt.Errorf("Secret PodEnvironmentSecret not found")
735+
}
736+
secret := &v1.Secret{}
737+
secret.Name = testPodEnvironmentSecretName
738+
secret.Data = map[string][]byte{
739+
"minio_access_key": []byte("alpha"),
740+
"minio_secret_key": []byte("beta"),
741+
}
742+
return secret, nil
743+
}
744+
745+
func (c *mockConfigMap) Get(ctx context.Context, name string, options metav1.GetOptions) (*v1.ConfigMap, error) {
746+
if name != testPodEnvironmentConfigMapName {
747+
return nil, fmt.Errorf("NotFound")
748+
}
749+
configmap := &v1.ConfigMap{}
750+
configmap.Name = testPodEnvironmentConfigMapName
751+
configmap.Data = map[string]string{
752+
"foo": "bar",
753+
}
754+
return configmap, nil
755+
}
756+
757+
type MockSecretGetter struct {
758+
}
759+
760+
type MockConfigMapsGetter struct {
761+
}
762+
763+
func (c *MockSecretGetter) Secrets(namespace string) v1core.SecretInterface {
764+
return &mockSecret{}
765+
}
766+
767+
func (c *MockConfigMapsGetter) ConfigMaps(namespace string) v1core.ConfigMapInterface {
768+
return &mockConfigMap{}
769+
}
770+
771+
func newMockKubernetesClient() k8sutil.KubernetesClient {
772+
return k8sutil.KubernetesClient{
773+
SecretsGetter: &MockSecretGetter{},
774+
ConfigMapsGetter: &MockConfigMapsGetter{},
775+
}
776+
}
777+
func newMockCluster(opConfig config.Config) *Cluster {
778+
cluster := &Cluster{
779+
Config: Config{OpConfig: opConfig},
780+
KubeClient: newMockKubernetesClient(),
781+
}
782+
return cluster
783+
}
784+
785+
func TestPodEnvironmentConfigMapVariables(t *testing.T) {
786+
testName := "TestPodEnvironmentConfigMapVariables"
787+
tests := []struct {
788+
subTest string
789+
opConfig config.Config
790+
envVars []v1.EnvVar
791+
err error
792+
}{
793+
{
794+
subTest: "no PodEnvironmentConfigMap",
795+
envVars: []v1.EnvVar{},
796+
},
797+
{
798+
subTest: "missing PodEnvironmentConfigMap",
799+
opConfig: config.Config{
800+
Resources: config.Resources{
801+
PodEnvironmentConfigMap: spec.NamespacedName{
802+
Name: "idonotexist",
803+
},
804+
},
805+
},
806+
err: fmt.Errorf("could not read PodEnvironmentConfigMap: NotFound"),
807+
},
808+
{
809+
subTest: "simple PodEnvironmentConfigMap",
810+
opConfig: config.Config{
811+
Resources: config.Resources{
812+
PodEnvironmentConfigMap: spec.NamespacedName{
813+
Name: testPodEnvironmentConfigMapName,
814+
},
815+
},
816+
},
817+
envVars: []v1.EnvVar{
818+
{
819+
Name: "foo",
820+
Value: "bar",
821+
},
822+
},
823+
},
824+
}
825+
for _, tt := range tests {
826+
c := newMockCluster(tt.opConfig)
827+
vars, err := c.getPodEnvironmentConfigMapVariables()
828+
if !reflect.DeepEqual(vars, tt.envVars) {
829+
t.Errorf("%s %s: expected `%v` but got `%v`",
830+
testName, tt.subTest, tt.envVars, vars)
831+
}
832+
if tt.err != nil {
833+
if err.Error() != tt.err.Error() {
834+
t.Errorf("%s %s: expected error `%v` but got `%v`",
835+
testName, tt.subTest, tt.err, err)
836+
}
837+
} else {
838+
if err != nil {
839+
t.Errorf("%s %s: expected no error but got error: `%v`",
840+
testName, tt.subTest, err)
841+
}
842+
}
843+
}
844+
}
845+
846+
// Test if the keys of an existing secret are properly referenced
847+
func TestPodEnvironmentSecretVariables(t *testing.T) {
848+
testName := "TestPodEnvironmentSecretVariables"
849+
tests := []struct {
850+
subTest string
851+
opConfig config.Config
852+
envVars []v1.EnvVar
853+
err error
854+
}{
855+
{
856+
subTest: "No PodEnvironmentSecret configured",
857+
envVars: []v1.EnvVar{},
858+
},
859+
{
860+
subTest: "Secret referenced by PodEnvironmentSecret does not exist",
861+
opConfig: config.Config{
862+
Resources: config.Resources{
863+
PodEnvironmentSecret: "idonotexist",
864+
},
865+
},
866+
err: fmt.Errorf("could not read Secret PodEnvironmentSecretName: Secret PodEnvironmentSecret not found"),
867+
},
868+
{
869+
subTest: "Pod environment vars reference all keys from secret configured by PodEnvironmentSecret",
870+
opConfig: config.Config{
871+
Resources: config.Resources{
872+
PodEnvironmentSecret: testPodEnvironmentSecretName,
873+
},
874+
},
875+
envVars: []v1.EnvVar{
876+
{
877+
Name: "minio_access_key",
878+
ValueFrom: &v1.EnvVarSource{
879+
SecretKeyRef: &v1.SecretKeySelector{
880+
LocalObjectReference: v1.LocalObjectReference{
881+
Name: testPodEnvironmentSecretName,
882+
},
883+
Key: "minio_access_key",
884+
},
885+
},
886+
},
887+
{
888+
Name: "minio_secret_key",
889+
ValueFrom: &v1.EnvVarSource{
890+
SecretKeyRef: &v1.SecretKeySelector{
891+
LocalObjectReference: v1.LocalObjectReference{
892+
Name: testPodEnvironmentSecretName,
893+
},
894+
Key: "minio_secret_key",
895+
},
896+
},
897+
},
898+
},
899+
},
900+
}
901+
902+
for _, tt := range tests {
903+
c := newMockCluster(tt.opConfig)
904+
vars, err := c.getPodEnvironmentSecretVariables()
905+
if !reflect.DeepEqual(vars, tt.envVars) {
906+
t.Errorf("%s %s: expected `%v` but got `%v`",
907+
testName, tt.subTest, tt.envVars, vars)
908+
}
909+
if tt.err != nil {
910+
if err.Error() != tt.err.Error() {
911+
t.Errorf("%s %s: expected error `%v` but got `%v`",
912+
testName, tt.subTest, tt.err, err)
913+
}
914+
} else {
915+
if err != nil {
916+
t.Errorf("%s %s: expected no error but got error: `%v`",
917+
testName, tt.subTest, err)
918+
}
919+
}
920+
}
921+
922+
}
923+
716924
func testResources(cluster *Cluster, podSpec *v1.PodTemplateSpec) error {
717925
cpuReq := podSpec.Spec.Containers[0].Resources.Requests["cpu"]
718926
if cpuReq.String() != cluster.OpConfig.ConnectionPooler.ConnectionPoolerDefaultCPURequest {

0 commit comments

Comments
 (0)