package diff2 import ( "reflect" "strings" "testing" "github.com/StackExchange/dnscontrol/v3/models" "github.com/fatih/color" "github.com/kylelemons/godebug/diff" ) func init() { // Disable colorizing the output. // NOTE: "go test ./..." turns it off automatically but "cd // pkg/diff2 && go test" does not. Without this statement, the // latter fails. color.NoColor = true } var testDataAA1234 = makeRec("laba", "A", "1.2.3.4") // [0] var testDataAA5678 = makeRec("laba", "A", "5.6.7.8") // var testDataAA1234ttl700 = makeRecTTL("laba", "A", "1.2.3.4", 700) // var testDataAA5678ttl700 = makeRecTTL("laba", "A", "5.6.7.8", 700) // var testDataAMX10a = makeRec("laba", "MX", "10 laba") // [1] var testDataCCa = makeRec("labc", "CNAME", "laba") // [2] var testDataEA15 = makeRec("labe", "A", "10.10.10.15") // [3] var e4 = makeRec("labe", "A", "10.10.10.16") // [4] var e5 = makeRec("labe", "A", "10.10.10.17") // [5] var e6 = makeRec("labe", "A", "10.10.10.18") // [6] var e7 = makeRec("labg", "NS", "10.10.10.15") // [7] var e8 = makeRec("labg", "NS", "10.10.10.16") // [8] var e9 = makeRec("labg", "NS", "10.10.10.17") // [9] var e10 = makeRec("labg", "NS", "10.10.10.18") // [10] var e11mx = makeRec("labh", "MX", "22 ttt") // [11] var e11 = makeRec("labh", "CNAME", "labd") // [11] var testDataApexMX1aaa = makeRec("", "MX", "1 aaa") var testDataAA1234clone = makeRec("laba", "A", "1.2.3.4") // [0'] var testDataAA12345 = makeRec("laba", "A", "1.2.3.5") // [1'] var testDataAMX20b = makeRec("laba", "MX", "20 labb") // [2'] var d3 = makeRec("labe", "A", "10.10.10.95") // [3'] var d4 = makeRec("labe", "A", "10.10.10.96") // [4'] var d5 = makeRec("labe", "A", "10.10.10.97") // [5'] var d6 = makeRec("labe", "A", "10.10.10.98") // [6'] var d7 = makeRec("labf", "TXT", "foo") // [7'] var d8 = makeRec("labg", "NS", "10.10.10.10") // [8'] var d9 = makeRec("labg", "NS", "10.10.10.15") // [9'] var d10 = makeRec("labg", "NS", "10.10.10.16") // [10'] var d11 = makeRec("labg", "NS", "10.10.10.97") // [11'] var d12 = makeRec("labh", "A", "1.2.3.4") // [12'] var testDataApexMX22bbb = makeRec("", "MX", "22 bbb") func makeChange(v Verb, l, t string, old, new models.Records, msgs []string) Change { c := Change{ Type: v, Old: old, New: new, Msgs: msgs, } c.Key.NameFQDN = l c.Key.Type = t return c } func compareMsgs(t *testing.T, fnname, testname, testpart string, gotcc ChangeList, wantstring string) { t.Helper() gs := strings.TrimSpace(justMsgString(gotcc)) ws := strings.TrimSpace(wantstring) d := diff.Diff(gs, ws) if d != "" { t.Errorf("%s()/%s (wantMsgs:%s):\n===got===\n%s\n===want===\n%s\n===diff===\n%s\n===", fnname, testname, testpart, gs, ws, d) } } func compareCL(t *testing.T, fnname, testname, testpart string, gotcl ChangeList, wantstring string) { t.Helper() gs := strings.TrimSpace(gotcl.String()) ws := strings.TrimSpace(wantstring) d := diff.Diff(gs, ws) if d != "" { t.Errorf("%s()/%s (wantChange%s):\n===got===\n%s\n===want===\n%s\n===diff===\n%s\n===", fnname, testname, testpart, gs, ws, d) } } func Test_analyzeByRecordSet(t *testing.T) { type args struct { origin string existing, desired models.Records compFn ComparableFunc } origin := "f.com" existingSample := models.Records{testDataAA1234, testDataAMX10a, testDataCCa, testDataEA15, e4, e5, e6, e7, e8, e9, e10, e11} desiredSample := models.Records{testDataAA1234clone, testDataAA12345, testDataAMX20b, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12} tests := []struct { name string args args wantMsgs string wantChangeRSet string wantChangeLabel string wantChangeRec string wantChangeZone string }{ { name: "oneequal", args: args{ origin: origin, existing: models.Records{testDataAA1234}, desired: models.Records{testDataAA1234clone}, }, wantMsgs: "", // Empty wantChangeRSet: "ChangeList: len=0", wantChangeLabel: "ChangeList: len=0", wantChangeRec: "ChangeList: len=0", }, { name: "onediff", args: args{ origin: origin, existing: models.Records{testDataAA1234, testDataAMX10a}, desired: models.Records{testDataAA1234clone, testDataAMX20b}, }, wantMsgs: "± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300)", wantChangeRSet: ` ChangeList: len=1 00: Change: verb=CHANGE key={laba.f.com MX} old=[10 laba] new=[20 labb] msg=["± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300)"] `, wantChangeLabel: ` ChangeList: len=1 00: Change: verb=CHANGE key={laba.f.com } old=[1.2.3.4 10 laba] new=[1.2.3.4 20 labb] msg=["± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300)"] `, wantChangeRec: ` ChangeList: len=1 00: Change: verb=CHANGE key={laba.f.com MX} old=[10 laba] new=[20 labb] msg=["± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300)"] `, }, { name: "apex", args: args{ origin: origin, existing: models.Records{testDataAA1234, testDataApexMX1aaa}, desired: models.Records{testDataAA1234clone, testDataApexMX22bbb}, }, wantMsgs: "± MODIFY f.com MX (1 aaa ttl=300) -> (22 bbb ttl=300)", wantChangeRSet: ` ChangeList: len=1 00: Change: verb=CHANGE key={f.com MX} old=[1 aaa] new=[22 bbb] msg=["± MODIFY f.com MX (1 aaa ttl=300) -> (22 bbb ttl=300)"] `, wantChangeLabel: ` ChangeList: len=1 00: Change: verb=CHANGE key={f.com } old=[1 aaa] new=[22 bbb] msg=["± MODIFY f.com MX (1 aaa ttl=300) -> (22 bbb ttl=300)"] `, wantChangeRec: ` ChangeList: len=1 00: Change: verb=CHANGE key={f.com MX} old=[1 aaa] new=[22 bbb] msg=["± MODIFY f.com MX (1 aaa ttl=300) -> (22 bbb ttl=300)"] `, }, { name: "firsta", args: args{ origin: origin, existing: models.Records{testDataAA1234, testDataAMX10a}, desired: models.Records{testDataAA1234clone, testDataAA12345, testDataAMX20b}, }, wantMsgs: ` + CREATE laba.f.com A 1.2.3.5 ttl=300 ± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300) `, wantChangeRSet: ` ChangeList: len=2 00: Change: verb=CHANGE key={laba.f.com A} old=[1.2.3.4] new=[1.2.3.4 1.2.3.5] msg=["+ CREATE laba.f.com A 1.2.3.5 ttl=300"] 01: Change: verb=CHANGE key={laba.f.com MX} old=[10 laba] new=[20 labb] msg=["± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300)"] `, wantChangeLabel: ` ChangeList: len=1 00: Change: verb=CHANGE key={laba.f.com } old=[1.2.3.4 10 laba] new=[1.2.3.4 1.2.3.5 20 labb] msg=["+ CREATE laba.f.com A 1.2.3.5 ttl=300" "± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300)"] `, wantChangeRec: ` ChangeList: len=2 00: Change: verb=CREATE key={laba.f.com A} new=[1.2.3.5] msg=["+ CREATE laba.f.com A 1.2.3.5 ttl=300"] 01: Change: verb=CHANGE key={laba.f.com MX} old=[10 laba] new=[20 labb] msg=["± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300)"] `, }, { name: "big", args: args{ origin: origin, existing: existingSample, desired: desiredSample, }, wantMsgs: ` + CREATE laba.f.com A 1.2.3.5 ttl=300 ± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300) - DELETE labc.f.com CNAME laba ttl=300 ± MODIFY labe.f.com A (10.10.10.15 ttl=300) -> (10.10.10.95 ttl=300) ± MODIFY labe.f.com A (10.10.10.16 ttl=300) -> (10.10.10.96 ttl=300) ± MODIFY labe.f.com A (10.10.10.17 ttl=300) -> (10.10.10.97 ttl=300) ± MODIFY labe.f.com A (10.10.10.18 ttl=300) -> (10.10.10.98 ttl=300) + CREATE labf.f.com TXT "foo" ttl=300 ± MODIFY labg.f.com NS (10.10.10.17 ttl=300) -> (10.10.10.10 ttl=300) ± MODIFY labg.f.com NS (10.10.10.18 ttl=300) -> (10.10.10.97 ttl=300) - DELETE labh.f.com CNAME labd ttl=300 + CREATE labh.f.com A 1.2.3.4 ttl=300 `, wantChangeRSet: ` ChangeList: len=8 00: Change: verb=CHANGE key={laba.f.com A} old=[1.2.3.4] new=[1.2.3.4 1.2.3.5] msg=["+ CREATE laba.f.com A 1.2.3.5 ttl=300"] 01: Change: verb=CHANGE key={laba.f.com MX} old=[10 laba] new=[20 labb] msg=["± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300)"] 02: Change: verb=DELETE key={labc.f.com CNAME} old=[laba] msg=["- DELETE labc.f.com CNAME laba ttl=300"] 03: Change: verb=CHANGE key={labe.f.com A} old=[10.10.10.15 10.10.10.16 10.10.10.17 10.10.10.18] new=[10.10.10.95 10.10.10.96 10.10.10.97 10.10.10.98] msg=["± MODIFY labe.f.com A (10.10.10.15 ttl=300) -> (10.10.10.95 ttl=300)" "± MODIFY labe.f.com A (10.10.10.16 ttl=300) -> (10.10.10.96 ttl=300)" "± MODIFY labe.f.com A (10.10.10.17 ttl=300) -> (10.10.10.97 ttl=300)" "± MODIFY labe.f.com A (10.10.10.18 ttl=300) -> (10.10.10.98 ttl=300)"] 04: Change: verb=CREATE key={labf.f.com TXT} new=["foo"] msg=["+ CREATE labf.f.com TXT \"foo\" ttl=300"] 05: Change: verb=CHANGE key={labg.f.com NS} old=[10.10.10.15 10.10.10.16 10.10.10.17 10.10.10.18] new=[10.10.10.10 10.10.10.15 10.10.10.16 10.10.10.97] msg=["± MODIFY labg.f.com NS (10.10.10.17 ttl=300) -> (10.10.10.10 ttl=300)" "± MODIFY labg.f.com NS (10.10.10.18 ttl=300) -> (10.10.10.97 ttl=300)"] 06: Change: verb=DELETE key={labh.f.com CNAME} old=[labd] msg=["- DELETE labh.f.com CNAME labd ttl=300"] 07: Change: verb=CREATE key={labh.f.com A} new=[1.2.3.4] msg=["+ CREATE labh.f.com A 1.2.3.4 ttl=300"] `, wantChangeLabel: ` ChangeList: len=6 00: Change: verb=CHANGE key={laba.f.com } old=[1.2.3.4 10 laba] new=[1.2.3.4 1.2.3.5 20 labb] msg=["+ CREATE laba.f.com A 1.2.3.5 ttl=300" "± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300)"] 01: Change: verb=DELETE key={labc.f.com } old=[laba] msg=["- DELETE labc.f.com CNAME laba ttl=300"] 02: Change: verb=CHANGE key={labe.f.com } old=[10.10.10.15 10.10.10.16 10.10.10.17 10.10.10.18] new=[10.10.10.95 10.10.10.96 10.10.10.97 10.10.10.98] msg=["± MODIFY labe.f.com A (10.10.10.15 ttl=300) -> (10.10.10.95 ttl=300)" "± MODIFY labe.f.com A (10.10.10.16 ttl=300) -> (10.10.10.96 ttl=300)" "± MODIFY labe.f.com A (10.10.10.17 ttl=300) -> (10.10.10.97 ttl=300)" "± MODIFY labe.f.com A (10.10.10.18 ttl=300) -> (10.10.10.98 ttl=300)"] 03: Change: verb=CREATE key={labf.f.com } new=["foo"] msg=["+ CREATE labf.f.com TXT \"foo\" ttl=300"] 04: Change: verb=CHANGE key={labg.f.com } old=[10.10.10.15 10.10.10.16 10.10.10.17 10.10.10.18] new=[10.10.10.10 10.10.10.15 10.10.10.16 10.10.10.97] msg=["± MODIFY labg.f.com NS (10.10.10.17 ttl=300) -> (10.10.10.10 ttl=300)" "± MODIFY labg.f.com NS (10.10.10.18 ttl=300) -> (10.10.10.97 ttl=300)"] 05: Change: verb=CHANGE key={labh.f.com } old=[labd] new=[1.2.3.4] msg=["- DELETE labh.f.com CNAME labd ttl=300" "+ CREATE labh.f.com A 1.2.3.4 ttl=300"] `, wantChangeRec: ` ChangeList: len=12 00: Change: verb=CREATE key={laba.f.com A} new=[1.2.3.5] msg=["+ CREATE laba.f.com A 1.2.3.5 ttl=300"] 01: Change: verb=CHANGE key={laba.f.com MX} old=[10 laba] new=[20 labb] msg=["± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300)"] 02: Change: verb=DELETE key={labc.f.com CNAME} old=[laba] msg=["- DELETE labc.f.com CNAME laba ttl=300"] 03: Change: verb=CHANGE key={labe.f.com A} old=[10.10.10.15] new=[10.10.10.95] msg=["± MODIFY labe.f.com A (10.10.10.15 ttl=300) -> (10.10.10.95 ttl=300)"] 04: Change: verb=CHANGE key={labe.f.com A} old=[10.10.10.16] new=[10.10.10.96] msg=["± MODIFY labe.f.com A (10.10.10.16 ttl=300) -> (10.10.10.96 ttl=300)"] 05: Change: verb=CHANGE key={labe.f.com A} old=[10.10.10.17] new=[10.10.10.97] msg=["± MODIFY labe.f.com A (10.10.10.17 ttl=300) -> (10.10.10.97 ttl=300)"] 06: Change: verb=CHANGE key={labe.f.com A} old=[10.10.10.18] new=[10.10.10.98] msg=["± MODIFY labe.f.com A (10.10.10.18 ttl=300) -> (10.10.10.98 ttl=300)"] 07: Change: verb=CREATE key={labf.f.com TXT} new=["foo"] msg=["+ CREATE labf.f.com TXT \"foo\" ttl=300"] 08: Change: verb=CHANGE key={labg.f.com NS} old=[10.10.10.17] new=[10.10.10.10] msg=["± MODIFY labg.f.com NS (10.10.10.17 ttl=300) -> (10.10.10.10 ttl=300)"] 09: Change: verb=CHANGE key={labg.f.com NS} old=[10.10.10.18] new=[10.10.10.97] msg=["± MODIFY labg.f.com NS (10.10.10.18 ttl=300) -> (10.10.10.97 ttl=300)"] 10: Change: verb=DELETE key={labh.f.com CNAME} old=[labd] msg=["- DELETE labh.f.com CNAME labd ttl=300"] 11: Change: verb=CREATE key={labh.f.com A} new=[1.2.3.4] msg=["+ CREATE labh.f.com A 1.2.3.4 ttl=300"] `, }, } for _, tt := range tests { // Each "analyze*()" should return the same msgs, but a different ChangeList. // Sadly the analyze*() functions are destructive to the CompareConfig struct. // Therefore we have to run NewCompareConfig() each time. t.Run(tt.name, func(t *testing.T) { cl := analyzeByRecordSet(NewCompareConfig(tt.args.origin, tt.args.existing, tt.args.desired, tt.args.compFn)) compareMsgs(t, "analyzeByRecordSet", tt.name, "RSet", cl, tt.wantMsgs) compareCL(t, "analyzeByRecordSet", tt.name, "RSet", cl, tt.wantChangeRSet) }) t.Run(tt.name, func(t *testing.T) { cl := analyzeByLabel(NewCompareConfig(tt.args.origin, tt.args.existing, tt.args.desired, tt.args.compFn)) compareMsgs(t, "analyzeByLabel", tt.name, "Label", cl, tt.wantMsgs) compareCL(t, "analyzeByLabel", tt.name, "Label", cl, tt.wantChangeLabel) }) t.Run(tt.name, func(t *testing.T) { cl := analyzeByRecord(NewCompareConfig(tt.args.origin, tt.args.existing, tt.args.desired, tt.args.compFn)) compareMsgs(t, "analyzeByRecord", tt.name, "Rec", cl, tt.wantMsgs) compareCL(t, "analyzeByRecord", tt.name, "Rec", cl, tt.wantChangeRec) }) // NB(tlim): There is no analyzeByZone(). diff2.ByZone() uses analyzeByRecord(). } } func mkTargetConfig(x ...*models.RecordConfig) []targetConfig { var tc []targetConfig for _, r := range x { ct, cf := mkCompareBlobs(r, nil) tc = append(tc, targetConfig{ comparableNoTTL: ct, comparableFull: cf, rec: r, }) } return tc } func mkTargetConfigMap(x ...*models.RecordConfig) map[string]*targetConfig { var m = map[string]*targetConfig{} for _, v := range mkTargetConfig(x...) { m[v.comparableFull] = &v } return m } func Test_diffTargets(t *testing.T) { type args struct { existing []targetConfig desired []targetConfig } tests := []struct { name string args args want ChangeList }{ { name: "add1changettl", args: args{ existing: mkTargetConfig(testDataAA5678), desired: mkTargetConfig(testDataAA5678ttl700, testDataAA1234ttl700), }, want: ChangeList{ Change{Type: CHANGE, Key: models.RecordKey{NameFQDN: "laba.f.com", Type: "A"}, New: models.Records{testDataAA5678ttl700, testDataAA1234ttl700}, Msgs: []string{ "± MODIFY-TTL laba.f.com A 5.6.7.8 ttl=(300->700)", "+ CREATE laba.f.com A 1.2.3.4 ttl=700", }, }, }, }, { name: "single", args: args{ existing: mkTargetConfig(testDataAA1234), desired: mkTargetConfig(testDataAA1234), }, //want: , }, { name: "add1", args: args{ existing: mkTargetConfig(testDataAA1234), desired: mkTargetConfig(testDataAA1234, testDataAMX10a), }, want: ChangeList{ Change{Type: CREATE, Key: models.RecordKey{NameFQDN: "laba.f.com", Type: "MX"}, New: models.Records{testDataAMX10a}, Msgs: []string{"+ CREATE laba.f.com MX 10 laba ttl=300"}, }, }, }, { name: "del1", args: args{ existing: mkTargetConfig(testDataAA1234, testDataAMX10a), desired: mkTargetConfig(testDataAA1234), }, want: ChangeList{ Change{Type: DELETE, Key: models.RecordKey{NameFQDN: "laba.f.com", Type: "MX"}, Old: models.Records{testDataAMX10a}, Msgs: []string{"- DELETE laba.f.com MX 10 laba ttl=300"}, }, }, }, { name: "change2nd", args: args{ existing: mkTargetConfig(testDataAA1234, testDataAMX10a), desired: mkTargetConfig(testDataAA1234, testDataAMX20b), }, want: ChangeList{ Change{Type: CHANGE, Key: models.RecordKey{NameFQDN: "laba.f.com", Type: "MX"}, Old: models.Records{testDataAMX10a}, New: models.Records{testDataAMX20b}, Msgs: []string{"± MODIFY laba.f.com MX (10 laba ttl=300) -> (20 labb ttl=300)"}, }, }, }, { name: "del2nd", args: args{ existing: mkTargetConfig(testDataAA1234, testDataAA5678), desired: mkTargetConfig(testDataAA1234), }, want: ChangeList{ Change{Type: CHANGE, Key: models.RecordKey{NameFQDN: "laba.f.com", Type: "A"}, Old: models.Records{testDataAA1234, testDataAA5678}, New: models.Records{testDataAA1234}, Msgs: []string{"- DELETE laba.f.com A 5.6.7.8 ttl=300"}, }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { //fmt.Printf("DEBUG: Test %02d\n", i) got := diffTargets(tt.args.existing, tt.args.desired) g := strings.TrimSpace(justMsgString(got)) w := strings.TrimSpace(justMsgString(tt.want)) d := diff.Diff(g, w) if d != "" { //fmt.Printf("DEBUG: fail %q %q\n", g, w) t.Errorf("diffTargets()\n diff=%s", d) } }) } } func Test_removeCommon(t *testing.T) { type args struct { existing []targetConfig desired []targetConfig } tests := []struct { name string args args want []targetConfig want1 []targetConfig }{ { name: "same", args: args{ existing: mkTargetConfig(testDataAA1234clone), desired: mkTargetConfig(testDataAA1234clone), }, want: []targetConfig{}, want1: []targetConfig{}, }, { name: "disjoint", args: args{ existing: mkTargetConfig(testDataAA1234), desired: mkTargetConfig(testDataAA5678), }, want: mkTargetConfig(testDataAA1234), want1: mkTargetConfig(testDataAA5678), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, got1 := removeCommon(tt.args.existing, tt.args.desired) if !reflect.DeepEqual(got, tt.want) { t.Errorf("removeCommon() got = %v, want %v", got, tt.want) } if (!(got1 == nil && tt.want1 == nil)) && !reflect.DeepEqual(got1, tt.want1) { t.Errorf("removeCommon() got1 = %v, want %v", got1, tt.want1) } }) } } func comparables(s []targetConfig) []string { var r []string for _, j := range s { r = append(r, j.comparableFull) } return r } func Test_filterBy(t *testing.T) { type args struct { s []targetConfig m map[string]*targetConfig } tests := []struct { name string args args want []targetConfig }{ { name: "removeall", args: args{ s: mkTargetConfig(testDataAA1234, testDataAMX10a), m: mkTargetConfigMap(testDataAA1234, testDataAMX10a), }, want: []targetConfig{}, }, { name: "keepall", args: args{ s: mkTargetConfig(testDataAA1234, testDataAMX10a), m: mkTargetConfigMap(), }, want: mkTargetConfig(testDataAA1234, testDataAMX10a), }, { name: "keepsome", args: args{ s: mkTargetConfig(testDataAA1234, testDataAMX10a), m: mkTargetConfigMap(testDataAMX10a), }, want: mkTargetConfig(testDataAA1234), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := filterBy(tt.args.s, tt.args.m); !reflect.DeepEqual(comparables(got), comparables(tt.want)) { t.Errorf("filterBy() = %v, want %v", got, tt.want) } }) } } func Test_splitTTLOnly(t *testing.T) { type args struct { existing []targetConfig desired []targetConfig } tests := []struct { name string args args wantExistDiff []targetConfig wantDesireDiff []targetConfig wantChanges string }{ { name: "simple", args: args{ existing: mkTargetConfig(testDataAA1234), desired: mkTargetConfig(testDataAA1234ttl700), }, wantExistDiff: nil, wantDesireDiff: nil, wantChanges: "ChangeList: len=1\n00: Change: verb=CHANGE\n key={laba.f.com A}\n Hints=OnlyTTL\n{laba.f.com A} old=[1.2.3.4]\n new=[1.2.3.4]\n msg=[\"± MODIFY-TTL laba.f.com A 1.2.3.4 ttl=(300->700)\"]\n", }, { name: "both", args: args{ existing: mkTargetConfig(testDataAA1234), desired: mkTargetConfig(testDataAA5678), }, wantExistDiff: mkTargetConfig(testDataAA1234), wantDesireDiff: mkTargetConfig(testDataAA5678), wantChanges: "ChangeList: len=0\n", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { gotExistDiff, gotDesireDiff, gotChanges := findTTLChanges(tt.args.existing, tt.args.desired) if !reflect.DeepEqual(gotExistDiff, tt.wantExistDiff) { t.Errorf("splitTTLOnly() gotExistDiff = %v, want %v", gotExistDiff, tt.wantExistDiff) } if !reflect.DeepEqual(gotDesireDiff, tt.wantDesireDiff) { t.Errorf("splitTTLOnly() gotDesireDiff = %v, want %v", gotDesireDiff, tt.wantDesireDiff) } gotChangesString := gotChanges.String() if gotChangesString != tt.wantChanges { t.Errorf("splitTTLOnly() gotChanges=\n%q, want=\n%q", gotChangesString, tt.wantChanges) } }) } }