Grants first could hold back the very declaration that lets the controller issue them. The holder now goes first, then buckets and memberships, then the rest; a membership that fails holds back only its own machine, and an announcement whose send stopped at its grants is asked again. Whether the holder must go first is read from a digest of the user list it was last sent, not its whole declaration. Migration renumbered to 0058.
46 lines
1.4 KiB
Go
46 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// A cascade round gives its hold back on every way out: a declaration that cannot be marshalled
|
|
// and a send that fails leave nobody waiting for the node.
|
|
func TestASendRoundGivesItsHoldBackOnEveryWayOut(t *testing.T) {
|
|
open := aMesh(t)
|
|
ctx := t.Context()
|
|
unmarshallable := func(context.Context, string) (sendable, error) {
|
|
return sendable{Resources: []map[string]any{{"id": "x", "bad": make(chan int)}}}, nil
|
|
}
|
|
plain := func(context.Context, string) (sendable, error) {
|
|
return sendable{Resources: []map[string]any{{"id": "x"}}}, nil
|
|
}
|
|
failing := &recordingDelivery{declareErr: errors.New("the broker went away")}
|
|
fine := &recordingDelivery{}
|
|
|
|
for name, round := range map[string]func() error{
|
|
"a body that cannot be marshalled": func() error {
|
|
_, err := sendRound(ctx, open, []string{"anchor"}, unmarshallable, fine, "")
|
|
return err
|
|
},
|
|
"a send that fails": func() error {
|
|
_, err := sendRound(ctx, open, []string{"anchor"}, plain, failing, "")
|
|
return err
|
|
},
|
|
} {
|
|
if err := round(); err == nil {
|
|
t.Fatalf("%s was not an error", name)
|
|
}
|
|
waiting, cancel := context.WithTimeout(ctx, 2*time.Second)
|
|
release, err := open.inventory.HoldNodes(waiting, []string{"anchor"})
|
|
cancel()
|
|
if err != nil {
|
|
t.Fatalf("after %s the node is still held: %v", name, err)
|
|
}
|
|
release()
|
|
}
|
|
}
|