iop/apps/control-plane/cmd/control-plane/main_test.go
toki 6f36449daa feat(control-plane): edge connector implementation and control proto updates
- Add edge connector module (edge.go, edge_registry.go, edge_server.go)
- Add edge server tests (edge_server_test.go, edge_test.go)
- Update control.proto with edge-related messages and RPCs
- Generate proto files for Go, Dart
- Update control-plane Dockerfile and configuration
- Add client-side proto bindings
- Update roadmap and milestones for control-plane-edge-wire-baseline
- Add agent-task documentation for edge connector and local smoke tests
- Update docker-compose.yml for edge support
2026-05-30 20:00:37 +09:00

232 lines
6.8 KiB
Go

package main
import (
"fmt"
"os"
"path/filepath"
"strings"
"testing"
)
func TestLoadConfigDatabaseDefaultsToLocal(t *testing.T) {
t.Setenv("IOP_DATABASE_URL", "")
t.Setenv("IOP_REDIS_URL", "")
t.Setenv("IOP_REDIS_KEY_PREFIX", "")
cfg, err := loadConfig("")
if err != nil {
t.Fatalf("load config: %v", err)
}
const wantDatabase = "postgres://nomadcode:nomadcode@code-server-postgres:5432/iop-control-plane-local?sslmode=disable"
if cfg.Database.URL != wantDatabase {
t.Fatalf("database url: got %q want %q", cfg.Database.URL, wantDatabase)
}
const wantRedis = "redis://code-server-redis:6379/1"
if cfg.Redis.URL != wantRedis {
t.Fatalf("redis url: got %q want %q", cfg.Redis.URL, wantRedis)
}
const wantRedisKeyPrefix = "iop:control-plane:local:"
if cfg.Redis.KeyPrefix != wantRedisKeyPrefix {
t.Fatalf("redis key prefix: got %q want %q", cfg.Redis.KeyPrefix, wantRedisKeyPrefix)
}
}
func TestLoadConfigDatabaseFromYAML(t *testing.T) {
t.Setenv("IOP_DATABASE_URL", "")
t.Setenv("IOP_REDIS_URL", "")
t.Setenv("IOP_REDIS_KEY_PREFIX", "")
path := writeConfig(t, `
server:
listen: "127.0.0.1:9080"
database:
url: "postgres://user:pass@db:5432/iop-control-plane-local?sslmode=disable"
redis:
url: "redis://cache:6379/1"
key_prefix: "iop:test:"
`)
cfg, err := loadConfig(path)
if err != nil {
t.Fatalf("load config: %v", err)
}
const want = "postgres://user:pass@db:5432/iop-control-plane-local?sslmode=disable"
if cfg.Database.URL != want {
t.Fatalf("database url: got %q want %q", cfg.Database.URL, want)
}
if cfg.Redis.URL != "redis://cache:6379/1" {
t.Fatalf("redis url: got %q", cfg.Redis.URL)
}
if cfg.Redis.KeyPrefix != "iop:test:" {
t.Fatalf("redis key prefix: got %q", cfg.Redis.KeyPrefix)
}
}
func TestLoadConfigRepositoryLocalConfig(t *testing.T) {
t.Setenv("IOP_DATABASE_URL", "")
t.Setenv("IOP_REDIS_URL", "")
t.Setenv("IOP_REDIS_KEY_PREFIX", "")
t.Setenv("IOP_WIRE_LISTEN", "")
t.Setenv("IOP_EDGE_WIRE_LISTEN", "")
cfg, err := loadConfig("../../../../configs/control-plane.yaml")
if err != nil {
t.Fatalf("load config: %v", err)
}
if cfg.Redis.URL != "redis://code-server-redis:6379/1" {
t.Fatalf("redis url: got %q", cfg.Redis.URL)
}
if cfg.Redis.KeyPrefix != "iop:control-plane:local:" {
t.Fatalf("redis key prefix: got %q", cfg.Redis.KeyPrefix)
}
if cfg.Server.WireListen != "0.0.0.0:19080" {
t.Fatalf("wire_listen: got %q", cfg.Server.WireListen)
}
if cfg.Server.EdgeWireListen != "0.0.0.0:19081" {
t.Fatalf("edge_wire_listen: got %q", cfg.Server.EdgeWireListen)
}
}
func TestLoadConfigEnvOverrides(t *testing.T) {
path := writeConfig(t, `
database:
url: "postgres://user:pass@db:5432/iop-control-plane-local?sslmode=disable"
redis:
url: "redis://cache:6379/1"
key_prefix: "iop:control-plane:local:"
`)
const wantDatabase = "postgres://user:pass@db:5432/iop-control-plane-dev?sslmode=disable"
const wantRedis = "redis://redis:6379/2"
const wantRedisKeyPrefix = "iop:control-plane:dev:"
t.Setenv("IOP_DATABASE_URL", wantDatabase)
t.Setenv("IOP_REDIS_URL", wantRedis)
t.Setenv("IOP_REDIS_KEY_PREFIX", wantRedisKeyPrefix)
cfg, err := loadConfig(path)
if err != nil {
t.Fatalf("load config: %v", err)
}
if cfg.Database.URL != wantDatabase {
t.Fatalf("database url: got %q want %q", cfg.Database.URL, wantDatabase)
}
if cfg.Redis.URL != wantRedis {
t.Fatalf("redis url: got %q want %q", cfg.Redis.URL, wantRedis)
}
if cfg.Redis.KeyPrefix != wantRedisKeyPrefix {
t.Fatalf("redis key prefix: got %q want %q", cfg.Redis.KeyPrefix, wantRedisKeyPrefix)
}
}
func TestDatabaseLogFieldsDoNotExposeCredentials(t *testing.T) {
fields := databaseLogFields("postgres://user:secret@db.example:5432/iop-control-plane-local?sslmode=disable")
var host, database string
for _, field := range fields {
switch field.Key {
case "host":
host = field.String
case "database":
database = field.String
}
}
if host != "db.example:5432" {
t.Fatalf("host field: got %q", host)
}
if database != "iop-control-plane-local" {
t.Fatalf("database field: got %q", database)
}
if strings.Contains(fmt.Sprint(fields), "secret") {
t.Fatal("secret leaked into log fields")
}
}
func TestRedisLogFields(t *testing.T) {
fields := redisLogFields("redis://:secret@cache.example:6379/2", "iop:control-plane:dev:")
var host, database, keyPrefix string
for _, field := range fields {
switch field.Key {
case "host":
host = field.String
case "database":
database = field.String
case "key_prefix":
keyPrefix = field.String
}
}
if host != "cache.example:6379" {
t.Fatalf("host field: got %q", host)
}
if database != "2" {
t.Fatalf("database field: got %q", database)
}
if keyPrefix != "iop:control-plane:dev:" {
t.Fatalf("key_prefix field: got %q", keyPrefix)
}
if strings.Contains(fmt.Sprint(fields), "secret") {
t.Fatal("secret leaked into log fields")
}
}
func writeConfig(t *testing.T, body string) string {
t.Helper()
path := filepath.Join(t.TempDir(), "control-plane.yaml")
if err := os.WriteFile(path, []byte(body), 0o600); err != nil {
t.Fatalf("write config: %v", err)
}
return path
}
func TestLoadConfigWireListenEnvOverrides(t *testing.T) {
path := writeConfig(t, `
server:
listen: "0.0.0.0:9080"
wire_listen: "0.0.0.0:19080"
`)
const wantListen = "127.0.0.1:9081"
const wantWireListen = "127.0.0.1:19081"
t.Setenv("IOP_LISTEN", wantListen)
t.Setenv("IOP_WIRE_LISTEN", wantWireListen)
cfg, err := loadConfig(path)
if err != nil {
t.Fatalf("load config: %v", err)
}
if cfg.Server.Listen != wantListen {
t.Fatalf("listen: got %q want %q", cfg.Server.Listen, wantListen)
}
if cfg.Server.WireListen != wantWireListen {
t.Fatalf("wire_listen: got %q want %q", cfg.Server.WireListen, wantWireListen)
}
}
func TestLoadConfigEdgeWireListenDefault(t *testing.T) {
t.Setenv("IOP_EDGE_WIRE_LISTEN", "")
cfg, err := loadConfig("")
if err != nil {
t.Fatalf("load config: %v", err)
}
if cfg.Server.EdgeWireListen != "0.0.0.0:19081" {
t.Fatalf("edge_wire_listen default: got %q want %q", cfg.Server.EdgeWireListen, "0.0.0.0:19081")
}
if cfg.Server.EdgeWireListen == cfg.Server.WireListen {
t.Fatalf("edge_wire_listen must not share the client wire_listen address %q", cfg.Server.WireListen)
}
}
func TestLoadConfigEdgeWireListenEnvOverrides(t *testing.T) {
path := writeConfig(t, `
server:
listen: "0.0.0.0:9080"
wire_listen: "0.0.0.0:19080"
edge_wire_listen: "0.0.0.0:19081"
`)
const wantEdgeWireListen = "127.0.0.1:29081"
t.Setenv("IOP_EDGE_WIRE_LISTEN", wantEdgeWireListen)
cfg, err := loadConfig(path)
if err != nil {
t.Fatalf("load config: %v", err)
}
if cfg.Server.EdgeWireListen != wantEdgeWireListen {
t.Fatalf("edge_wire_listen: got %q want %q", cfg.Server.EdgeWireListen, wantEdgeWireListen)
}
if cfg.Server.WireListen != "0.0.0.0:19080" {
t.Fatalf("wire_listen should stay from YAML: got %q", cfg.Server.WireListen)
}
}