feat(service): apply custom marks to the computed diff
This commit is contained in:
@@ -27,10 +27,11 @@ func testCipher(t *testing.T) *crypto.Cipher {
|
||||
|
||||
// fakeProvider records applied changesets and returns canned zone records.
|
||||
type fakeProvider struct {
|
||||
actual []model.Record
|
||||
applied diff.Changeset
|
||||
getErr error // when set, GetRecords fails with this error
|
||||
applyErr error // when set, ApplyChanges fails with this error
|
||||
actual []model.Record
|
||||
applied diff.Changeset
|
||||
applyCalls int
|
||||
getErr error // when set, GetRecords fails with this error
|
||||
applyErr error // when set, ApplyChanges fails with this error
|
||||
}
|
||||
|
||||
func (fakeProvider) Name() string { return "selectel" }
|
||||
@@ -44,6 +45,7 @@ func (f *fakeProvider) GetRecords(context.Context, provider.Credentials, string)
|
||||
return f.actual, nil
|
||||
}
|
||||
func (f *fakeProvider) ApplyChanges(_ context.Context, _ provider.Credentials, _ string, cs diff.Changeset) error {
|
||||
f.applyCalls++
|
||||
if f.applyErr != nil {
|
||||
return f.applyErr
|
||||
}
|
||||
@@ -70,12 +72,18 @@ type nopRecorder struct{}
|
||||
func (nopRecorder) SaveCheckRun(context.Context, uuid.UUID, diff.Changeset) error { return nil }
|
||||
|
||||
func setup(t *testing.T, actual []model.Record, tmpl dto.TemplateDoc) (*DomainService, *fakeProvider) {
|
||||
return setupWithCustomKeys(t, actual, tmpl, nil)
|
||||
}
|
||||
|
||||
// setupWithCustomKeys mirrors setup but also lets a test populate
|
||||
// DomainRef.CustomKeys, exercising the resolve() -> MarkCustom wiring.
|
||||
func setupWithCustomKeys(t *testing.T, actual []model.Record, tmpl dto.TemplateDoc, customKeys []string) (*DomainService, *fakeProvider) {
|
||||
fp := &fakeProvider{actual: actual}
|
||||
reg := registry.New()
|
||||
reg.Register(fp)
|
||||
cipher := testCipher(t)
|
||||
enc, _ := cipher.Encrypt([]byte("secret"))
|
||||
loader := fakeLoader{ref: DomainRef{ZoneID: "z1", ZoneName: "example.com.", Provider: "selectel", SecretEnc: enc, Template: tmpl}}
|
||||
loader := fakeLoader{ref: DomainRef{ZoneID: "z1", ZoneName: "example.com.", Provider: "selectel", SecretEnc: enc, Template: tmpl, CustomKeys: customKeys}}
|
||||
return New(loader, nopRecorder{}, reg, cipher), fp
|
||||
}
|
||||
|
||||
@@ -246,3 +254,53 @@ func TestResolveWrapsProviderError(t *testing.T) {
|
||||
t.Fatalf("expected clean provider message, got %q", msg)
|
||||
}
|
||||
}
|
||||
|
||||
// TestResolveMarksCustomKeys covers the resolve() -> cs.MarkCustom(ref.CustomKeys)
|
||||
// wiring: a zone record with no template counterpart, whose key is in
|
||||
// DomainRef.CustomKeys, must be marked Custom rather than surfacing as a
|
||||
// prune/drift.
|
||||
func TestResolveMarksCustomKeys(t *testing.T) {
|
||||
// Zone contains a record absent from the template, and its key is marked custom.
|
||||
actual := []model.Record{
|
||||
{Type: model.CNAME, Name: "admin.example.com.", TTL: 300, Values: []string{"example.com."}},
|
||||
}
|
||||
svc, _ := setupWithCustomKeys(t, actual, dto.TemplateDoc{Records: nil}, []string{"CNAME admin.example.com."})
|
||||
|
||||
cs, err := svc.Check(context.Background(), uuid.New(), uuid.New())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := cs.Prunes(); len(got) != 0 {
|
||||
t.Fatalf("custom record must not appear in Prunes, got %+v", got)
|
||||
}
|
||||
if got := cs.Customs(); len(got) != 1 {
|
||||
t.Fatalf("expected 1 custom diff, got %+v", got)
|
||||
}
|
||||
if status := DeriveStatus(cs); status != StatusInSync {
|
||||
t.Fatalf("a zone whose only deviation is custom must be in_sync, got %q", status)
|
||||
}
|
||||
}
|
||||
|
||||
// TestApplyIgnoresCustomKeySentAsPrune covers the case where a client sends a
|
||||
// custom-marked key in ApplyRequest.Prunes anyway (stale UI state, replay,
|
||||
// etc): since a custom diff is excluded from cs.Prunes(), Apply's key
|
||||
// selection never picks it up and the provider is not called at all.
|
||||
func TestApplyIgnoresCustomKeySentAsPrune(t *testing.T) {
|
||||
actual := []model.Record{
|
||||
{Type: model.CNAME, Name: "admin.example.com.", TTL: 300, Values: []string{"example.com."}},
|
||||
}
|
||||
svc, fp := setupWithCustomKeys(t, actual, dto.TemplateDoc{Records: nil}, []string{"CNAME admin.example.com."})
|
||||
|
||||
applied, err := svc.Apply(context.Background(), uuid.New(), uuid.New(), ApplyRequest{
|
||||
Prunes: []string{"CNAME admin.example.com."},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(applied.Diffs) != 0 {
|
||||
t.Fatalf("custom key must never be applied, got %+v", applied.Diffs)
|
||||
}
|
||||
if fp.applyCalls != 0 {
|
||||
t.Fatalf("provider must not be called with an empty change set, got %d calls", fp.applyCalls)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user