diff options
| author | Shulhan <ms@kilabit.info> | 2019-01-23 23:13:13 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2019-01-24 00:26:30 +0700 |
| commit | deb802ac3c1b9279ececedfdca679198c6fe7c8c (patch) | |
| tree | 9647bcfa55a54aeb7fbab86f5df927c183443640 /cacheworker_test.go | |
| parent | 1ddb2adc858d72932a1236f7a0b56275e26353f4 (diff) | |
| download | rescached-deb802ac3c1b9279ececedfdca679198c6fe7c8c.tar.xz | |
cacheworker: add unit test for cacheWorker
Diffstat (limited to 'cacheworker_test.go')
| -rw-r--r-- | cacheworker_test.go | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/cacheworker_test.go b/cacheworker_test.go new file mode 100644 index 0000000..c4fe863 --- /dev/null +++ b/cacheworker_test.go @@ -0,0 +1,233 @@ +// Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package rescached + +import ( + "container/list" + "regexp" + "testing" + "time" + + "github.com/shuLhan/share/lib/dns" + "github.com/shuLhan/share/lib/test" +) + +var testCacheWorker = newCacheWorker(10*time.Second, -10*time.Second) + +func assertCaches(t *testing.T, exp string) { + got := testCacheWorker.caches.String() + re, err := regexp.Compile(exp) + if err != nil { + t.Fatal(err) + } + if !re.MatchString(got) { + t.Fatalf("Expecting caches:\n\t%s\n got:\n%s\n", exp, got) + } +} + +func assertCachesList(t *testing.T, exp string) { + re, err := regexp.Compile(exp) + if err != nil { + t.Fatal(err) + } + + got := testCacheWorker.cachesList.String() + if !re.MatchString(got) { + t.Fatalf("Expecting cachesList:\n%s\n got:\n%s\n", exp, got) + } +} + +func TestCacheWorkerUpsert(t *testing.T) { + cases := []struct { + desc string + msg *dns.Message + isLocal bool + expReturn bool + expCaches string + expCachesList string + }{{ + desc: "With empty message", + expCaches: `^caches\[\]$`, + expCachesList: `^cachesList\[\]$`, + }, { + desc: "With response code is not OK", + msg: &dns.Message{ + Header: &dns.SectionHeader{ + RCode: dns.RCodeErrFormat, + }, + }, + expCaches: `^caches\[\]$`, + expCachesList: `^cachesList\[\]$`, + }, { + desc: "With new message, local - A", + msg: &dns.Message{ + Header: &dns.SectionHeader{ + RCode: dns.RCodeOK, + QDCount: 1, + }, + Question: &dns.SectionQuestion{ + Name: []byte("local"), + Type: dns.QueryTypeA, + Class: dns.QueryClassIN, + }, + }, + isLocal: true, + expReturn: true, + expCaches: `^caches\[local:\[{\d+ \d+ &{Name:local Type:1 Class:1}}\]\]$`, + expCachesList: `^cachesList\[\]$`, + }, { + desc: "With new message, test1 - A", + msg: &dns.Message{ + Header: &dns.SectionHeader{ + RCode: dns.RCodeOK, + QDCount: 1, + }, + Question: &dns.SectionQuestion{ + Name: []byte("test1"), + Type: dns.QueryTypeA, + Class: dns.QueryClassIN, + }, + }, + expReturn: true, + expCaches: `^caches\[local:\[{\d+ \d+ &{Name:local Type:1 Class:1}}\] test1:\[{\d+ \d+ &{Name:test1 Type:1 Class:1}}\]\]$`, + expCachesList: `^cachesList\[&{\d+ \d+ &{Name:test1 Type:1 Class:1}}\]$`, + }, { + desc: "With new message, different type, test1 - NS", + msg: &dns.Message{ + Header: &dns.SectionHeader{ + RCode: dns.RCodeOK, + QDCount: 1, + }, + Question: &dns.SectionQuestion{ + Name: []byte("test1"), + Type: dns.QueryTypeNS, + Class: dns.QueryClassIN, + }, + }, + expReturn: true, + expCaches: `^caches\[local:\[{\d+ \d+ &{Name:local Type:1 Class:1}}\] test1:\[{\d+ \d+ &{Name:test1 Type:1 Class:1}} {\d+ \d+ &{Name:test1 Type:2 Class:1}}\]\]$`, + expCachesList: `^cachesList\[&{\d+ \d+ &{Name:test1 Type:1 Class:1}} &{\d+ \d+ &{Name:test1 Type:2 Class:1}}\]$`, + }, { + desc: "With updated message, test1 - A", + msg: &dns.Message{ + Header: &dns.SectionHeader{ + RCode: dns.RCodeOK, + QDCount: 1, + }, + Question: &dns.SectionQuestion{ + Name: []byte("test1"), + Type: dns.QueryTypeA, + Class: dns.QueryClassIN, + }, + }, + expReturn: true, + expCaches: `^caches\[local:\[{\d+ \d+ &{Name:local Type:1 Class:1}}\] test1:\[{\d+ \d+ &{Name:test1 Type:1 Class:1}} {\d+ \d+ &{Name:test1 Type:2 Class:1}}\]\]$`, + expCachesList: `^cachesList\[&{\d+ \d+ &{Name:test1 Type:2 Class:1}} &{\d+ \d+ &{Name:test1 Type:1 Class:1}}\]$`, + }, { + desc: "With new message, test2 - A", + msg: &dns.Message{ + Header: &dns.SectionHeader{ + RCode: dns.RCodeOK, + QDCount: 1, + }, + Question: &dns.SectionQuestion{ + Name: []byte("test2"), + Type: dns.QueryTypeA, + Class: dns.QueryClassIN, + }, + }, + expReturn: true, + expCaches: `^caches\[local:\[{\d+ \d+ &{Name:local Type:1 Class:1}}\] test1:\[{\d+ \d+ &{Name:test1 Type:1 Class:1}} {\d+ \d+ &{Name:test1 Type:2 Class:1}}\] test2:\[{\d+ \d+ &{Name:test2 Type:1 Class:1}}\]\]$`, + expCachesList: `^cachesList\[&{\d+ \d+ &{Name:test1 Type:2 Class:1}} &{\d+ \d+ &{Name:test1 Type:1 Class:1}} &{\d+ \d+ &{Name:test2 Type:1 Class:1}}\]$`, + }} + + for _, c := range cases { + t.Log(c.desc) + + gotReturn := testCacheWorker.upsert(c.msg, c.isLocal) + + test.Assert(t, "return value", c.expReturn, gotReturn, true) + + assertCaches(t, c.expCaches) + + assertCachesList(t, c.expCachesList) + } +} + +func TestCacheWorkerUpdate(t *testing.T) { + first := testCacheWorker.cachesList.v.Front() + res := first.Value.(*response) + + testCacheWorker.update(res) + + exp := `^cachesList\[&{\d{10} \d{10} &{Name:test1 Type:1 Class:1}} &{\d{10} \d{10} &{Name:test2 Type:1 Class:1}} &{\d{10} \d{10} &{Name:test1 Type:2 Class:1}}\]$` + assertCachesList(t, exp) +} + +func TestCacheWorkerRemove(t *testing.T) { + cases := []struct { + desc string + el *list.Element + expCaches string + expCachesList string + }{{ + desc: "With nil response", + expCaches: `^caches\[local:\[{\d+ \d+ &{Name:local Type:1 Class:1}}\] test1:\[{\d+ \d+ &{Name:test1 Type:1 Class:1}} {\d+ \d+ &{Name:test1 Type:2 Class:1}}\] test2:\[{\d+ \d+ &{Name:test2 Type:1 Class:1}}\]\]$`, + expCachesList: `^cachesList\[&{\d{10} \d{10} &{Name:test1 Type:1 Class:1}} &{\d{10} \d{10} &{Name:test2 Type:1 Class:1}} &{\d{10} \d{10} &{Name:test1 Type:2 Class:1}}\]$`, + }, { + desc: "Removing one element", + el: testCacheWorker.cachesList.v.Front(), + expCaches: `^caches\[local:\[{\d+ \d+ &{Name:local Type:1 Class:1}}\] test1:\[{\d+ \d+ &{Name:test1 Type:2 Class:1}}\] test2:\[{\d+ \d+ &{Name:test2 Type:1 Class:1}}\]\]$`, + expCachesList: `^cachesList\[&{\d{10} \d{10} &{Name:test2 Type:1 Class:1}} &{\d{10} \d{10} &{Name:test1 Type:2 Class:1}}\]$`, + }} + + for _, c := range cases { + var res *response + + t.Log(c.desc) + + if c.el != nil { + v := testCacheWorker.cachesList.v.Remove(c.el) + res = v.(*response) + res.el = nil + } + + testCacheWorker.remove(res) + + assertCaches(t, c.expCaches) + assertCachesList(t, c.expCachesList) + } +} + +func TestCacheWorkerPrune(t *testing.T) { + cases := []struct { + desc string + res *response + expCaches string + expCachesList string + }{{ + desc: "With no items pruned", + expCaches: `^caches\[local:\[{\d+ \d+ &{Name:local Type:1 Class:1}}\] test1:\[{\d+ \d+ &{Name:test1 Type:2 Class:1}}\] test2:\[{\d+ \d+ &{Name:test2 Type:1 Class:1}}\]\]$`, + expCachesList: `^cachesList\[&{\d{10} \d{10} &{Name:test2 Type:1 Class:1}} &{\d{10} \d{10} &{Name:test1 Type:2 Class:1}}\]$`, + }, { + desc: "Pruning one element", + res: testCacheWorker.cachesList.v.Front().Value.(*response), + expCaches: `^caches\[local:\[{\d+ \d+ &{Name:local Type:1 Class:1}}\] test1:\[{\d+ \d+ &{Name:test1 Type:2 Class:1}}\]\]$`, + expCachesList: `^cachesList\[&{\d+ \d+ &{Name:test1 Type:2 Class:1}}\]$`, + }} + + for _, c := range cases { + t.Log(c.desc) + + if c.res != nil { + c.res.accessedAt = time.Now().Add(-20 * time.Second).Unix() + } + + testCacheWorker.prune() + + assertCaches(t, c.expCaches) + assertCachesList(t, c.expCachesList) + } +} |
