| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- /*
- Copyright 2026 LocoStack.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package templates
- import (
- "strings"
- "testing"
- "github.com/LocoStack/loco-operator/api/v1alpha1"
- corev1 "k8s.io/api/core/v1"
- )
- func TestResolveTemplateMergesBaseAndOverride(t *testing.T) {
- m := NewTemplateManager()
- m.RegisterTemplate(v1alpha1.Template{
- Name: "stack-default",
- Spec: v1alpha1.TemplateSpec{
- NodeSelector: map[string]string{"zone": "a", "disk": "hdd"},
- Runtime: v1alpha1.RuntimeSpec{
- Name: "go-runtime",
- Image: "golang:1.24",
- Port: 8080,
- },
- },
- })
- override := &v1alpha1.Template{
- Name: "stack-default",
- Spec: v1alpha1.TemplateSpec{
- NodeSelector: map[string]string{"disk": "ssd"},
- Runtime: v1alpha1.RuntimeSpec{
- Image: "my-custom-image:1",
- },
- },
- }
- resolved, err := m.ResolveTemplate(override, "stack-default")
- if err != nil {
- t.Fatalf("expected no error, got %v", err)
- }
- if got := resolved.Spec.NodeSelector["zone"]; got != "a" {
- t.Fatalf("expected inherited nodeSelector zone, got %q", got)
- }
- if got := resolved.Spec.NodeSelector["disk"]; got != "ssd" {
- t.Fatalf("expected override nodeSelector disk, got %q", got)
- }
- if resolved.Spec.Runtime.Name != "go-runtime" {
- t.Fatalf("expected runtime name from base, got %q", resolved.Spec.Runtime.Name)
- }
- if resolved.Spec.Runtime.Image != "my-custom-image:1" {
- t.Fatalf("expected runtime image override, got %q", resolved.Spec.Runtime.Image)
- }
- if resolved.Spec.Runtime.Port != 8080 {
- t.Fatalf("expected inherited runtime port, got %d", resolved.Spec.Runtime.Port)
- }
- }
- func TestResolveTemplateErrorsWhenTemplateMissing(t *testing.T) {
- m := NewTemplateManager()
- _, err := m.ResolveTemplate(&v1alpha1.Template{Name: "missing-template"}, "stack-default")
- if err == nil {
- t.Fatalf("expected error for missing template")
- }
- if !strings.Contains(err.Error(), "template \"missing-template\" not found") {
- t.Fatalf("unexpected error: %v", err)
- }
- }
- func TestResolveTemplateErrorsWhenRuntimeMissing(t *testing.T) {
- m := NewTemplateManager()
- m.RegisterTemplate(v1alpha1.Template{
- Name: "stack-default",
- Spec: v1alpha1.TemplateSpec{
- Runtime: v1alpha1.RuntimeSpec{Name: "go-runtime"},
- },
- })
- _, err := m.ResolveTemplate(&v1alpha1.Template{
- Name: "stack-default",
- Spec: v1alpha1.TemplateSpec{
- Runtime: v1alpha1.RuntimeSpec{Name: "python-runtime"},
- },
- }, "stack-default")
- if err == nil {
- t.Fatalf("expected error for missing runtime")
- }
- if !strings.Contains(err.Error(), "runtime \"python-runtime\" not found") {
- t.Fatalf("unexpected error: %v", err)
- }
- }
- func TestResolveTemplateResolvesRuntimePresetAndMergesOverride(t *testing.T) {
- m := NewTemplateManager()
- m.RegisterTemplate(v1alpha1.Template{
- Name: "stack-default",
- Spec: v1alpha1.TemplateSpec{
- Runtime: v1alpha1.RuntimeSpec{Name: "go-runtime", Image: "golang:1.24"},
- },
- })
- m.RegisterRuntime(v1alpha1.RuntimeSpec{
- Name: "python-runtime",
- Image: "python:3.12",
- Command: []string{"python"},
- ExtraArgs: []string{"-m", "http.server"},
- Env: []corev1.EnvVar{{Name: "BASE", Value: "1"}},
- Port: 8000,
- })
- override := &v1alpha1.Template{
- Name: "stack-default",
- Spec: v1alpha1.TemplateSpec{
- Runtime: v1alpha1.RuntimeSpec{
- Name: "python-runtime",
- Image: "python:3.12-slim",
- Args: []string{"-u"},
- Env: []corev1.EnvVar{{Name: "OVERRIDE", Value: "2"}},
- },
- },
- }
- resolved, err := m.ResolveTemplate(override, "stack-default")
- if err != nil {
- t.Fatalf("expected no error, got %v", err)
- }
- if resolved.Spec.Runtime.Name != "python-runtime" {
- t.Fatalf("expected resolved runtime name, got %q", resolved.Spec.Runtime.Name)
- }
- if resolved.Spec.Runtime.Image != "python:3.12-slim" {
- t.Fatalf("expected override image on resolved runtime, got %q", resolved.Spec.Runtime.Image)
- }
- if len(resolved.Spec.Runtime.Command) != 1 || resolved.Spec.Runtime.Command[0] != "python" {
- t.Fatalf("expected inherited command from runtime preset")
- }
- if len(resolved.Spec.Runtime.ExtraArgs) != 2 || resolved.Spec.Runtime.ExtraArgs[0] != "-m" {
- t.Fatalf("expected inherited extraArgs from runtime preset")
- }
- if len(resolved.Spec.Runtime.Args) != 1 || resolved.Spec.Runtime.Args[0] != "-u" {
- t.Fatalf("expected override args on resolved runtime")
- }
- if len(resolved.Spec.Runtime.Env) != 1 || resolved.Spec.Runtime.Env[0].Name != "OVERRIDE" {
- t.Fatalf("expected override env on resolved runtime")
- }
- if resolved.Spec.Runtime.Port != 8000 {
- t.Fatalf("expected inherited port from runtime preset, got %d", resolved.Spec.Runtime.Port)
- }
- }
- func TestResolveTemplateWithoutNameUsesDefaultTemplate(t *testing.T) {
- m := NewTemplateManager()
- m.RegisterTemplate(v1alpha1.Template{
- Name: "stack-default",
- Spec: v1alpha1.TemplateSpec{
- NodeSelector: map[string]string{"zone": "a", "disk": "hdd"},
- },
- })
- in := &v1alpha1.Template{
- Spec: v1alpha1.TemplateSpec{
- NodeSelector: map[string]string{"disk": "ssd"},
- },
- }
- resolved, err := m.ResolveTemplate(in, "stack-default")
- if err != nil {
- t.Fatalf("expected no error, got %v", err)
- }
- if got := resolved.Spec.NodeSelector["zone"]; got != "a" {
- t.Fatalf("expected nodeSelector zone from default template, got %q", got)
- }
- if got := resolved.Spec.NodeSelector["disk"]; got != "ssd" {
- t.Fatalf("expected nodeSelector disk override from input template, got %q", got)
- }
- }
|