119 lines
4.3 KiB
Go
119 lines
4.3 KiB
Go
//go:build integration
|
|
|
|
package link_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
"github.com/novox/mesh-controller/internal/link"
|
|
)
|
|
|
|
func anOrderedMachine(t *testing.T) (*inventory.Inventory, link.Enrolment, string) {
|
|
t.Helper()
|
|
inv := inventory.ForTest(t)
|
|
node, err := inv.AddNode(context.Background(), "home-server")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return inv, link.Enrolment{Inventory: inv}, node.ID
|
|
}
|
|
|
|
func TestAnAccountOfAnOlderDeclarationIsRefusedByItsSequence(t *testing.T) {
|
|
inv, heard, id := anOrderedMachine(t)
|
|
ctx := context.Background()
|
|
before := countFor(link.WriterNodeEngine("home-server"))
|
|
if _, err := heard.Heard(ctx, ordered("d12", 57, 12, 41, "a", "b")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := heard.Heard(ctx, ordered("d11", 57, 11, 40, "a")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
doing, _, err := inv.DoingOf(ctx, "home-server")
|
|
if err != nil || doing.Declared != "d12" || doing.Applied != 2 {
|
|
t.Fatalf("the older account replaced the newer: %+v (%v)", doing, err)
|
|
}
|
|
if got := countFor(link.WriterNodeEngine("home-server")) - before; got != 1 {
|
|
t.Fatalf("the refusal was counted %d times, want once", got)
|
|
}
|
|
kept, err := inv.KeptOrder(ctx, id)
|
|
if err != nil || kept != (inventory.ReportOrder{Epoch: 57, Sequence: 12, ReportSequence: 41}) {
|
|
t.Fatalf("the order kept is %+v (%v)", kept, err)
|
|
}
|
|
}
|
|
|
|
func TestAnOlderReportOfTheSameDeclarationIsRefused(t *testing.T) {
|
|
inv, heard, _ := anOrderedMachine(t)
|
|
ctx := context.Background()
|
|
if _, err := heard.Heard(ctx, ordered("d12", 57, 12, 41, "a", "b")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
failed := ordered("d12", 57, 12, 40)
|
|
failed.Failed = map[string]string{"b": "it failed a moment before it applied"}
|
|
if _, err := heard.Heard(ctx, failed); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
doing, _, _ := inv.DoingOf(ctx, "home-server")
|
|
if doing.Outcome != inventory.OutcomeApplied {
|
|
t.Fatalf("an older report of the same declaration replaced the newer: %+v", doing)
|
|
}
|
|
// A newer report of it — the next reconcile — is kept.
|
|
again := ordered("d12", 57, 12, 42)
|
|
again.Failed = map[string]string{"b": "it failed since"}
|
|
if _, err := heard.Heard(ctx, again); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if doing, _, _ := inv.DoingOf(ctx, "home-server"); doing.Outcome != inventory.OutcomeFailed {
|
|
t.Fatalf("a newer report of the same declaration was not kept: %+v", doing)
|
|
}
|
|
}
|
|
|
|
func TestAnOrderedAccountIsNotJudgedByTheDigestSent(t *testing.T) {
|
|
inv, heard, id := anOrderedMachine(t)
|
|
ctx := context.Background()
|
|
if err := inv.RecordSent(ctx, id, "d13", nil); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := heard.Heard(ctx, ordered("d12", 57, 12, 41, "a")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if doing, said, _ := inv.DoingOf(ctx, "home-server"); !said || doing.Declared != "d12" {
|
|
t.Fatalf("the newest account the machine gave was set aside by the digest: %+v", doing)
|
|
}
|
|
// And the machine reads an epoch: it orders its reports.
|
|
if reads, err := inv.ReadsEpoch(ctx, id); err != nil || !reads {
|
|
t.Fatalf("a machine whose reports carry a report sequence is not recorded as reading an epoch: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestAnUnorderedAccountClearsTheOrderAndTheEpoch(t *testing.T) {
|
|
inv, heard, id := anOrderedMachine(t)
|
|
ctx := context.Background()
|
|
if _, err := heard.Heard(ctx, ordered("d12", 57, 12, 41, "a")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := inv.RecordSent(ctx, id, "d13", nil); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := heard.Heard(ctx, link.Report{Node: "home-server", Declared: "d13", Applied: []string{"a", "b"}}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if doing, _, _ := inv.DoingOf(ctx, "home-server"); doing.Declared != "d13" {
|
|
t.Fatalf("an older node-engine's account of what was sent was not kept: %+v", doing)
|
|
}
|
|
if kept, _ := inv.KeptOrder(ctx, id); kept != (inventory.ReportOrder{}) {
|
|
t.Fatalf("an unordered account left the order kept: %+v", kept)
|
|
}
|
|
if reads, _ := inv.ReadsEpoch(ctx, id); reads {
|
|
t.Fatal("a node-engine that orders nothing is still sent an epoch")
|
|
}
|
|
// The next ordered account, whatever its numbers, has nothing to be older than.
|
|
if _, err := heard.Heard(ctx, ordered("d14", 58, 14, 1, "a")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if doing, _, _ := inv.DoingOf(ctx, "home-server"); doing.Declared != "d14" {
|
|
t.Fatalf("the first ordered account after an unordered one was refused: %+v", doing)
|
|
}
|
|
}
|