feat: publish standalone worker
Separate worker packaging and service lifecycle from the control plane.
Этот коммит содержится в:
94
app/models/monitor_transfer_test.go
Обычный файл
94
app/models/monitor_transfer_test.go
Обычный файл
@@ -0,0 +1,94 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/datatypes"
|
||||
|
||||
"rsgit.ru/rsmon/rsmon/app/models"
|
||||
)
|
||||
|
||||
// TestMonitorTransferGroupSwap verifies that swapping a monitor's
|
||||
// group_id between two accounts correctly re-homes the monitor without
|
||||
// touching any other monitor data. This is the database primitive that
|
||||
// POST /api/v1/monitors/:id/transfer relies on.
|
||||
func TestMonitorTransferGroupSwap(t *testing.T) {
|
||||
models.Drop()
|
||||
models.Migrate()
|
||||
|
||||
plan := models.Plan{Name: "test", Default: true}
|
||||
require.NoError(t, models.DB().Create(&plan).Error)
|
||||
|
||||
// Two accounts, each with their own default group.
|
||||
accA := models.Account{Name: "A", PlanID: &plan.ID}
|
||||
require.NoError(t, models.DB().Create(&accA).Error)
|
||||
accB := models.Account{Name: "B", PlanID: &plan.ID}
|
||||
require.NoError(t, models.DB().Create(&accB).Error)
|
||||
|
||||
groupA := models.Group{AccountID: accA.ID, Name: "A-default"}
|
||||
require.NoError(t, models.DB().Create(&groupA).Error)
|
||||
groupB := models.Group{AccountID: accB.ID, Name: "B-default"}
|
||||
require.NoError(t, models.DB().Create(&groupB).Error)
|
||||
|
||||
// Monitor lives in account A with one HTTP check.
|
||||
monitor := models.Monitor{
|
||||
GroupID: groupA.ID,
|
||||
Host: "example-a.test",
|
||||
}
|
||||
require.NoError(t, models.DB().Create(&monitor).Error)
|
||||
|
||||
check := models.Check{
|
||||
MonitorID: monitor.ID,
|
||||
Kind: "http",
|
||||
URL: ptrString("https://example-a.test/"),
|
||||
Interval: 300,
|
||||
Settings: datatypes.JSON([]byte("{}")),
|
||||
}
|
||||
require.NoError(t, models.DB().Create(&check).Error)
|
||||
|
||||
// Simulate the controller-side update.
|
||||
require.NoError(t, models.DB().
|
||||
Model(&models.Monitor{}).
|
||||
Where("id = ?", monitor.ID).
|
||||
Update("group_id", groupB.ID).Error)
|
||||
|
||||
// Monitor now lives in B; check follows by FK on monitor_id.
|
||||
var reloaded models.Monitor
|
||||
require.NoError(t, models.DB().Preload("Group").First(&reloaded, monitor.ID).Error)
|
||||
assert.Equal(t, groupB.ID, reloaded.GroupID, "monitor group_id should now point at account B's group")
|
||||
assert.Equal(t, accB.ID, reloaded.Group.AccountID, "preloaded group should belong to account B")
|
||||
|
||||
var checkCount int64
|
||||
require.NoError(t, models.DB().Model(&models.Check{}).
|
||||
Where("monitor_id = ?", monitor.ID).Count(&checkCount).Error)
|
||||
assert.Equal(t, int64(1), checkCount, "check rows must follow the monitor across the move")
|
||||
}
|
||||
|
||||
// TestMonitorTransferSameAccountGuard documents the early-return path: the
|
||||
// controller must not silently no-op when the caller picks the current
|
||||
// account, and the test exercises that the DB stays untouched.
|
||||
func TestMonitorTransferSameAccountGuard(t *testing.T) {
|
||||
models.Drop()
|
||||
models.Migrate()
|
||||
|
||||
plan := models.Plan{Name: "test", Default: true}
|
||||
require.NoError(t, models.DB().Create(&plan).Error)
|
||||
|
||||
acc := models.Account{Name: "only", PlanID: &plan.ID}
|
||||
require.NoError(t, models.DB().Create(&acc).Error)
|
||||
group := models.Group{AccountID: acc.ID, Name: "only"}
|
||||
require.NoError(t, models.DB().Create(&group).Error)
|
||||
|
||||
monitor := models.Monitor{GroupID: group.ID, Host: "x.test"}
|
||||
require.NoError(t, models.DB().Create(&monitor).Error)
|
||||
|
||||
// No update is issued because the controller rejects same-account moves
|
||||
// before the SQL UPDATE. Verify the row is unchanged.
|
||||
var reloaded models.Monitor
|
||||
require.NoError(t, models.DB().First(&reloaded, monitor.ID).Error)
|
||||
assert.Equal(t, group.ID, reloaded.GroupID)
|
||||
}
|
||||
|
||||
func ptrString(s string) *string { return &s }
|
||||
Ссылка в новой задаче
Block a user