// Создано: 2026-03-11 // Юнит-тесты для FunctionReconciler (без k8s envtest). // Проверяют логику которую можно тестировать изолированно. package controllers import ( "testing" slessv1alpha1 "gitea-naeel.giteak8s.services.ngcloud.ru/naeel/sless/api/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // TestBuildDeployment_EnvVarsSorted проверяет что env vars в Deployment всегда // идут в алфавитном порядке — независимо от порядка в map. // Важно: нестабильный порядок приводит к лишним pod restarts в k8s. func TestBuildDeployment_EnvVarsSorted(t *testing.T) { r := &FunctionReconciler{ RegistrySecret: "", } fn := &slessv1alpha1.Function{ ObjectMeta: metav1.ObjectMeta{Name: "test-fn", Namespace: "test-ns"}, Spec: slessv1alpha1.FunctionSpec{ Entrypoint: "handler.handle", MemoryMB: 128, Env: map[string]string{ "ZEBRA": "last", "ALPHA": "first", "MIDDLE": "middle", "DATABASE": "url", }, }, Status: slessv1alpha1.FunctionStatus{ ImageRef: "registry/test:abc123", }, } dep := r.buildDeployment(fn, "sless-fn-test-ns") envs := dep.Spec.Template.Spec.Containers[0].Env // Первый env всегда SLESS_ENTRYPOINT if envs[0].Name != "SLESS_ENTRYPOINT" { t.Fatalf("first env should be SLESS_ENTRYPOINT, got %s", envs[0].Name) } // Остальные — отсортированы по алфавиту userEnvs := envs[1:] for i := 1; i < len(userEnvs); i++ { if userEnvs[i].Name < userEnvs[i-1].Name { t.Errorf("env vars not sorted at index %d: %s before %s", i, userEnvs[i-1].Name, userEnvs[i].Name) } } // Все 4 ключа присутствуют if len(userEnvs) != 4 { t.Errorf("expected 4 user env vars, got %d", len(userEnvs)) } } // TestBuildDeployment_EmptyEnv проверяет что функция без env vars корректно // создаёт Deployment только с SLESS_ENTRYPOINT. func TestBuildDeployment_EmptyEnv(t *testing.T) { r := &FunctionReconciler{} fn := &slessv1alpha1.Function{ ObjectMeta: metav1.ObjectMeta{Name: "bare-fn", Namespace: "ns"}, Spec: slessv1alpha1.FunctionSpec{ Entrypoint: "main.run", MemoryMB: 64, }, Status: slessv1alpha1.FunctionStatus{ImageRef: "reg/bare:tag"}, } dep := r.buildDeployment(fn, "sless-fn-ns") envs := dep.Spec.Template.Spec.Containers[0].Env if len(envs) != 1 { t.Errorf("expected only SLESS_ENTRYPOINT, got %d env vars", len(envs)) } if envs[0].Name != "SLESS_ENTRYPOINT" || envs[0].Value != "main.run" { t.Errorf("unexpected env: %+v", envs[0]) } }