package viewstate import ( "strings" "testing" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks" "git.novox.be/novox/mesh-sdk/go/keys" ) func sampleReach() Reach { return Reach{V: keys.Version, Repository: "novox/mesh-catalog", Indexed: "cccc", Reached: "cccc", ReachedSrc: 9, Modules: map[string]ModuleReach{ "gitea": {FP: "src2:a", Nodes: 1, Floor: "cccc", Waiting: "gitea on ace runs src2:a and its health check failed", Changes: []Change{{Commit: "cccc", FP: "src2:a", Src: 9}, {Commit: "bbbb", FP: "src2:b", Src: 7}}}, "zsh": {FP: "src2:z", Changes: []Change{{Commit: "aaaa", FP: "src2:z"}}}, }} } // 1280: the reach value (ADR 0556) round-trips, and values that do not hold are refused, naming what is wrong. func TestAReachValueRoundTripsAndRefusesWhatDoesNotHold(t *testing.T) { wantErr := func(what string, err error, in string) { t.Helper() if err == nil || !strings.Contains(err.Error(), in) { t.Errorf("%s: %v, want an error naming %q", what, err, in) } } r := sampleReach() data, err := EncodeReach(r) if err != nil { t.Fatal(err) } if got, err := DecodeReach(data); err != nil || !SameReach(got, r) { t.Errorf("reach round trip: %+v %v", got, err) } r.Repository = "" _, err = EncodeReach(r) wantErr("reach without repository", err, "repository") r = sampleReach() m := r.Modules["gitea"] m.Changes = append(m.Changes, Change{Commit: "dddd"}) r.Modules["gitea"] = m _, err = EncodeReach(r) wantErr("reach with a change naming no fingerprint", err, "gitea") r = sampleReach() m = r.Modules["gitea"] m.Changes = make([]Change, MostChanges+1) r.Modules["gitea"] = m _, err = EncodeReach(r) wantErr("reach keeping too many changes", err, "more than") r = sampleReach() r.ReachedSrc = 0 _, err = EncodeReach(r) wantErr("reach with a head and no revision", err, "reached head") } func TestReachValuesDifferingInAnyPartAreNotTheSame(t *testing.T) { if !SameReach(sampleReach(), sampleReach()) { t.Error("equal reach values differ") } for name, change := range map[string]func(*Reach){ "indexed": func(r *Reach) { r.Indexed = "dddd" }, "floor": func(r *Reach) { m := r.Modules["gitea"]; m.Floor = "bbbb"; r.Modules["gitea"] = m }, "changes": func(r *Reach) { m := r.Modules["zsh"]; m.Changes = nil; r.Modules["zsh"] = m }, "modules": func(r *Reach) { delete(r.Modules, "zsh") }, "reached": func(r *Reach) { r.Reached, r.ReachedSrc = "bbbb", 7 }, "holds": func(r *Reach) { r.Holds = []string{"gitea on ace does not yet run src2:a"} }, } { r := sampleReach() change(&r) if SameReach(r, sampleReach()) { t.Errorf("reach values differing in %s are the same", name) } } } func TestViewAnswerRoundTrip(t *testing.T) { t.Run("the key and the asking", func(t *testing.T) { fp := "src2:" + strings.Repeat("ab", 32) hold, _ := asks.HoldAskKey("gitea", fp) key, err := ViewAnswerKey(hold) if err != nil || key != hold+".view" { t.Fatalf("ViewAnswerKey = %q, %v", key, err) } if back, err := ParseViewAnswerKey(key); err != nil || back != hold { t.Errorf("ParseViewAnswerKey = %q, %v", back, err) } for _, bad := range []string{hold, "merge.g.d106c7950d28.view", "other.x.view"} { if _, err := ParseViewAnswerKey(bad); err == nil { t.Errorf("ParseViewAnswerKey(%q) reads a wrong key", bad) } } if _, err := ViewAnswerKey("merge.g.d106c7950d28"); err == nil || !strings.Contains(err.Error(), "proof") { t.Errorf("a merge ask is answered by the view: %v", err) } first := ViewAnswer{Asking: meshdeliveryclient.AskingID(hold, 0), Option: "release"} if err := ViewAnswerFits(first, hold, asks.Ask{}); err != nil { t.Errorf("an answer to the first asking is refused: %v", err) } if err := ViewAnswerFits(first, hold, asks.Ask{Asking: 2}); err == nil { t.Error("an answer to an earlier asking is taken for the later one") } }) a := ViewAnswer{Asking: "hold-mesh-mail-aaaa-0123456789ab", Option: "release", Words: "fixed by #12"} data, err := EncodeViewAnswer(a) if err != nil { t.Fatal(err) } got, err := DecodeViewAnswer(data) a.V = keys.Version if err != nil || !SameViewAnswer(got, a) { t.Errorf("view answer came back %+v, %v", got, err) } if _, err := EncodeViewAnswer(ViewAnswer{Asking: "x", Option: " "}); err == nil { t.Errorf("a view answer naming no option was accepted") } if _, err := EncodeViewAnswer(ViewAnswer{Option: "release"}); err == nil { t.Errorf("a view answer naming no asking was accepted") } }