feat: add auto update
This commit is contained in:
@ -2,6 +2,7 @@ package store
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func newTestStore(t *testing.T) *Store {
|
||||
@ -254,3 +255,199 @@ func TestCreateAgentToken_IdempotentIgnore(t *testing.T) {
|
||||
t.Fatalf("second call (should be idempotent): %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// ── AutoUpdatePolicies ────────────────────────────────────────────────────────
|
||||
|
||||
// helper: create an agent prerequisite for FK constraints.
|
||||
func createAgent(t *testing.T, s *Store, id, token, hostname string) {
|
||||
t.Helper()
|
||||
if err := s.CreateAgentToken(id, token, hostname); err != nil {
|
||||
t.Fatalf("createAgent: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpsertAndGetAutoUpdatePolicy(t *testing.T) {
|
||||
s := newTestStore(t)
|
||||
createAgent(t, s, "ag1", "tok1", "host1")
|
||||
|
||||
p := &AutoUpdatePolicy{
|
||||
AgentID: "ag1",
|
||||
ContainerID: "ctr1",
|
||||
Enabled: true,
|
||||
IntervalMinutes: 60,
|
||||
}
|
||||
if err := s.UpsertAutoUpdatePolicy(p); err != nil {
|
||||
t.Fatalf("UpsertAutoUpdatePolicy: %v", err)
|
||||
}
|
||||
|
||||
got, err := s.GetAutoUpdatePolicy("ag1", "ctr1")
|
||||
if err != nil {
|
||||
t.Fatalf("GetAutoUpdatePolicy: %v", err)
|
||||
}
|
||||
if got == nil {
|
||||
t.Fatal("expected policy, got nil")
|
||||
}
|
||||
if !got.Enabled || got.IntervalMinutes != 60 {
|
||||
t.Errorf("unexpected policy: %+v", got)
|
||||
}
|
||||
if got.LastCheckedAt != nil || got.LastUpdatedAt != nil {
|
||||
t.Error("expected nil timestamps on fresh policy")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAutoUpdatePolicy_NotFound(t *testing.T) {
|
||||
s := newTestStore(t)
|
||||
|
||||
p, err := s.GetAutoUpdatePolicy("nobody", "ctr")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if p != nil {
|
||||
t.Errorf("expected nil, got %+v", p)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpsertAutoUpdatePolicy_Update(t *testing.T) {
|
||||
s := newTestStore(t)
|
||||
createAgent(t, s, "ag1", "tok1", "host1")
|
||||
|
||||
_ = s.UpsertAutoUpdatePolicy(&AutoUpdatePolicy{AgentID: "ag1", ContainerID: "ctr1", Enabled: true, IntervalMinutes: 60})
|
||||
_ = s.UpsertAutoUpdatePolicy(&AutoUpdatePolicy{AgentID: "ag1", ContainerID: "ctr1", Enabled: false, IntervalMinutes: 1440})
|
||||
|
||||
got, err := s.GetAutoUpdatePolicy("ag1", "ctr1")
|
||||
if err != nil {
|
||||
t.Fatalf("GetAutoUpdatePolicy: %v", err)
|
||||
}
|
||||
if got.Enabled || got.IntervalMinutes != 1440 {
|
||||
t.Errorf("expected updated policy, got %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateAutoUpdateChecked(t *testing.T) {
|
||||
s := newTestStore(t)
|
||||
createAgent(t, s, "ag1", "tok1", "host1")
|
||||
_ = s.UpsertAutoUpdatePolicy(&AutoUpdatePolicy{AgentID: "ag1", ContainerID: "ctr1", Enabled: true, IntervalMinutes: 60})
|
||||
|
||||
now := time.Now().Truncate(time.Second)
|
||||
if err := s.UpdateAutoUpdateChecked("ag1", "ctr1", now); err != nil {
|
||||
t.Fatalf("UpdateAutoUpdateChecked: %v", err)
|
||||
}
|
||||
|
||||
got, _ := s.GetAutoUpdatePolicy("ag1", "ctr1")
|
||||
if got.LastCheckedAt == nil {
|
||||
t.Fatal("expected LastCheckedAt to be set")
|
||||
}
|
||||
if got.LastCheckedAt.UTC().Truncate(time.Second) != now.UTC() {
|
||||
t.Errorf("expected %v, got %v", now.UTC(), got.LastCheckedAt.UTC().Truncate(time.Second))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateAutoUpdateDone(t *testing.T) {
|
||||
s := newTestStore(t)
|
||||
createAgent(t, s, "ag1", "tok1", "host1")
|
||||
_ = s.UpsertAutoUpdatePolicy(&AutoUpdatePolicy{AgentID: "ag1", ContainerID: "ctr1", Enabled: true, IntervalMinutes: 60})
|
||||
|
||||
now := time.Now().Truncate(time.Second)
|
||||
if err := s.UpdateAutoUpdateDone("ag1", "ctr1", now); err != nil {
|
||||
t.Fatalf("UpdateAutoUpdateDone: %v", err)
|
||||
}
|
||||
|
||||
got, _ := s.GetAutoUpdatePolicy("ag1", "ctr1")
|
||||
if got.LastUpdatedAt == nil {
|
||||
t.Fatal("expected LastUpdatedAt to be set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListDueAutoUpdatePolicies_NullLastChecked(t *testing.T) {
|
||||
s := newTestStore(t)
|
||||
createAgent(t, s, "ag1", "tok1", "host1")
|
||||
_ = s.UpsertAutoUpdatePolicy(&AutoUpdatePolicy{AgentID: "ag1", ContainerID: "ctr1", Enabled: true, IntervalMinutes: 60})
|
||||
|
||||
// last_checked_at IS NULL → should be due immediately.
|
||||
due, err := s.ListDueAutoUpdatePolicies(time.Now())
|
||||
if err != nil {
|
||||
t.Fatalf("ListDueAutoUpdatePolicies: %v", err)
|
||||
}
|
||||
if len(due) != 1 {
|
||||
t.Fatalf("expected 1 due policy, got %d", len(due))
|
||||
}
|
||||
if due[0].ContainerID != "ctr1" {
|
||||
t.Errorf("unexpected container: %q", due[0].ContainerID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListDueAutoUpdatePolicies_NotDueYet(t *testing.T) {
|
||||
s := newTestStore(t)
|
||||
createAgent(t, s, "ag1", "tok1", "host1")
|
||||
_ = s.UpsertAutoUpdatePolicy(&AutoUpdatePolicy{AgentID: "ag1", ContainerID: "ctr1", Enabled: true, IntervalMinutes: 1440})
|
||||
|
||||
// Mark as just checked — not due yet.
|
||||
_ = s.UpdateAutoUpdateChecked("ag1", "ctr1", time.Now())
|
||||
|
||||
due, err := s.ListDueAutoUpdatePolicies(time.Now())
|
||||
if err != nil {
|
||||
t.Fatalf("ListDueAutoUpdatePolicies: %v", err)
|
||||
}
|
||||
if len(due) != 0 {
|
||||
t.Fatalf("expected 0 due policies (just checked), got %d", len(due))
|
||||
}
|
||||
}
|
||||
|
||||
func TestListDueAutoUpdatePolicies_Due(t *testing.T) {
|
||||
s := newTestStore(t)
|
||||
createAgent(t, s, "ag1", "tok1", "host1")
|
||||
_ = s.UpsertAutoUpdatePolicy(&AutoUpdatePolicy{AgentID: "ag1", ContainerID: "ctr1", Enabled: true, IntervalMinutes: 60})
|
||||
|
||||
// Simulate last check 2 hours ago → should be due.
|
||||
past := time.Now().Add(-2 * time.Hour)
|
||||
_ = s.UpdateAutoUpdateChecked("ag1", "ctr1", past)
|
||||
|
||||
due, err := s.ListDueAutoUpdatePolicies(time.Now())
|
||||
if err != nil {
|
||||
t.Fatalf("ListDueAutoUpdatePolicies: %v", err)
|
||||
}
|
||||
if len(due) != 1 {
|
||||
t.Fatalf("expected 1 due policy (overdue), got %d", len(due))
|
||||
}
|
||||
}
|
||||
|
||||
func TestListDueAutoUpdatePolicies_DisabledExcluded(t *testing.T) {
|
||||
s := newTestStore(t)
|
||||
createAgent(t, s, "ag1", "tok1", "host1")
|
||||
_ = s.UpsertAutoUpdatePolicy(&AutoUpdatePolicy{AgentID: "ag1", ContainerID: "ctr1", Enabled: false, IntervalMinutes: 60})
|
||||
|
||||
due, err := s.ListDueAutoUpdatePolicies(time.Now())
|
||||
if err != nil {
|
||||
t.Fatalf("ListDueAutoUpdatePolicies: %v", err)
|
||||
}
|
||||
if len(due) != 0 {
|
||||
t.Fatalf("expected 0 due policies (disabled), got %d", len(due))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteAutoUpdatePolicy(t *testing.T) {
|
||||
s := newTestStore(t)
|
||||
createAgent(t, s, "ag1", "tok1", "host1")
|
||||
_ = s.UpsertAutoUpdatePolicy(&AutoUpdatePolicy{AgentID: "ag1", ContainerID: "ctr1", Enabled: true, IntervalMinutes: 60})
|
||||
|
||||
if err := s.DeleteAutoUpdatePolicy("ag1", "ctr1"); err != nil {
|
||||
t.Fatalf("DeleteAutoUpdatePolicy: %v", err)
|
||||
}
|
||||
|
||||
got, err := s.GetAutoUpdatePolicy("ag1", "ctr1")
|
||||
if err != nil {
|
||||
t.Fatalf("GetAutoUpdatePolicy: %v", err)
|
||||
}
|
||||
if got != nil {
|
||||
t.Error("expected nil after deletion")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteAutoUpdatePolicy_Idempotent(t *testing.T) {
|
||||
s := newTestStore(t)
|
||||
|
||||
// Deleting a non-existent policy should not error.
|
||||
if err := s.DeleteAutoUpdatePolicy("nobody", "ctr"); err != nil {
|
||||
t.Fatalf("DeleteAutoUpdatePolicy on missing: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user