suite: test deployment templates: - deployment.yaml - configmap-litellm.yaml tests: - it: should work template: deployment.yaml set: image.tag: test asserts: - isKind: of: Deployment - matchRegex: path: metadata.name pattern: -litellm$ - equal: path: spec.template.spec.containers[0].image value: ghcr.io/berriai/litellm:test - it: should work with tolerations template: deployment.yaml set: tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule asserts: - equal: path: spec.template.spec.tolerations[0].key value: node-role.kubernetes.io/master - equal: path: spec.template.spec.tolerations[0].operator value: Exists - it: should work with affinity template: deployment.yaml set: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: topology.kubernetes.io/zone operator: In values: - antarctica-east1 asserts: - equal: path: spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[0].matchExpressions[0].key value: topology.kubernetes.io/zone - equal: path: spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[0].matchExpressions[0].operator value: In - equal: path: spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[0].matchExpressions[0].values[0] value: antarctica-east1 - it: should work without masterkeySecretName or masterkeySecretKey template: deployment.yaml set: masterkeySecretName: "" masterkeySecretKey: "" asserts: - contains: path: spec.template.spec.containers[0].env content: name: PROXY_MASTER_KEY valueFrom: secretKeyRef: name: RELEASE-NAME-litellm-masterkey key: masterkey - it: should work with masterkeySecretName and masterkeySecretKey template: deployment.yaml set: masterkeySecretName: my-secret masterkeySecretKey: my-key asserts: - contains: path: spec.template.spec.containers[0].env content: name: PROXY_MASTER_KEY valueFrom: secretKeyRef: name: my-secret key: my-key - it: should inject DATABASE_READER_HOST from readReplicaEndpointKey before DATABASE_URL_READ_REPLICA template: deployment.yaml set: db: deployStandalone: false useExisting: true secret: name: postgres usernameKey: username passwordKey: password readReplicaEndpointKey: reader-host readReplicaUrl: postgresql://$(DATABASE_USERNAME):$(DATABASE_PASSWORD)@$(DATABASE_READER_HOST):5432/$(DATABASE_NAME)?sslmode=require asserts: - contains: path: spec.template.spec.containers[0].env content: name: DATABASE_READER_HOST valueFrom: secretKeyRef: name: postgres key: reader-host - contains: path: spec.template.spec.containers[0].env content: name: DATABASE_URL_READ_REPLICA value: postgresql://$(DATABASE_USERNAME):$(DATABASE_PASSWORD)@$(DATABASE_READER_HOST):5432/$(DATABASE_NAME)?sslmode=require # $(VAR) interpolation only resolves vars defined EARLIER in the env # array, so the reader host must precede the composed URL - equal: path: spec.template.spec.containers[0].env[7].name value: DATABASE_READER_HOST - equal: path: spec.template.spec.containers[0].env[8].name value: DATABASE_URL_READ_REPLICA - it: should omit reader host when readReplicaUrl is unset template: deployment.yaml set: db: deployStandalone: false useExisting: true secret: name: postgres usernameKey: username passwordKey: password readReplicaEndpointKey: reader-host asserts: - notContains: path: spec.template.spec.containers[0].env content: name: DATABASE_READER_HOST valueFrom: secretKeyRef: name: postgres key: reader-host - it: should prefer readReplicaUrlKey over readReplicaEndpointKey composition template: deployment.yaml set: db: useExisting: true secret: name: postgres usernameKey: username passwordKey: password readReplicaUrlKey: reader-url readReplicaEndpointKey: reader-host readReplicaUrl: postgresql://ignored asserts: - contains: path: spec.template.spec.containers[0].env content: name: DATABASE_URL_READ_REPLICA valueFrom: secretKeyRef: name: postgres key: reader-url - notContains: path: spec.template.spec.containers[0].env content: name: DATABASE_URL_READ_REPLICA value: postgresql://ignored # the unused reader-host secret ref must be suppressed so a missing # key can't fail pod creation - notContains: path: spec.template.spec.containers[0].env content: name: DATABASE_READER_HOST valueFrom: secretKeyRef: name: postgres key: reader-host - it: should work with extraEnvVars template: deployment.yaml set: extraEnvVars: - name: EXTRA_ENV_VAR valueFrom: fieldRef: fieldPath: metadata.labels['env'] asserts: - contains: path: spec.template.spec.containers[0].env content: name: EXTRA_ENV_VAR valueFrom: fieldRef: fieldPath: metadata.labels['env'] - it: should work with both extraEnvVars and envVars template: deployment.yaml set: envVars: ENV_VAR: ENV_VAR_VALUE extraEnvVars: - name: EXTRA_ENV_VAR value: EXTRA_ENV_VAR_VALUE asserts: - contains: path: spec.template.spec.containers[0].env content: name: ENV_VAR value: ENV_VAR_VALUE - contains: path: spec.template.spec.containers[0].env content: name: EXTRA_ENV_VAR value: EXTRA_ENV_VAR_VALUE - it: should mount existing configmap when create=false template: deployment.yaml set: proxyConfigMap: create: false name: my-litellm-config key: custom.yaml asserts: - contains: path: spec.template.spec.volumes content: name: litellm-config configMap: name: my-litellm-config items: - key: custom.yaml path: config.yaml - contains: path: spec.template.spec.containers[0].volumeMounts content: name: litellm-config mountPath: /etc/litellm/config.yaml subPath: config.yaml - it: should work with lifecycle hooks template: deployment.yaml set: lifecycle: preStop: exec: command: - /bin/sh - -c - echo "Container stopping" asserts: - exists: path: spec.template.spec.containers[0].lifecycle - equal: path: spec.template.spec.containers[0].lifecycle.preStop.exec.command[0] value: /bin/sh - equal: path: spec.template.spec.containers[0].lifecycle.preStop.exec.command[1] value: -c - equal: path: spec.template.spec.containers[0].lifecycle.preStop.exec.command[2] value: echo "Container stopping" - it: should render background health check settings from proxy_config.general_settings template: configmap-litellm.yaml set: proxy_config.general_settings.background_health_checks: true proxy_config.general_settings.health_check_interval: 240 proxy_config.general_settings.health_check_concurrency: 16 proxy_config.general_settings.health_check_details: false asserts: - matchRegex: path: data["config.yaml"] pattern: '(?m)^\s*background_health_checks:\s*true$' - matchRegex: path: data["config.yaml"] pattern: '(?m)^\s*health_check_interval:\s*240$' - matchRegex: path: data["config.yaml"] pattern: '(?m)^\s*health_check_concurrency:\s*16$' - matchRegex: path: data["config.yaml"] pattern: '(?m)^\s*health_check_details:\s*false$' - it: should allow overriding liveness, readiness, and startup probes template: deployment.yaml set: livenessProbe: path: /custom/livez initialDelaySeconds: 5 periodSeconds: 15 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 readinessProbe: path: /custom/readyz initialDelaySeconds: 10 periodSeconds: 20 timeoutSeconds: 6 successThreshold: 1 failureThreshold: 6 startupProbe: path: /custom/startupz initialDelaySeconds: 15 periodSeconds: 25 timeoutSeconds: 7 successThreshold: 1 failureThreshold: 40 asserts: - equal: path: spec.template.spec.containers[0].livenessProbe.httpGet.path value: /custom/livez - equal: path: spec.template.spec.containers[0].livenessProbe.timeoutSeconds value: 5 - equal: path: spec.template.spec.containers[0].readinessProbe.httpGet.path value: /custom/readyz - equal: path: spec.template.spec.containers[0].readinessProbe.timeoutSeconds value: 6 - equal: path: spec.template.spec.containers[0].startupProbe.httpGet.path value: /custom/startupz - equal: path: spec.template.spec.containers[0].startupProbe.failureThreshold value: 40 - it: should render container resources from values template: deployment.yaml set: resources: limits: cpu: 500m memory: 2Gi requests: cpu: 250m memory: 1Gi asserts: - equal: path: spec.template.spec.containers[0].resources.limits.cpu value: 500m - equal: path: spec.template.spec.containers[0].resources.limits.memory value: 2Gi - equal: path: spec.template.spec.containers[0].resources.requests.cpu value: 250m - equal: path: spec.template.spec.containers[0].resources.requests.memory value: 1Gi - it: should keep default probes and empty resources unchanged template: deployment.yaml asserts: - equal: path: spec.template.spec.containers[0].livenessProbe.httpGet.path value: /health/liveliness - equal: path: spec.template.spec.containers[0].livenessProbe.initialDelaySeconds value: 0 - equal: path: spec.template.spec.containers[0].livenessProbe.periodSeconds value: 15 - equal: path: spec.template.spec.containers[0].livenessProbe.timeoutSeconds value: 5 - equal: path: spec.template.spec.containers[0].livenessProbe.successThreshold value: 1 - equal: path: spec.template.spec.containers[0].livenessProbe.failureThreshold value: 5 - equal: path: spec.template.spec.containers[0].readinessProbe.httpGet.path value: /health/readiness - equal: path: spec.template.spec.containers[0].readinessProbe.initialDelaySeconds value: 0 - equal: path: spec.template.spec.containers[0].readinessProbe.periodSeconds value: 10 - equal: path: spec.template.spec.containers[0].readinessProbe.timeoutSeconds value: 5 - equal: path: spec.template.spec.containers[0].readinessProbe.successThreshold value: 1 - equal: path: spec.template.spec.containers[0].readinessProbe.failureThreshold value: 3 - equal: path: spec.template.spec.containers[0].startupProbe.httpGet.path value: /health/readiness - equal: path: spec.template.spec.containers[0].startupProbe.initialDelaySeconds value: 0 - equal: path: spec.template.spec.containers[0].startupProbe.periodSeconds value: 10 - equal: path: spec.template.spec.containers[0].startupProbe.timeoutSeconds value: 5 - equal: path: spec.template.spec.containers[0].startupProbe.successThreshold value: 1 - equal: path: spec.template.spec.containers[0].startupProbe.failureThreshold value: 30 - equal: path: spec.template.spec.containers[0].resources value: {} - it: should be able to set minReadySeconds template: deployment.yaml set: deploymentMinReadySeconds: 5 asserts: - equal: path: spec.minReadySeconds value: 5 - it: should have minReadySeconds absent when deploymentMinReadySeconds is not set template: deployment.yaml asserts: - notExists: path: spec.minReadySeconds - it: should work with extraInitContainers template: deployment.yaml set: extraInitContainers: - name: init-test image: busybox:latest command: ["echo", "hello"] asserts: - contains: path: spec.template.spec.initContainers content: name: init-test image: busybox:latest command: ["echo", "hello"] - it: should support tpl in extraInitContainers template: deployment.yaml set: image: repository: ghcr.io/berriai/litellm tag: test extraInitContainers: - name: init-tpl image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" command: ["echo", "hello"] asserts: - contains: path: spec.template.spec.initContainers content: name: init-tpl image: "ghcr.io/berriai/litellm:test" command: ["echo", "hello"] - it: should work with extraContainers template: deployment.yaml set: extraContainers: - name: sidecar image: busybox:latest asserts: - contains: path: spec.template.spec.containers content: name: sidecar image: busybox:latest - it: should support tpl in extraContainers template: deployment.yaml set: image: repository: ghcr.io/berriai/litellm tag: test extraContainers: - name: sidecar-tpl image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" asserts: - contains: path: spec.template.spec.containers content: name: sidecar-tpl image: "ghcr.io/berriai/litellm:test" - it: should support tpl in podAnnotations template: deployment.yaml set: image: repository: ghcr.io/berriai/litellm tag: test # Mirrors the real-world scenario this feature unblocks: # user disables the built-in ConfigMap (and its built-in checksum/config # annotation) and re-implements checksum/config themselves via tpl. proxyConfigMap: create: false podAnnotations: checksum/config: "{{ .Values.image.tag }}" example.com/some-key: "{{ .Values.image.repository }}" example.com/literal: "plain-string-value" asserts: - equal: path: spec.template.metadata.annotations["checksum/config"] value: "test" - equal: path: spec.template.metadata.annotations["example.com/some-key"] value: "ghcr.io/berriai/litellm" - equal: path: spec.template.metadata.annotations["example.com/literal"] value: "plain-string-value"