feat: publish standalone worker
Separate worker packaging and service lifecycle from the control plane.
Этот коммит содержится в:
114
app/models/rkn_ip_test.go
Обычный файл
114
app/models/rkn_ip_test.go
Обычный файл
@@ -0,0 +1,114 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"rsgit.ru/rsmon/rsmon/app/models"
|
||||
)
|
||||
|
||||
func mustIPNet(t *testing.T, cidr string) *net.IPNet {
|
||||
t.Helper()
|
||||
_, n, err := net.ParseCIDR(cidr)
|
||||
require.NoError(t, err)
|
||||
return n
|
||||
}
|
||||
|
||||
func TestReplaceRknIPs_BulkAndDedup(t *testing.T) {
|
||||
models.Drop()
|
||||
models.Migrate()
|
||||
|
||||
input := []*net.IPNet{
|
||||
mustIPNet(t, "10.0.0.0/8"),
|
||||
mustIPNet(t, "10.5.0.0/8"), // same canonical /8 — dedup
|
||||
mustIPNet(t, "192.168.1.0/24"),
|
||||
mustIPNet(t, "2001:db8::/32"),
|
||||
}
|
||||
require.NoError(t, models.ReplaceRknIPs(input))
|
||||
|
||||
// The uniqueIndex on rkn_ips.network ensures the dedup actually drops
|
||||
// duplicates; ReplaceRknIPs does an in-memory dedup, but the DB-level
|
||||
// constraint is the guarantee.
|
||||
var count int64
|
||||
assert.NoError(t, models.DB().Model(&models.RknIP{}).Count(&count).Error)
|
||||
assert.Equal(t, int64(3), count, "expected dedup to 3 unique CIDRs")
|
||||
}
|
||||
|
||||
func TestReplaceRknIPs_ReplacesExisting(t *testing.T) {
|
||||
models.Drop()
|
||||
models.Migrate()
|
||||
|
||||
require.NoError(t, models.ReplaceRknIPs([]*net.IPNet{
|
||||
mustIPNet(t, "8.8.8.0/24"),
|
||||
}))
|
||||
|
||||
var n int64
|
||||
assert.NoError(t, models.DB().Model(&models.RknIP{}).Count(&n).Error)
|
||||
assert.Equal(t, int64(1), n)
|
||||
|
||||
require.NoError(t, models.ReplaceRknIPs([]*net.IPNet{
|
||||
mustIPNet(t, "1.0.0.0/8"),
|
||||
mustIPNet(t, "2.0.0.0/8"),
|
||||
}))
|
||||
|
||||
assert.NoError(t, models.DB().Model(&models.RknIP{}).Count(&n).Error)
|
||||
assert.Equal(t, int64(2), n)
|
||||
}
|
||||
|
||||
func TestIsRknIPBlocked(t *testing.T) {
|
||||
models.Drop()
|
||||
models.Migrate()
|
||||
|
||||
require.NoError(t, models.ReplaceRknIPs([]*net.IPNet{
|
||||
mustIPNet(t, "10.0.0.0/8"),
|
||||
mustIPNet(t, "192.168.1.0/24"),
|
||||
mustIPNet(t, "2001:db8::/32"),
|
||||
}))
|
||||
|
||||
cases := []struct {
|
||||
ip string
|
||||
want bool
|
||||
}{
|
||||
{"10.5.7.9", true},
|
||||
{"10.255.255.255", true},
|
||||
{"192.168.1.42", true},
|
||||
{"11.0.0.1", false},
|
||||
{"8.8.8.8", false},
|
||||
{"2001:db8::1", true},
|
||||
{"2001:db9::1", false},
|
||||
{"", false},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.ip, func(t *testing.T) {
|
||||
got, err := models.IsRknIPBlocked(c.ip)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, c.want, got, "ip=%s", c.ip)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureRknIndexes_Idempotent(t *testing.T) {
|
||||
// Calling EnsureRknIndexes twice must not error — it's used both by
|
||||
// Migrate() and could be called from boot scripts.
|
||||
models.Drop()
|
||||
models.Migrate()
|
||||
|
||||
require.NoError(t, models.EnsureRknIndexes())
|
||||
require.NoError(t, models.EnsureRknIndexes())
|
||||
|
||||
// GiST index must exist on rkn_ips.network.
|
||||
var exists bool
|
||||
err := models.DB().Raw(`
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM pg_indexes
|
||||
WHERE schemaname='public' AND tablename='rkn_ips'
|
||||
AND indexname='idx_rkn_ips_network'
|
||||
)
|
||||
`).Scan(&exists).Error
|
||||
require.NoError(t, err)
|
||||
assert.True(t, exists, "idx_rkn_ips_network must exist")
|
||||
}
|
||||
Ссылка в новой задаче
Block a user