Files
wehub-resource-sync f99010fae1
CI / lint (push) Failing after 1s
CI / frontend (push) Failing after 1s
CI / scripts (push) Failing after 1s
CI / Go Test (ubuntu-latest) (push) Failing after 0s
CI / frontend-node-25 (push) Failing after 1s
CI / docs (push) Failing after 0s
CI / coverage (push) Failing after 0s
CI / e2e (push) Failing after 0s
Docker / build-and-push (push) Failing after 1s
CI / integration (push) Failing after 4m43s
CI / Go Test (windows-latest) (push) Has been cancelled
CI / Desktop Unit Tests (Windows) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Linux) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Windows) (push) Has been cancelled
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Has been cancelled
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:36 +08:00

247 lines
5.4 KiB
Go

package postgres
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestCheckSSL(t *testing.T) {
tests := []struct {
name string
dsn string
wantErr bool
}{
{
"loopback localhost",
"postgres://user:pass@localhost:5432/db",
false,
},
{
"loopback 127.0.0.1",
"postgres://user:pass@127.0.0.1:5432/db",
false,
},
{
"loopback ::1",
"postgres://user:pass@[::1]:5432/db",
false,
},
{
"empty host defaults local",
"",
false,
},
{
"remote with require",
"postgres://u:p@remote:5432/db?sslmode=require",
false,
},
{
"remote with verify-full",
"postgres://u:p@remote:5432/db?sslmode=verify-full",
false,
},
{
"remote no sslmode",
"postgres://u:p@remote:5432/db",
true,
},
{
"remote sslmode=disable",
"postgres://u:p@remote:5432/db?sslmode=disable",
true,
},
{
"remote sslmode=prefer",
"postgres://u:p@remote:5432/db?sslmode=prefer",
true,
},
{
"remote sslmode=allow",
"postgres://u:p@remote:5432/db?sslmode=allow",
true,
},
{
"kv remote require",
"host=remote sslmode=require",
false,
},
{
"kv remote disable",
"host=remote sslmode=disable",
true,
},
{
"kv unix socket",
"host=/var/run/postgresql sslmode=disable",
false,
},
{
"uri query host disable",
"postgres:///db?host=remote&sslmode=disable",
true,
},
{
"uri query host require",
"postgres:///db?host=remote&sslmode=require",
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := CheckSSL(tt.dsn)
assert.Equal(t, tt.wantErr, err != nil, "err = %v", err)
})
}
}
func TestRedactDSN(t *testing.T) {
tests := []struct {
name string
dsn string
want string
}{
{
"strips credentials",
"postgres://user:secret@myhost:5432/db",
"myhost",
},
{
"empty dsn",
"",
"",
},
{
"invalid dsn",
"://bad",
"",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, RedactDSN(tt.dsn))
})
}
}
func TestIsLoopback(t *testing.T) {
tests := []struct {
host string
want bool
}{
{"", true},
{"localhost", true},
{"127.0.0.1", true},
{"::1", true},
{"/var/run/postgresql", true},
{"remote.host.com", false},
{"10.0.0.1", false},
}
for _, tt := range tests {
t.Run(tt.host, func(t *testing.T) {
assert.Equal(t, tt.want, isLoopback(tt.host))
})
}
}
func TestQuoteIdentifier(t *testing.T) {
tests := []struct {
name string
input string
want string
wantErr bool
}{
{"simple", "agentsview", `"agentsview"`, false},
{"underscore", "my_schema", `"my_schema"`, false},
{"empty", "", "", true},
{"has spaces", "bad schema", "", true},
{"has semicolon", "bad;drop", "", true},
{"starts with digit", "1bad", "", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := quoteIdentifier(tt.input)
assert.Equal(t, tt.wantErr, err != nil, "err = %v", err)
assert.Equal(t, tt.want, got)
})
}
}
func TestPGTargetFingerprint(t *testing.T) {
base, err := pgTargetFingerprint(
"postgres://alice:secret@db.example.com:5432/agents?sslmode=require&application_name=agentsview",
"agentsview",
)
assert.NoError(t, err)
samePasswordChanged, err := pgTargetFingerprint(
"postgres://alice:new-secret@db.example.com:5432/agents?sslmode=require&application_name=other",
"agentsview",
)
assert.NoError(t, err)
assert.Equal(t, base, samePasswordChanged)
baseWithFallback, err := pgTargetFingerprint(
"postgres://alice:secret@db.example.com:5432/agents?sslmode=require&application_name=agentsview&host=db.example.com,standby-a.example.com&port=5432,6432",
"agentsview",
)
assert.NoError(t, err)
sameFallbackNoiseChanged, err := pgTargetFingerprint(
"postgres://alice:new-secret@db.example.com:5432/agents?sslmode=require&application_name=other&host=DB.EXAMPLE.COM,standby-a.example.com&port=5432,6432",
"agentsview",
)
assert.NoError(t, err)
assert.Equal(t, baseWithFallback, sameFallbackNoiseChanged)
cases := []struct {
name string
dsn string
schema string
}{
{
name: "host change",
dsn: "postgres://alice:secret@db2.example.com:5432/agents?sslmode=require",
schema: "agentsview",
},
{
name: "database change",
dsn: "postgres://alice:secret@db.example.com:5432/agents_archive?sslmode=require",
schema: "agentsview",
},
{
name: "user change",
dsn: "postgres://bob:secret@db.example.com:5432/agents?sslmode=require",
schema: "agentsview",
},
{
name: "schema change",
dsn: "postgres://alice:secret@db.example.com:5432/agents?sslmode=require",
schema: "agentsview_alt",
},
{
name: "fallback host change",
dsn: "postgres://alice:secret@db.example.com:5432/agents?sslmode=require&host=db.example.com,standby-b.example.com&port=5432,6432",
schema: "agentsview",
},
{
name: "fallback port change",
dsn: "postgres://alice:secret@db.example.com:5432/agents?sslmode=require&host=db.example.com,standby-a.example.com&port=5432,7432",
schema: "agentsview",
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got, err := pgTargetFingerprint(tc.dsn, tc.schema)
assert.NoError(t, err)
wantDifferentFrom := base
if tc.name == "fallback host change" || tc.name == "fallback port change" {
wantDifferentFrom = baseWithFallback
}
assert.NotEqual(t, wantDifferentFrom, got)
})
}
}