First Commit
ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
web / web (push) Waiting to run
docs / links (push) Canceled after 0s
detections / detections (push) Canceled after 0s

This commit is contained in:
dela
2026-10-09 08:38:16 +08:00
commit 0335d572de
756 changed files with 201663 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
package server
import (
"fmt"
"sync"
"testing"
)
func TestTaskLifecycleSnapshotCopiesContextSlices(t *testing.T) {
task := &Task{
Status: "running",
SourceTaskIDs: []int64{11, 12},
CompanyIDs: []int64{21, 22},
}
snapshot := task.lifecycleSnapshot()
snapshot.SourceTaskIDs[0] = 99
snapshot.CompanyIDs[0] = 98
fresh := task.lifecycleSnapshot()
if got := fresh.SourceTaskIDs[0]; got != 11 {
t.Fatalf("snapshot source IDs alias task storage: got %d", got)
}
if got := fresh.CompanyIDs[0]; got != 21 {
t.Fatalf("snapshot company IDs alias task storage: got %d", got)
}
sources := []int64{31, 32}
companies := []int64{41, 42}
task.updateLifecycle(func(state *taskLifecycleState) {
state.SourceTaskIDs = sources
state.CompanyIDs = companies
})
sources[0] = 97
companies[0] = 96
fresh = task.lifecycleSnapshot()
if got := fresh.SourceTaskIDs[0]; got != 31 {
t.Fatalf("lifecycle update retained caller source slice: got %d", got)
}
if got := fresh.CompanyIDs[0]; got != 41 {
t.Fatalf("lifecycle update retained caller company slice: got %d", got)
}
}
func TestTaskLifecycleSnapshotConcurrentConsistency(t *testing.T) {
task := &Task{}
writeState := func(generation int64, queued bool) {
task.updateLifecycle(func(state *taskLifecycleState) {
state.Status = map[bool]string{true: "queued", false: "paused"}[queued]
state.Queued = queued
state.Paused = !queued
state.QueuedAt = generation
state.QueueMode = map[bool]string{true: "resume", false: "bootstrap"}[queued]
state.CompletedAt = generation
state.FirstRunAt = generation
state.DeadlineAt = generation
state.SourceTaskIDs = []int64{generation, generation + 1}
state.CompanyIDs = []int64{generation, generation + 1}
})
}
writeState(1, true)
var wg sync.WaitGroup
for writer := 0; writer < 4; writer++ {
writer := writer
wg.Add(1)
go func() {
defer wg.Done()
for i := 1; i <= 1000; i++ {
generation := int64(writer*1000 + i)
writeState(generation, generation%2 == 0)
}
}()
}
errCh := make(chan error, 4)
for reader := 0; reader < 4; reader++ {
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 1000; i++ {
state := task.lifecycleSnapshot()
if state.Queued == state.Paused {
errCh <- fmt.Errorf("queued=%v paused=%v", state.Queued, state.Paused)
return
}
wantStatus := map[bool]string{true: "queued", false: "paused"}[state.Queued]
wantMode := map[bool]string{true: "resume", false: "bootstrap"}[state.Queued]
if state.Status != wantStatus || state.QueueMode != wantMode {
errCh <- fmt.Errorf("inconsistent status/mode: %+v", state)
return
}
generation := state.QueuedAt
if state.CompletedAt != generation || state.FirstRunAt != generation || state.DeadlineAt != generation ||
len(state.SourceTaskIDs) != 2 || len(state.CompanyIDs) != 2 ||
state.SourceTaskIDs[0] != generation || state.CompanyIDs[0] != generation {
errCh <- fmt.Errorf("mixed lifecycle snapshot: %+v", state)
return
}
}
}()
}
wg.Wait()
close(errCh)
for err := range errCh {
t.Fatal(err)
}
}