Skip to content

Commit dfddd5e

Browse files
committed
Add tests for standalone flagd deployment
Signed-off-by: Yosiah de Koeyer <dev@yosiahdekoeyer.dev>
1 parent 40a0c96 commit dfddd5e

1 file changed

Lines changed: 234 additions & 0 deletions

File tree

internal/common/flagdinjector/flagdinjector_test.go

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,145 @@ func TestFlagdContainerInjector_InjectUnknownSyncProvider(t *testing.T) {
711711
require.ErrorIs(t, err, common.ErrUnrecognizedSyncProvider)
712712
}
713713

714+
func TestFlagdContainerInjector_InjectDefaultSyncProvider_Standalone(t *testing.T) {
715+
namespace, fakeClient := initContainerInjectionTestEnv()
716+
717+
fi := &FlagdContainerInjector{
718+
Client: fakeClient,
719+
Logger: testr.New(t),
720+
FlagdProxyConfig: getProxyConfig(),
721+
FlagdResourceRequirements: getResourceRequirements(),
722+
Image: testImage,
723+
Tag: testTag,
724+
}
725+
726+
pod := generatePod(nil, nil, nil, namespace)
727+
728+
flagSourceConfig := getFlagSourceConfigSpec()
729+
730+
flagSourceConfig.DefaultSyncProvider = apicommon.SyncProviderGrpc
731+
732+
flagSourceConfig.Sources = []api.Source{{}}
733+
734+
err := fi.InjectFlagd(context.Background(), &pod.ObjectMeta, &pod.Spec, flagSourceConfig)
735+
require.Nil(t, err)
736+
737+
expectedPod := getExpectedStandalonePod(namespace)
738+
739+
expectedPod.Spec.Containers[0].Args = []string{"start", "--management-port", "8014", "--port", "8013", "--sources", "[{\"uri\":\"\",\"provider\":\"grpc\"}]"}
740+
741+
require.Equal(t, expectedPod, pod)
742+
}
743+
744+
func TestFlagdContainerInjector_InjectFlagdKubernetesSource_Standalone(t *testing.T) {
745+
namespace, fakeClient := initContainerInjectionTestEnv()
746+
747+
fi := &FlagdContainerInjector{
748+
Client: fakeClient,
749+
Logger: testr.New(t),
750+
FlagdProxyConfig: getProxyConfig(),
751+
FlagdResourceRequirements: getResourceRequirements(),
752+
Image: testImage,
753+
Tag: testTag,
754+
}
755+
756+
pod := generatePod(nil, nil, nil, namespace)
757+
758+
flagSourceConfig := getFlagSourceConfigSpec()
759+
760+
flagSourceConfig.Sources = []api.Source{
761+
{
762+
Source: "my-namespace/server-side",
763+
Provider: apicommon.SyncProviderKubernetes,
764+
},
765+
}
766+
767+
err := fi.InjectFlagd(context.Background(), &pod.ObjectMeta, &pod.Spec, flagSourceConfig)
768+
769+
require.Nil(t, err)
770+
771+
expectedPod := getExpectedStandalonePod(namespace)
772+
773+
expectedPod.Annotations = map[string]string{
774+
"openfeature.dev/allowkubernetessync": "true",
775+
}
776+
expectedPod.Spec.Containers[0].Args = []string{"start", "--management-port", "8014", "--port", "8013", "--sources", "[{\"uri\":\"my-namespace/server-side\",\"provider\":\"kubernetes\"}]"}
777+
778+
require.Equal(t, expectedPod, pod)
779+
780+
// verify the update of the ClusterRoleBinding
781+
cbr := &rbacv1.ClusterRoleBinding{}
782+
err = fakeClient.Get(context.Background(), client.ObjectKey{Name: common.ClusterRoleBindingName}, cbr)
783+
784+
require.Nil(t, err)
785+
786+
require.Len(t, cbr.Subjects, 1)
787+
require.Equal(t, rbacv1.Subject{
788+
Kind: "ServiceAccount",
789+
Name: "default",
790+
Namespace: namespace,
791+
}, cbr.Subjects[0])
792+
}
793+
794+
func TestFlagdContainerInjector_InjectFlagdFilePathSource_Standalone(t *testing.T) {
795+
namespace, fakeClient := initContainerInjectionTestEnv()
796+
797+
fi := &FlagdContainerInjector{
798+
Client: fakeClient,
799+
Logger: testr.New(t),
800+
FlagdProxyConfig: getProxyConfig(),
801+
FlagdResourceRequirements: getResourceRequirements(),
802+
Image: testImage,
803+
Tag: testTag,
804+
}
805+
806+
pod := generatePod(nil, nil, nil, namespace)
807+
808+
flagSourceConfig := getFlagSourceConfigSpec()
809+
810+
flagSourceConfig.Sources = []api.Source{
811+
{
812+
Source: "my-namespace/server-side",
813+
Provider: apicommon.SyncProviderFilepath,
814+
},
815+
}
816+
817+
err := fi.InjectFlagd(context.Background(), &pod.ObjectMeta, &pod.Spec, flagSourceConfig)
818+
819+
require.Nil(t, err)
820+
821+
expectedPod := getExpectedStandalonePod(namespace)
822+
823+
expectedPod.Spec.Volumes = []v1.Volume{
824+
{
825+
Name: "server-side",
826+
VolumeSource: v1.VolumeSource{
827+
ConfigMap: &v1.ConfigMapVolumeSource{
828+
LocalObjectReference: v1.LocalObjectReference{
829+
Name: "server-side",
830+
},
831+
},
832+
},
833+
},
834+
}
835+
836+
expectedPod.Spec.Containers[0].Args = []string{"start", "--management-port", "8014", "--port", "8013", "--sources", "[{\"uri\":\"/etc/flagd/my-namespace_server-side/my-namespace_server-side.flagd.json\",\"provider\":\"file\"}]"}
837+
expectedPod.Spec.Containers[0].VolumeMounts = []v1.VolumeMount{
838+
{
839+
Name: "server-side",
840+
ReadOnly: false,
841+
MountPath: "/etc/flagd/my-namespace_server-side",
842+
},
843+
}
844+
845+
require.Equal(t, expectedPod, pod)
846+
847+
// verify the creation of the referenced ConfigMap
848+
cm := &v1.ConfigMap{}
849+
err = fakeClient.Get(context.TODO(), client.ObjectKey{Name: pod.Spec.Volumes[0].ConfigMap.Name, Namespace: namespace}, cm)
850+
require.Nil(t, err)
851+
}
852+
714853
func TestFlagdContainerInjector_createConfigMap(t *testing.T) {
715854
_ = api.AddToScheme(scheme.Scheme)
716855

@@ -973,6 +1112,101 @@ func getExpectedPod(namespace string) v1.Pod {
9731112
}
9741113
}
9751114

1115+
func getExpectedStandalonePod(namespace string) v1.Pod {
1116+
return v1.Pod{
1117+
ObjectMeta: metav1.ObjectMeta{
1118+
Name: "my-pod",
1119+
Namespace: namespace,
1120+
},
1121+
Spec: v1.PodSpec{
1122+
Containers: []v1.Container{
1123+
{
1124+
Name: "flagd",
1125+
Image: "flagd:0.5.0",
1126+
WorkingDir: "",
1127+
Ports: []v1.ContainerPort{
1128+
{
1129+
Name: "management",
1130+
ContainerPort: int32(8014),
1131+
},
1132+
{
1133+
Name: "flagd",
1134+
ContainerPort: int32(8013),
1135+
},
1136+
},
1137+
Env: []v1.EnvVar{
1138+
{
1139+
Name: "flagd_my-env-var",
1140+
Value: "my-value",
1141+
},
1142+
{
1143+
Name: "flagd_MANAGEMENT_PORT",
1144+
Value: "8014",
1145+
},
1146+
{
1147+
Name: "flagd_PORT",
1148+
Value: "8013",
1149+
},
1150+
{
1151+
Name: "flagd_EVALUATOR",
1152+
Value: "",
1153+
},
1154+
{
1155+
Name: "flagd_LOG_FORMAT",
1156+
Value: "",
1157+
},
1158+
{
1159+
Name: "flagd_RESOLVER",
1160+
Value: "rpc",
1161+
},
1162+
},
1163+
Resources: getResourceRequirements(),
1164+
LivenessProbe: &v1.Probe{
1165+
ProbeHandler: v1.ProbeHandler{
1166+
HTTPGet: &v1.HTTPGetAction{
1167+
Path: "/healthz",
1168+
Port: intstr.IntOrString{Type: 0, IntVal: 8014, StrVal: ""},
1169+
Host: "",
1170+
Scheme: "HTTP",
1171+
},
1172+
},
1173+
InitialDelaySeconds: 5,
1174+
},
1175+
ReadinessProbe: &v1.Probe{
1176+
ProbeHandler: v1.ProbeHandler{
1177+
HTTPGet: &v1.HTTPGetAction{
1178+
Path: "/readyz",
1179+
Port: intstr.IntOrString{Type: 0, IntVal: 8014, StrVal: ""},
1180+
Host: "",
1181+
Scheme: "HTTP",
1182+
},
1183+
},
1184+
InitialDelaySeconds: 5,
1185+
},
1186+
VolumeMounts: []v1.VolumeMount{},
1187+
ImagePullPolicy: "Always",
1188+
SecurityContext: &v1.SecurityContext{
1189+
Capabilities: &v1.Capabilities{
1190+
Drop: []v1.Capability{
1191+
"ALL",
1192+
},
1193+
},
1194+
Privileged: utils.FalseVal(),
1195+
RunAsUser: intPtr(65532),
1196+
RunAsGroup: intPtr(65532),
1197+
RunAsNonRoot: utils.TrueVal(),
1198+
ReadOnlyRootFilesystem: utils.TrueVal(),
1199+
AllowPrivilegeEscalation: utils.FalseVal(),
1200+
SeccompProfile: &v1.SeccompProfile{
1201+
Type: "RuntimeDefault",
1202+
},
1203+
},
1204+
},
1205+
},
1206+
},
1207+
}
1208+
}
1209+
9761210
func generatePod(containers []v1.Container, initContainers []v1.Container, ownerRef []metav1.OwnerReference, ns string) v1.Pod {
9771211
return v1.Pod{
9781212
ObjectMeta: metav1.ObjectMeta{

0 commit comments

Comments
 (0)