package declaration import ( "strings" "testing" ) // Defends novox/hq ADR 0117: a service may leave its unit's lifecycle to the machine, and then // says nothing but its triggers. func TestAServiceWithoutAStateSaysOnlyItsTriggers(t *testing.T) { for name, c := range map[string]struct{ resource, refusal string }{ "no trigger": {`{"id":"s","type":"service","unit":"NetworkManager.service"}`, "declares nothing"}, "with boot": {`{"id":"s","type":"service","unit":"NetworkManager.service","boot":"enabled","reload-on":["f"]}`, "boot and takes-over"}, "with takes-over": {`{"id":"s","type":"service","unit":"a.service","reload-on":["f"],"takes-over":{"interface":"wg0","unit":"b.service","config":"/etc/x"}}`, "boot and takes-over"}, "an unknown state": {`{"id":"s","type":"service","unit":"a.service","state":"paused"}`, "omits state to leave the unit's lifecycle to the machine"}, } { _, err := Parse([]byte(`{"declaration":1,"resources":[{"id":"f","type":"file","path":"/etc/x","content":"x"},` + c.resource + `]}`)) if err == nil || !strings.Contains(err.Error(), c.refusal) { t.Errorf("%s: want a refusal naming %q, got %v", name, c.refusal, err) } } d, err := Parse([]byte(`{"declaration":1,"resources":[{"id":"f","type":"file","path":"/etc/x","content":"x"}, {"id":"s","type":"service","unit":"NetworkManager.service","restart-on":["f"]}]}`)) if err != nil { t.Fatal(err) } if s := d.Resources[1].(*Service); !s.Stateless() { t.Error("a service without a state was not read as stateless") } }