package main import ( "encoding/json" "reflect" "testing" stdio "git.novox.be/novox/mesh-sdk/go" "distribution/internal/holder" ) // casMem is a kept state with revisions; before writes it lets another writer write first, once. type casMem struct { value []byte rev uint64 before func() } func (m *casMem) Get(string) (*stdio.StateEntry, error) { if m.value == nil { return nil, nil } return &stdio.StateEntry{Value: m.value, Revision: m.rev}, nil } func (m *casMem) write(v any, at uint64) (uint64, error) { if f := m.before; f != nil { m.before = nil f() } if m.rev != at { return 0, stdio.ErrChanged } m.value, _ = json.Marshal(v) m.rev++ return m.rev, nil } func (m *casMem) Create(_ string, v any) (uint64, error) { return m.write(v, 0) } func (m *casMem) Update(_ string, v any, rev uint64) (uint64, error) { return m.write(v, rev) } // TestTwoFirstPublishesAtOnceAreBothKept: the publishing builds are written with compare-and-set, so a writer that lost // the race reads again and neither build is lost (A3f finding 2). func TestTwoFirstPublishesAtOnceAreBothKept(t *testing.T) { m := &casMem{} m.before = func() { // Another tools process learns mesh-build-go's build first. m.value, _ = json.Marshal(holder.Publishing{Name: holder.PublishingKey, Modules: map[string][]string{"mesh-build-go": {"fp-go"}}}) m.rev = 1 } if learnt, err := learnInto(m, "mesh-build-node", "fp-node", 3); err != nil || !learnt { t.Fatalf("learnInto = %v, %v", learnt, err) } var got holder.Publishing _ = json.Unmarshal(m.value, &got) want := map[string][]string{"mesh-build-go": {"fp-go"}, "mesh-build-node": {"fp-node"}} if !reflect.DeepEqual(got.Modules, want) { t.Errorf("kept %v, want both builds %v", got.Modules, want) } if learnt, err := learnInto(m, "mesh-build-node", "fp-node", 3); err != nil || learnt { t.Errorf("learning a kept build again = %v, %v, want not new and no write", learnt, err) } m.before = func() { m.rev++ } if _, err := learnInto(m, "mesh-build-oci", "fp-oci", 1); err == nil { t.Error("a write lost on every attempt answered no error") } }