package host import ( "testing" "github.com/carlosframework/platform/internal/hostclaim" ) func plan9D1Session(phase string, session uint64) hostclaim.Observed { return hostclaim.Observed{Host: recoveryHost, Claim: &hostclaim.Claim{Host: recoveryHost, Holder: &hostclaim.Holder{Incarnation: "inc", Location: "instances/" + recoveryHost, Generation: "m1", Stamp: 10, Session: session, WriterBox: "uk-box"}, Op: hostclaim.Op{Kind: hostclaim.KindLanding, ID: "m1", Phase: phase, Exec: "uk-box"}}} } // The wake's write identity follows the session table one adjacent step at // a time (M9): a probe session checked at probing is itself at probed for // Prepare, not at committed, and nothing else is. Its stop identity follows // the row forward to any later phase (R1): stopping grants no authority, so a // probe that reached committed unseen is still stopped as itself. Neither // follows a new session or a step back. func TestPlan9D1WriterIdentityFollowsTheSessionTable(t *testing.T) { probing := plan9D1Session(hostclaim.PhaseLandingProbing, 11) for _, tc := range []struct { name string later hostclaim.Observed continues, reaches func(string, string, string) bool write, stop bool }{ {"same", plan9D1Session(hostclaim.PhaseLandingProbing, 11), nil, nil, true, true}, {"main-equality", plan9D1Session(hostclaim.PhaseLandingProbed, 11), nil, nil, false, false}, {"probed", plan9D1Session(hostclaim.PhaseLandingProbed, 11), hostclaim.SessionContinues, hostclaim.SessionReaches, true, true}, {"skipped", plan9D1Session(hostclaim.PhaseLandingCommitted, 11), hostclaim.SessionContinues, hostclaim.SessionReaches, false, true}, {"new-session", plan9D1Session(hostclaim.PhaseLandingCommitted, 12), hostclaim.SessionContinues, hostclaim.SessionReaches, false, false}, {"backward", plan9D1Session("restored", 11), hostclaim.SessionContinues, hostclaim.SessionReaches, false, false}, } { if got := claimSameWriter(probing, tc.later, tc.continues); got != tc.write { t.Errorf("%s: claimSameWriter = %v, want %v", tc.name, got, tc.write) } if got := sameStopWriter(probing, tc.later, tc.reaches); got != tc.stop { t.Errorf("%s: sameStopWriter = %v, want %v", tc.name, got, tc.stop) } } probed, committed := plan9D1Session(hostclaim.PhaseLandingProbed, 11), plan9D1Session(hostclaim.PhaseLandingCommitted, 11) if !claimSameWriter(probed, committed, hostclaim.SessionContinues) || !sameStopWriter(probed, committed, hostclaim.SessionReaches) { t.Fatal("probed to committed ended the session") } for _, back := range []hostclaim.Observed{probing, probed} { if claimSameWriter(committed, back, hostclaim.SessionContinues) || sameStopWriter(committed, back, hostclaim.SessionReaches) { t.Fatalf("a later observation stepped back to %s and kept the session", back.Claim.Op.Phase) } } // The stop predicate is bound with the session table and only then. if (ClaimAssembly{}).stopReaches() != nil || (ClaimAssembly{Wake: &ClaimWakeAssembly{}}).stopReaches() != nil { t.Fatal("stop reachability bound without the moves C1 session table") } if r := (ClaimAssembly{Wake: &ClaimWakeAssembly{Continue: hostclaim.SessionContinues}}).stopReaches(); r == nil || !r(hostclaim.KindLanding, hostclaim.PhaseLandingProbing, hostclaim.PhaseLandingCommitted) || r(hostclaim.KindLanding, hostclaim.PhaseLandingCommitted, hostclaim.PhaseLandingProbing) || r(hostclaim.KindServing, "a", "b") { t.Fatal("bound stop predicate is not forward reachability on the row") } }