coverage: medium batch — hostnat runner, store guest-sessions, daemon helpers
Reuses existing fixtures (CommandRunner fakes, SQLite tempfile store, pure-Go seams). No new infra needed. hostnat 50% -> 98% (iptables orchestration via fake runner) store 78% -> 91% (guest_sessions CRUD roundtrip) daemon/session 57% -> 95% (script gen, state parse, snapshot apply) daemon/opstate 67% -> 100% (Registry Insert/Get/Prune) daemon (firstNonEmpty) slight bump Total 54.0% -> 56.5%.
This commit is contained in:
parent
f8979de58a
commit
346eaba673
5 changed files with 1010 additions and 0 deletions
74
internal/daemon/opstate/registry_test.go
Normal file
74
internal/daemon/opstate/registry_test.go
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
package opstate
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type fakeOp struct {
|
||||
id string
|
||||
done atomic.Bool
|
||||
updatedAt time.Time
|
||||
canceled atomic.Bool
|
||||
}
|
||||
|
||||
func (f *fakeOp) ID() string { return f.id }
|
||||
func (f *fakeOp) IsDone() bool { return f.done.Load() }
|
||||
func (f *fakeOp) UpdatedAt() time.Time { return f.updatedAt }
|
||||
func (f *fakeOp) Cancel() { f.canceled.Store(true) }
|
||||
|
||||
func TestRegistryInsertAndGet(t *testing.T) {
|
||||
var r Registry[*fakeOp]
|
||||
op := &fakeOp{id: "op-1", updatedAt: time.Now()}
|
||||
r.Insert(op)
|
||||
got, ok := r.Get("op-1")
|
||||
if !ok {
|
||||
t.Fatal("Get after Insert missed")
|
||||
}
|
||||
if got.ID() != "op-1" {
|
||||
t.Fatalf("Get().ID = %q", got.ID())
|
||||
}
|
||||
|
||||
_, ok = r.Get("missing")
|
||||
if ok {
|
||||
t.Fatal("Get on missing key should miss")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegistryPruneDropsCompletedOldOps(t *testing.T) {
|
||||
var r Registry[*fakeOp]
|
||||
now := time.Now()
|
||||
|
||||
recent := &fakeOp{id: "recent", updatedAt: now}
|
||||
recent.done.Store(true)
|
||||
|
||||
stale := &fakeOp{id: "stale", updatedAt: now.Add(-time.Hour)}
|
||||
stale.done.Store(true)
|
||||
|
||||
pending := &fakeOp{id: "pending", updatedAt: now.Add(-time.Hour)}
|
||||
// NOT done → stays even though old.
|
||||
|
||||
r.Insert(recent)
|
||||
r.Insert(stale)
|
||||
r.Insert(pending)
|
||||
|
||||
cutoff := now.Add(-time.Minute)
|
||||
r.Prune(cutoff)
|
||||
|
||||
if _, ok := r.Get("stale"); ok {
|
||||
t.Error("stale op should have been pruned")
|
||||
}
|
||||
if _, ok := r.Get("recent"); !ok {
|
||||
t.Error("recent op should survive (newer than cutoff)")
|
||||
}
|
||||
if _, ok := r.Get("pending"); !ok {
|
||||
t.Error("pending op should survive (not done)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegistryPruneNoOpOnEmpty(t *testing.T) {
|
||||
var r Registry[*fakeOp]
|
||||
// Just shouldn't panic.
|
||||
r.Prune(time.Now())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue