57 lines
1.6 KiB
Go
57 lines
1.6 KiB
Go
//go:build integration
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// A plan moved by a seat verb is looked at as the verb ends (issue 974, review 1): the verb runs as a child process
|
|
// whose saves the serving controller does not hear, so `deliver`, which lets a walk go after the operator's approval,
|
|
// would leave its first tier waiting for an unrelated event.
|
|
func TestAVerbThatMayMoveAPlanHasTheServingControllerLookWhenItEnds(t *testing.T) {
|
|
var looks, failures atomic.Int32
|
|
l := lookerCounting(&failures, &looks, nil)
|
|
lookerMu.Lock()
|
|
theLooker = l
|
|
lookerMu.Unlock()
|
|
t.Cleanup(func() { lookerMu.Lock(); theLooker = nil; lookerMu.Unlock() })
|
|
ctx, stop := context.WithCancel(context.Background())
|
|
defer stop()
|
|
go l.run(ctx)
|
|
|
|
was := runTheVerb
|
|
runTheVerb = func(context.Context, []string) (verbAnswer, error) { return verbAnswer{}, nil }
|
|
t.Cleanup(func() { runTheVerb = was })
|
|
handlers, _, err := seatToolHandlers()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, c := range []struct {
|
|
verb string
|
|
args string
|
|
look bool
|
|
}{
|
|
{"deliver", `{"plan":"p"}`, true},
|
|
{"plans", `{"stop":"plan-1","why":"w"}`, true},
|
|
{"plans", `{}`, false},
|
|
{"nodes", `{}`, false},
|
|
} {
|
|
before := looks.Load()
|
|
h := handlers[c.verb]
|
|
if h == nil {
|
|
t.Fatalf("no verb %s", c.verb)
|
|
}
|
|
if _, err := h(ctx, []byte(c.args)); err != nil {
|
|
t.Fatalf("%s %s: %v", c.verb, c.args, err)
|
|
}
|
|
time.Sleep(100 * time.Millisecond)
|
|
if got := looks.Load() > before; got != c.look {
|
|
t.Errorf("%s %s: look asked = %v; want %v", c.verb, c.args, got, c.look)
|
|
}
|
|
}
|
|
}
|