Run the equality test's three stores one after the other, and log where each phase starts (issue 1384)

The live try failed in 32 s: throwawayStores finds its databases by the process environment, and a store opened later finds them there too, so a second store raised at the same time took the first one's database from under it (database gate_inventory_... does not exist). The three stores are raised one after another again, each phase says when it starts, and a failed phase stops the test. The two served-fact tests log one line when they pass their key assertion.
This commit is contained in:
2026-10-20 09:58:49 +00:00
parent 9f773e0b3c
commit 7d949f888f
2 changed files with 21 additions and 16 deletions
@@ -9,7 +9,6 @@ import (
"os" "os"
"sort" "sort"
"strings" "strings"
"sync"
"testing" "testing"
"time" "time"
@@ -57,10 +56,11 @@ func TestEveryMachineComposesAlikeBothWays(t *testing.T) {
} }
sources := sourcesOfFacts(f) sources := sourcesOfFacts(f)
// Three stores, raised from the same snapshot, are three independent pieces of work and run together: (a) both ways on a // Three stores, raised from the same snapshot, one after the other: (a) both ways on a fresh store, (b) and (c) the
// fresh store, (b) and (c) the controller's sends and readings, (b) mesh-sdk's sends. // controller's sends and readings, (b) mesh-sdk's sends. They cannot run together: throwawayStores finds its databases by
// the process environment (and a store opened later finds them there too), so a second one raised at the same time takes
// the first one's connection from under it (the live try: database gate_inventory_... does not exist).
var ( var (
wg sync.WaitGroup
oldForeseen, sdkForeseen = map[string]composedBoth{}, map[string]composedBoth{} oldForeseen, sdkForeseen = map[string]composedBoth{}, map[string]composedBoth{}
foreseenPorts = map[string][]string{} foreseenPorts = map[string][]string{}
readOld, readSDK = map[string]composedBoth{}, map[string]composedBoth{} readOld, readSDK = map[string]composedBoth{}, map[string]composedBoth{}
@@ -69,9 +69,8 @@ func TestEveryMachineComposesAlikeBothWays(t *testing.T) {
sendRefused = map[string]string{} sendRefused = map[string]string{}
errA, errOld, errSDK error errA, errOld, errSDK error
) )
wg.Add(3) func() { // (a) Foreseeing on the fresh store.
go func() { // (a) Foreseeing on the fresh store. phase("(a) starts: raising a fresh store")
defer wg.Done()
fresh, drop, err := throwawayStores(ctx, admin) fresh, drop, err := throwawayStores(ctx, admin)
if err != nil { if err != nil {
errA = err errA = err
@@ -84,6 +83,7 @@ func TestEveryMachineComposesAlikeBothWays(t *testing.T) {
} }
// mesh-sdk's composition first: it writes nothing, where the controller's makes every pair credential on the way. The // mesh-sdk's composition first: it writes nothing, where the controller's makes every pair credential on the way. The
// Input is read once for all of its machines. // Input is read once for all of its machines.
phase("(a) the store is raised; mesh-sdk's Foreseeing starts")
cached := withInputCache(ctx) cached := withInputCache(ctx)
for _, m := range f.Machines { for _, m := range f.Machines {
in, err := inputFor(cached, fresh) in, err := inputFor(cached, fresh)
@@ -110,8 +110,11 @@ func TestEveryMachineComposesAlikeBothWays(t *testing.T) {
} }
phase("(a) the controller's Foreseeing of every machine") phase("(a) the controller's Foreseeing of every machine")
}() }()
go func() { // (b) and (c): the controller's send of every machine, then both ways of reading. if errA != nil {
defer wg.Done() t.Fatal(errA)
}
func() { // (b) and (c): the controller's send of every machine, then both ways of reading.
phase("(b) starts: the controller's send, raising a store")
oldStore, drop, err := throwawayStores(ctx, admin) oldStore, drop, err := throwawayStores(ctx, admin)
if err != nil { if err != nil {
errOld = err errOld = err
@@ -149,8 +152,11 @@ func TestEveryMachineComposesAlikeBothWays(t *testing.T) {
} }
phase("(c) both ways of reading every machine after the controller's send") phase("(c) both ways of reading every machine after the controller's send")
}() }()
go func() { // (b) mesh-sdk's send of every machine. if errOld != nil {
defer wg.Done() t.Fatal(errOld)
}
func() { // (b) mesh-sdk's send of every machine.
phase("(b) starts: mesh-sdk's send, raising a store")
sdkStore, drop, err := throwawayStores(ctx, admin) sdkStore, drop, err := throwawayStores(ctx, admin)
if err != nil { if err != nil {
errSDK = err errSDK = err
@@ -169,11 +175,8 @@ func TestEveryMachineComposesAlikeBothWays(t *testing.T) {
phase("(b) mesh-sdk's send of every machine") phase("(b) mesh-sdk's send of every machine")
sdkMade, errSDK = madeIn(ctx, sdkStore) sdkMade, errSDK = madeIn(ctx, sdkStore)
}() }()
wg.Wait() if errSDK != nil {
for _, err := range []error{errA, errOld, errSDK} { t.Fatal(errSDK)
if err != nil {
t.Fatal(err)
}
} }
var failures []string var failures []string
@@ -291,6 +291,7 @@ func TestAServedFactThatSaysASettingIsResolvedWithTheSettingInTheInput(t *testin
if !reflect.DeepEqual(oldPlan.Needs, newPlan.Needs) { if !reflect.DeepEqual(oldPlan.Needs, newPlan.Needs) {
t.Errorf("the consumer's needs are %+v, the controller's own %+v", newPlan.Needs, oldPlan.Needs) t.Errorf("the consumer's needs are %+v, the controller's own %+v", newPlan.Needs, oldPlan.Needs)
} }
t.Logf("a served fact that says a setting resolves with the setting in the Input: the Input builds and the consumer's needs equal planFor's")
} }
// A setting that nothing sets, in a fact a provider serves, is not the adapter's to hide: the controller's own composition // A setting that nothing sets, in a fact a provider serves, is not the adapter's to hide: the controller's own composition
@@ -324,4 +325,5 @@ func TestAServedFactThatSaysAnUnsetSettingIsRefusedAsTheControllerRefusesIt(t *t
if oldErr != nil && !strings.Contains(newErr.Error(), "nothing sets \"domain\"") { if oldErr != nil && !strings.Contains(newErr.Error(), "nothing sets \"domain\"") {
t.Errorf("the adapter's words are %q, the controller's %q", newErr, oldErr) t.Errorf("the adapter's words are %q, the controller's %q", newErr, oldErr)
} }
t.Logf("an unset setting in a served fact is refused alike: the controller says %v, the adapter says %v", oldErr != nil, newErr != nil)
} }