package catalogue import ( "testing" ) // A store as a module now declares it (novox/hq ADR 0233): its own data by directory with a class and a // dump, and what it keeps for its consumers. const declaredStore = `{"module":"pg","version":"1", "provides":[{"name":"postgres-database","scope":"mesh"}], "grants":{"postgres-database":"${dir:grants}"}, "data":{ "own":[ {"id":"store","path":"${dir:store}","class":"irreplaceable","backup":{"dump":"dump-all > ${dir:dumps}/all","into":"dumps"},"active":"1d"}, {"id":"dumps","path":"${dir:dumps}","class":"rebuildable","backup":"none"}], "consumers":{"postgres-database":{"class":"irreplaceable","in":"store"}}}, "resources":[ {"id":"grants","type":"directory","mode":"0700"}, {"id":"store","type":"directory","path":"/srv/store","mode":"0700"}, {"id":"dumps","type":"directory","path":"${dir:store}/dumps","mode":"0700"}, {"id":"server","type":"container","image":"x@sha256:aa","volumes":["${dir:store}:/var/lib/postgresql/data"]}]}` func mustParse(t *testing.T, raw string) Manifest { t.Helper() m, err := decodeForTest([]byte(raw)) if err != nil { t.Fatalf("refused: %v", err) } return m } // What a binding is sticky by follows the class (ADR 0232, generalised by 0233): a cache's consumers // move freely, a store's do not; an older definition saying nothing still follows its grant. func TestKeepingConsumerDataFollowsTheClass(t *testing.T) { for class, keeps := range map[string]bool{"irreplaceable": true, "valuable": true, "rebuildable": true, "cache": false, "none": false} { in := `,"in":"d"` own := `"own":[{"id":"d","path":"${dir:d}","class":"irreplaceable"}],` if !keeps { in, own = "", "" } m := mustParse(t, `{"module":"p","version":"1","provides":[{"name":"q","scope":"mesh"}],"grants":{"q":"${dir:d}"}, "resources":[{"id":"d","type":"directory","mode":"0700"}], "data":{`+own+`"consumers":{"q":{"class":"`+class+`"`+in+`}}}}`) if m.KeepsConsumerData("q") != keeps { t.Errorf("class %s keeps consumer data: %v, want %v", class, !keeps, keeps) } shelf := map[string]Manifest{"p": m} if KeepsConsumerData(shelf, "q") != keeps { t.Errorf("class %s: the provision by name keeps: %v", class, !keeps) } } older := mustParse(t, `{"module":"p","version":"1","provides":[{"name":"q","scope":"mesh"}],"grants":{"q":"${dir:d}"}, "resources":[{"id":"d","type":"directory","mode":"0700"}]}`) if !older.KeepsConsumerData("q") { t.Fatal("an older definition that grants no longer keeps its consumers' data") } }