A provider whose wait fails the check raises unhealthy, but the holding read its stored statement with the wait unchecked: sayWaiters built the needs-operator key, found it not open and listed no held consumer. The holding now reads each statement as judged (ADR 0283 decision 3), in sayWaiters and in the provider's state its consumers are held by.
67 lines
3.5 KiB
Go
67 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/novox/mesh-controller/internal/conditions"
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
"github.com/novox/mesh-controller/internal/link"
|
|
)
|
|
|
|
// A provider whose wait fails the controller's check lists who waits on it (novox/hq issue 450).
|
|
//
|
|
// A wait that does not check out is judged unhealthy (ADR 0283 decision 3), so the provider raises its unhealthy
|
|
// condition and its consumers are held under it (ADR 0240 rule 5). What is stored is what the machine said, the
|
|
// wait unchecked: read as said, the provider seems to wait for the operator, and the held consumers were never
|
|
// listed on the condition that is open.
|
|
|
|
// refusedWait is a wait for a secret the database's manifest does not declare: it fails the check.
|
|
var refusedWait = inventory.Wait{Part: "postgres-database", Secret: "certificate", What: "the database's certificate"}
|
|
|
|
// judgedRefused is the provider's resource as the controller judges it: unhealthy, saying why.
|
|
func judgedRefused() inventory.ResourceHealth {
|
|
r := waitingDatabaseFor(refusedWait)
|
|
r.State, r.Waits = link.StateUnhealthy, nil
|
|
r.Reason = "says it waits for the secret certificate, which db does not declare"
|
|
return r
|
|
}
|
|
|
|
// The consumer's statement arrives after the provider's, so it is the consumer's judging (sayWaiters) that must list
|
|
// it at the provider's unhealthy condition, made urgent by who waits on it.
|
|
func TestAProviderWhoseWaitFailedItsCheckListsWhoWaitsOnIt(t *testing.T) {
|
|
k, _ := withConditionsInMemory(t)
|
|
stored := waitingDatabaseFor(refusedWait)
|
|
open := judgeBoth(t, k, []inventory.ResourceHealth{judgedRefused()},
|
|
map[string]inventory.NodeHealth{"anchor": {Node: "anchor", Resources: []inventory.ResourceHealth{stored}}},
|
|
shopFailingBeside(stored))
|
|
provider := conditionOf(open, moduleUnhealthyKey("db", "anchor"))
|
|
if len(open) != 1 || provider == nil {
|
|
t.Fatalf("a provider whose wait failed its check and a consumer of it raised %v; want the provider's "+
|
|
"unhealthy alone", openKeysOf(open))
|
|
}
|
|
if said := provider.Evidence[0].Said; !strings.Contains(said, "shop on laptop") {
|
|
t.Fatalf("the provider's unhealthy condition does not list shop on laptop as waiting on it: %s", said)
|
|
}
|
|
if provider.Severity != conditions.Urgent {
|
|
t.Fatalf("the provider's unhealthy condition is %s with a consumer waiting on it; want urgent", provider.Severity)
|
|
}
|
|
}
|
|
|
|
// A provider that waits for a secret already given is unhealthy to its consumers too, before its own condition opens:
|
|
// they are held under it as under any unhealthy provider, never as waiting for the operator, and its condition, when
|
|
// open, is said as unhealthy with who waits on it.
|
|
func TestAProviderWaitingForASecretAlreadyGivenIsUnhealthyToItsConsumers(t *testing.T) {
|
|
given := holdingOf(nil, shopFailingBeside(waitingDatabase()), shopOnTheDatabase)
|
|
given.waits.given["db@anchor"] = map[string]time.Time{"licence": time.Now().Add(-time.Hour)}
|
|
by, held := given.heldWith("laptop", "shop", []inventory.ResourceHealth{failingConsumer("shop")})
|
|
if !held || by.provider != theDatabase || len(by.waits) > 0 {
|
|
t.Fatalf("shop under a database waiting for a licence already given: held %v under %v with waits %v; want "+
|
|
"held under db on anchor as unhealthy, no waits", held, by.provider, by.waits)
|
|
}
|
|
if _, uncovered := given.waitingUncovered("laptop", "shop", []inventory.ResourceHealth{failingConsumer("shop")}); uncovered {
|
|
t.Fatalf("a provider whose wait failed its check is said as waiting for another part")
|
|
}
|
|
}
|