Files
cloud-ip-validator/internal/db/queries_inbound_test.go
T

103 lines
3.4 KiB
Go
Raw Normal View History

package db
import (
"errors"
"reflect"
"testing"
"cloudipvalidator/internal/config"
)
func TestBootstrapInboundChecksSeedsOnceFromConfig(t *testing.T) {
d, ctx := newTestDB(t)
cfg := &config.ControlAPI{Inbound: config.InboundConfig{Ports: []int{22, 80}, ICMP: true}}
if err := d.BootstrapFromConfig(ctx, cfg); err != nil {
t.Fatalf("first bootstrap: %v", err)
}
settings, err := d.GetInboundChecks(ctx)
if err != nil {
t.Fatalf("get inbound checks: %v", err)
}
if !reflect.DeepEqual(settings.Ports, []int{22, 80}) || !settings.ICMP {
t.Fatalf("expected seeded {[22 80] true}, got %+v", settings)
}
// A second bootstrap with a different YAML value must not overwrite the
// now-non-empty table — same "DB is source of truth once seeded"
// semantics as validators/sites/targets/check_types/settings.
cfg2 := &config.ControlAPI{Inbound: config.InboundConfig{Ports: []int{443}, ICMP: false}}
if err := d.BootstrapFromConfig(ctx, cfg2); err != nil {
t.Fatalf("second bootstrap: %v", err)
}
settings, err = d.GetInboundChecks(ctx)
if err != nil {
t.Fatalf("get inbound checks after second bootstrap: %v", err)
}
if !reflect.DeepEqual(settings.Ports, []int{22, 80}) || !settings.ICMP {
t.Fatalf("expected YAML to be ignored on non-empty table, got %+v", settings)
}
}
func TestSetInboundChecksRejectsPortOutOfRange(t *testing.T) {
d, ctx := newTestDB(t)
if err := d.BootstrapFromConfig(ctx, &config.ControlAPI{}); err != nil {
t.Fatalf("bootstrap: %v", err)
}
for _, p := range []int{0, -1, 65536, 70000} {
if err := d.SetInboundChecks(ctx, []int{p}, false); !errors.Is(err, ErrValidation) {
t.Fatalf("port %d: expected ErrValidation, got %v", p, err)
}
}
}
func TestSetInboundChecksRejectsDuplicatePorts(t *testing.T) {
d, ctx := newTestDB(t)
if err := d.BootstrapFromConfig(ctx, &config.ControlAPI{}); err != nil {
t.Fatalf("bootstrap: %v", err)
}
if err := d.SetInboundChecks(ctx, []int{22, 80, 22}, false); !errors.Is(err, ErrValidation) {
t.Fatalf("expected ErrValidation for duplicate port, got %v", err)
}
}
func TestGetSetInboundChecksRoundTrip(t *testing.T) {
d, ctx := newTestDB(t)
if err := d.BootstrapFromConfig(ctx, &config.ControlAPI{}); err != nil {
t.Fatalf("bootstrap: %v", err)
}
before, err := d.GetInboundChecks(ctx)
if err != nil {
t.Fatalf("get inbound checks: %v", err)
}
if len(before.Ports) != 0 || before.ICMP {
t.Fatalf("expected default {[] false}, got %+v", before)
}
if err := d.SetInboundChecks(ctx, []int{22, 443, 8080}, true); err != nil {
t.Fatalf("set inbound checks: %v", err)
}
after, err := d.GetInboundChecks(ctx)
if err != nil {
t.Fatalf("get inbound checks after set: %v", err)
}
if !reflect.DeepEqual(after.Ports, []int{22, 443, 8080}) || !after.ICMP {
t.Fatalf("expected {[22 443 8080] true}, got %+v", after)
}
if after.UpdatedAt.Before(before.UpdatedAt) {
t.Fatalf("expected updated_at not to go backwards, before=%v after=%v", before.UpdatedAt, after.UpdatedAt)
}
// Setting an empty port list + icmp:false is legal — it's the "disable
// all inbound checks without touching sites" configuration.
if err := d.SetInboundChecks(ctx, nil, false); err != nil {
t.Fatalf("set empty inbound checks: %v", err)
}
cleared, err := d.GetInboundChecks(ctx)
if err != nil {
t.Fatalf("get inbound checks after clear: %v", err)
}
if len(cleared.Ports) != 0 || cleared.ICMP {
t.Fatalf("expected {[] false} after clearing, got %+v", cleared)
}
}