mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-20 22:52:29 +02:00
291 lines
7.7 KiB
Go
291 lines
7.7 KiB
Go
package docker
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func cleanEmptyLines(s string) string {
|
|
lines := strings.Split(s, "\n")
|
|
var result []string
|
|
for _, line := range lines {
|
|
if strings.TrimSpace(line) != "" {
|
|
result = append(result, line)
|
|
}
|
|
}
|
|
return strings.Join(result, "\n")
|
|
}
|
|
|
|
var defaultCaps = &DockerCapabilities{
|
|
VersionDocker: Version{Major: 26, Minor: 1, Patch: 1},
|
|
VersionCompose: Version{Major: 2, Minor: 27, Patch: 0},
|
|
HealthcheckStartInterval: false,
|
|
}
|
|
|
|
func TestComposeCustomDBNoDebugger(t *testing.T) {
|
|
port := 8123
|
|
actual := Compose(defaultCaps, ComposeOpts{
|
|
Port: port,
|
|
PostgresURI: "custom_postgres_uri",
|
|
})
|
|
expected := fmt.Sprintf(`services:
|
|
langgraph-redis:
|
|
image: redis:6
|
|
healthcheck:
|
|
test: redis-cli ping
|
|
interval: 5s
|
|
timeout: 1s
|
|
retries: 5
|
|
langgraph-api:
|
|
ports:
|
|
- "%d:8000"
|
|
depends_on:
|
|
langgraph-redis:
|
|
condition: service_healthy
|
|
environment:
|
|
REDIS_URI: redis://langgraph-redis:6379
|
|
POSTGRES_URI: custom_postgres_uri`, port)
|
|
|
|
if cleanEmptyLines(actual) != expected {
|
|
t.Errorf("mismatch.\nExpected:\n%s\n\nGot:\n%s", expected, cleanEmptyLines(actual))
|
|
}
|
|
}
|
|
|
|
func TestComposeCustomDBWithHealthcheck(t *testing.T) {
|
|
port := 8123
|
|
capsHC := &DockerCapabilities{
|
|
VersionDocker: Version{Major: 26, Minor: 1, Patch: 1},
|
|
VersionCompose: Version{Major: 2, Minor: 27, Patch: 0},
|
|
HealthcheckStartInterval: true,
|
|
}
|
|
actual := Compose(capsHC, ComposeOpts{
|
|
Port: port,
|
|
PostgresURI: "custom_postgres_uri",
|
|
})
|
|
expected := fmt.Sprintf(`services:
|
|
langgraph-redis:
|
|
image: redis:6
|
|
healthcheck:
|
|
test: redis-cli ping
|
|
interval: 5s
|
|
timeout: 1s
|
|
retries: 5
|
|
langgraph-api:
|
|
ports:
|
|
- "%d:8000"
|
|
depends_on:
|
|
langgraph-redis:
|
|
condition: service_healthy
|
|
environment:
|
|
REDIS_URI: redis://langgraph-redis:6379
|
|
POSTGRES_URI: custom_postgres_uri
|
|
healthcheck:
|
|
test: python /api/healthcheck.py
|
|
interval: 60s
|
|
start_interval: 1s
|
|
start_period: 10s`, port)
|
|
|
|
if cleanEmptyLines(actual) != expected {
|
|
t.Errorf("mismatch.\nExpected:\n%s\n\nGot:\n%s", expected, cleanEmptyLines(actual))
|
|
}
|
|
}
|
|
|
|
func TestComposeDefaultDB(t *testing.T) {
|
|
port := 8123
|
|
actual := Compose(defaultCaps, ComposeOpts{Port: port})
|
|
expected := fmt.Sprintf(`volumes:
|
|
langgraph-data:
|
|
driver: local
|
|
services:
|
|
langgraph-redis:
|
|
image: redis:6
|
|
healthcheck:
|
|
test: redis-cli ping
|
|
interval: 5s
|
|
timeout: 1s
|
|
retries: 5
|
|
langgraph-postgres:
|
|
image: pgvector/pgvector:pg16
|
|
ports:
|
|
- "5433:5432"
|
|
environment:
|
|
POSTGRES_DB: postgres
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: postgres
|
|
command:
|
|
- postgres
|
|
- -c
|
|
- shared_preload_libraries=vector
|
|
volumes:
|
|
- langgraph-data:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: pg_isready -U postgres
|
|
start_period: 10s
|
|
timeout: 1s
|
|
retries: 5
|
|
interval: 5s
|
|
langgraph-api:
|
|
ports:
|
|
- "%d:8000"
|
|
depends_on:
|
|
langgraph-redis:
|
|
condition: service_healthy
|
|
langgraph-postgres:
|
|
condition: service_healthy
|
|
environment:
|
|
REDIS_URI: redis://langgraph-redis:6379
|
|
POSTGRES_URI: %s`, port, DefaultPostgresURI)
|
|
|
|
if cleanEmptyLines(actual) != expected {
|
|
t.Errorf("mismatch.\nExpected:\n%s\n\nGot:\n%s", expected, cleanEmptyLines(actual))
|
|
}
|
|
}
|
|
|
|
func TestComposeDistributedMode(t *testing.T) {
|
|
port := 8123
|
|
actual := Compose(defaultCaps, ComposeOpts{
|
|
Port: port,
|
|
PostgresURI: "custom_postgres_uri",
|
|
EngineRuntimeMode: "distributed",
|
|
})
|
|
expected := fmt.Sprintf(`services:
|
|
langgraph-redis:
|
|
image: redis:6
|
|
healthcheck:
|
|
test: redis-cli ping
|
|
interval: 5s
|
|
timeout: 1s
|
|
retries: 5
|
|
langgraph-api:
|
|
ports:
|
|
- "%d:8000"
|
|
depends_on:
|
|
langgraph-redis:
|
|
condition: service_healthy
|
|
environment:
|
|
REDIS_URI: redis://langgraph-redis:6379
|
|
POSTGRES_URI: custom_postgres_uri
|
|
N_JOBS_PER_WORKER: "0"`, port)
|
|
|
|
if cleanEmptyLines(actual) != expected {
|
|
t.Errorf("mismatch.\nExpected:\n%s\n\nGot:\n%s", expected, cleanEmptyLines(actual))
|
|
}
|
|
}
|
|
|
|
func TestComposeCombinedModeNoNJobs(t *testing.T) {
|
|
actual := Compose(defaultCaps, ComposeOpts{
|
|
Port: 8123,
|
|
EngineRuntimeMode: "combined_queue_worker",
|
|
})
|
|
if strings.Contains(actual, "N_JOBS_PER_WORKER") {
|
|
t.Error("combined mode should not contain N_JOBS_PER_WORKER")
|
|
}
|
|
}
|
|
|
|
func TestComposeDebuggerDefaultDB(t *testing.T) {
|
|
port := 8123
|
|
debuggerPort := 8001
|
|
actual := Compose(defaultCaps, ComposeOpts{
|
|
Port: port,
|
|
DebuggerPort: debuggerPort,
|
|
})
|
|
expected := fmt.Sprintf(`volumes:
|
|
langgraph-data:
|
|
driver: local
|
|
services:
|
|
langgraph-redis:
|
|
image: redis:6
|
|
healthcheck:
|
|
test: redis-cli ping
|
|
interval: 5s
|
|
timeout: 1s
|
|
retries: 5
|
|
langgraph-postgres:
|
|
image: pgvector/pgvector:pg16
|
|
ports:
|
|
- "5433:5432"
|
|
environment:
|
|
POSTGRES_DB: postgres
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: postgres
|
|
command:
|
|
- postgres
|
|
- -c
|
|
- shared_preload_libraries=vector
|
|
volumes:
|
|
- langgraph-data:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: pg_isready -U postgres
|
|
start_period: 10s
|
|
timeout: 1s
|
|
retries: 5
|
|
interval: 5s
|
|
langgraph-debugger:
|
|
image: langchain/langgraph-debugger
|
|
restart: on-failure
|
|
depends_on:
|
|
langgraph-postgres:
|
|
condition: service_healthy
|
|
ports:
|
|
- "%d:3968"
|
|
langgraph-api:
|
|
ports:
|
|
- "%d:8000"
|
|
depends_on:
|
|
langgraph-redis:
|
|
condition: service_healthy
|
|
langgraph-postgres:
|
|
condition: service_healthy
|
|
environment:
|
|
REDIS_URI: redis://langgraph-redis:6379
|
|
POSTGRES_URI: %s`, debuggerPort, port, DefaultPostgresURI)
|
|
|
|
if cleanEmptyLines(actual) != expected {
|
|
t.Errorf("mismatch.\nExpected:\n%s\n\nGot:\n%s", expected, cleanEmptyLines(actual))
|
|
}
|
|
}
|
|
|
|
func TestParseVersion(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
expected Version
|
|
}{
|
|
{"1.2.3", Version{1, 2, 3}},
|
|
{"v1.2.3", Version{1, 2, 3}},
|
|
{"1.2.3-alpha", Version{1, 2, 3}},
|
|
{"1.2.3+1", Version{1, 2, 3}},
|
|
{"1.2.3-alpha+build", Version{1, 2, 3}},
|
|
{"1.2", Version{1, 2, 0}},
|
|
{"1", Version{1, 0, 0}},
|
|
{"v28.1.1+1", Version{28, 1, 1}},
|
|
{"2.0.0-beta.1+exp.sha.5114f85", Version{2, 0, 0}},
|
|
{"v3.4.5-rc1+build.123", Version{3, 4, 5}},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
result := ParseVersion(tc.input)
|
|
if result != tc.expected {
|
|
t.Errorf("ParseVersion(%q) = %v, want %v", tc.input, result, tc.expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestVersionGreaterOrEqual(t *testing.T) {
|
|
tests := []struct {
|
|
v, other Version
|
|
want bool
|
|
}{
|
|
{Version{25, 0, 0}, Version{25, 0, 0}, true},
|
|
{Version{26, 1, 1}, Version{25, 0, 0}, true},
|
|
{Version{24, 9, 9}, Version{25, 0, 0}, false},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
got := tc.v.GreaterOrEqual(tc.other)
|
|
if got != tc.want {
|
|
t.Errorf("%v.GreaterOrEqual(%v) = %v, want %v", tc.v, tc.other, got, tc.want)
|
|
}
|
|
}
|
|
}
|