@@ -16,6 +16,7 @@ import (
1616 "testing"
1717 "time"
1818
19+ "github.com/actordock/actordock/internal/signals"
1920 "github.com/actordock/actordock/internal/types"
2021)
2122
@@ -372,6 +373,86 @@ func (h *Harness) FetchMetrics(ctx context.Context) string {
372373 return string (raw )
373374}
374375
376+ func (h * Harness ) ListSandboxSignals (ctx context.Context ) []signals.SandboxSignals {
377+ h .t .Helper ()
378+ var list []signals.SandboxSignals
379+ h .DoJSON (ctx , http .MethodGet , "/v1/signals/sandboxes" , nil , & list )
380+ return list
381+ }
382+
383+ func (h * Harness ) GetSandboxSignals (ctx context.Context , id string ) signals.SandboxSignals {
384+ h .t .Helper ()
385+ var sig signals.SandboxSignals
386+ h .DoJSON (ctx , http .MethodGet , "/v1/signals/sandboxes/" + id , nil , & sig )
387+ return sig
388+ }
389+
390+ func (h * Harness ) ListWorkerSignals (ctx context.Context ) []signals.WorkerResource {
391+ h .t .Helper ()
392+ var list []signals.WorkerResource
393+ h .DoJSON (ctx , http .MethodGet , "/v1/signals/workers" , nil , & list )
394+ return list
395+ }
396+
397+ // WaitPositiveResourceSignals polls until sandboxID and its worker have all
398+ // numeric resource-plugin metrics > 0 (and healthy / timestamps set).
399+ func (h * Harness ) WaitPositiveResourceSignals (ctx context.Context , sandboxID , workerID string , timeout time.Duration ) {
400+ h .t .Helper ()
401+ deadline := time .Now ().Add (timeout )
402+ var lastSB signals.SandboxSignals
403+ var lastW signals.WorkerResource
404+ for time .Now ().Before (deadline ) {
405+ okSB , okW := false , false
406+ for _ , sig := range h .ListSandboxSignals (ctx ) {
407+ if sig .SandboxID == sandboxID {
408+ lastSB = sig
409+ okSB = sandboxSignalsAllPositive (sig )
410+ break
411+ }
412+ }
413+ for _ , w := range h .ListWorkerSignals (ctx ) {
414+ if w .WorkerID == workerID {
415+ lastW = w
416+ okW = workerSignalsAllPositive (w )
417+ break
418+ }
419+ }
420+ if okSB && okW {
421+ return
422+ }
423+ time .Sleep (time .Second )
424+ }
425+ h .t .Fatalf ("timeout waiting for positive resource signals\n sandbox=%+v\n worker=%+v" , lastSB , lastW )
426+ }
427+
428+ func sandboxSignalsAllPositive (sig signals.SandboxSignals ) bool {
429+ rt := sig .Runtime
430+ snap := sig .Snapshot
431+ return rt .CPUUtil > 0 &&
432+ rt .MemRSSBytes > 0 &&
433+ ! rt .LastActiveAt .IsZero () &&
434+ snap .LastCheckpointBytes > 0 &&
435+ snap .LastPreemptCostSec > 0 &&
436+ ! snap .LastCheckpointAt .IsZero () &&
437+ snap .LastCheckpointDur > 0 &&
438+ ! snap .LastRestoreAt .IsZero () &&
439+ snap .LastRestoreDur > 0 &&
440+ sig .KeepAliveH > 0 &&
441+ ! sig .ReportedAt .IsZero () &&
442+ sig .WorkerID != ""
443+ }
444+
445+ func workerSignalsAllPositive (w signals.WorkerResource ) bool {
446+ return w .WorkerID != "" &&
447+ w .MaxSlots > 0 &&
448+ w .UsedSlots > 0 &&
449+ w .Healthy &&
450+ w .CPUUtil > 0 &&
451+ w .MemUtil > 0 &&
452+ w .MemBytes > 0 &&
453+ ! w .ReportedAt .IsZero ()
454+ }
455+
375456func EnvOr (k , def string ) string {
376457 if v := os .Getenv (k ); v != "" {
377458 return v
0 commit comments