93 lines
3.1 KiB
Go
93 lines
3.1 KiB
Go
//go:build integration
|
|
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestAnUnassignThatLeavesItsNodeUnresolvedSaysSoOnceInItsAnswer(t *testing.T) {
|
|
open := aMesh(t)
|
|
ctx := t.Context()
|
|
twoRivalsAndANote(t, open)
|
|
// Straight into the store, as a node that came to this before the act.
|
|
for _, m := range []string{"rival-one", "rival-two", "notes"} {
|
|
if _, err := open.inventory.Assign(ctx, "laptop", m); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
said := answered(t, func() error { return assignCommand(ctx, "unassign", []string{"laptop", "notes"}) })
|
|
|
|
if _, _, err := planFor(ctx, open, "laptop"); err == nil || !unresolvable(err) {
|
|
t.Fatalf("laptop resolves with two claimants of one seat: %v", err)
|
|
}
|
|
if n := strings.Count(said, "laptop does not resolve now"); n != 1 {
|
|
t.Errorf("the answer says laptop does not resolve %d times, want once:\n%s", n, said)
|
|
}
|
|
if strings.Contains(said, "is left out of the rest of the mesh") {
|
|
t.Errorf("the answer carries a line from a read that is not its resolution:\n%s", said)
|
|
}
|
|
}
|
|
|
|
func TestAnUnassignThatLeavesItsNodeResolvedSaysNothingOfIt(t *testing.T) {
|
|
open := aMesh(t)
|
|
ctx := t.Context()
|
|
aProviderAndItsConsumer(t, open)
|
|
if _, err := assign(ctx, open, "laptop", "db", "app"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
said, err := unassign(ctx, open, "laptop", "app")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, _, err := planFor(ctx, open, "laptop"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if strings.Contains(said, "does not resolve") || strings.Contains(said, "could not be read") {
|
|
t.Errorf("a node that resolves is said not to:\n%s", said)
|
|
}
|
|
}
|
|
|
|
func TestAnAssignThatLeavesItsNodeUnresolvedSaysOnlyThePlansRefusal(t *testing.T) {
|
|
open := aMesh(t)
|
|
ctx := t.Context()
|
|
twoRivalsAndANote(t, open)
|
|
if _, err := assign(ctx, open, "laptop", "rival-one"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Kept and not resolvable: a second claimant of the seat, which assignment keeps.
|
|
said, err := assign(ctx, open, "laptop", "rival-two")
|
|
if err == nil {
|
|
t.Fatalf("two claimants of one node seat resolved:\n%s", said)
|
|
}
|
|
_, _, planErr := planFor(ctx, open, "laptop")
|
|
if planErr == nil || planErr.Error() != err.Error() {
|
|
t.Errorf("the act's refusal is not the plan's right after:\nact: %v\nplan: %v", err, planErr)
|
|
}
|
|
if strings.Contains(said, "now has") {
|
|
t.Errorf("the answer says a seat is now held on a node that does not resolve:\n%s", said)
|
|
}
|
|
}
|
|
|
|
// The other readers of the whole mesh still say a machine they leave out, on standard error (novox/hq
|
|
// issue 188); an act sends it elsewhere.
|
|
func TestAMachineLeftOutIsSaidWhereTheContextSays(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
sayLeftOut(leftOutSaidBy(context.Background(), &buf), "laptop", errors.New("why"))
|
|
if buf.String() != "laptop is left out of the rest of the mesh: it does not resolve: why\n" {
|
|
t.Errorf("said %q", buf.String())
|
|
}
|
|
got := answered(t, func() error {
|
|
sayLeftOut(context.Background(), "laptop", errors.New("why"))
|
|
return nil
|
|
})
|
|
if !strings.Contains(got, "laptop is left out") {
|
|
t.Errorf("without an act's writer the line did not reach standard error: %q", got)
|
|
}
|
|
}
|