"Fossies" - the Fresh Open Source Software Archive 
Member "AdGuardHome-0.104.3/internal/querylog/qlog_test.go" (19 Nov 2020, 7408 Bytes) of package /linux/misc/dns/AdGuardHome-0.104.3.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
See also the latest
Fossies "Diffs" side-by-side code changes report for "qlog_test.go":
0.104.1_vs_0.104.3.
1 package querylog
2
3 import (
4 "net"
5 "os"
6 "testing"
7
8 "github.com/AdguardTeam/dnsproxy/proxyutil"
9
10 "github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
11 "github.com/AdguardTeam/AdGuardHome/internal/testutil"
12 "github.com/miekg/dns"
13 "github.com/stretchr/testify/assert"
14 )
15
16 func TestMain(m *testing.M) {
17 testutil.DiscardLogOutput(m)
18 }
19
20 func prepareTestDir() string {
21 const dir = "./agh-test"
22 _ = os.RemoveAll(dir)
23 _ = os.MkdirAll(dir, 0755)
24 return dir
25 }
26
27 // Check adding and loading (with filtering) entries from disk and memory
28 func TestQueryLog(t *testing.T) {
29 conf := Config{
30 Enabled: true,
31 FileEnabled: true,
32 Interval: 1,
33 MemSize: 100,
34 }
35 conf.BaseDir = prepareTestDir()
36 defer func() { _ = os.RemoveAll(conf.BaseDir) }()
37 l := newQueryLog(conf)
38
39 // add disk entries
40 addEntry(l, "example.org", "1.1.1.1", "2.2.2.1")
41 // write to disk (first file)
42 _ = l.flushLogBuffer(true)
43 // start writing to the second file
44 _ = l.rotate()
45 // add disk entries
46 addEntry(l, "example.org", "1.1.1.2", "2.2.2.2")
47 // write to disk
48 _ = l.flushLogBuffer(true)
49 // add memory entries
50 addEntry(l, "test.example.org", "1.1.1.3", "2.2.2.3")
51 addEntry(l, "example.com", "1.1.1.4", "2.2.2.4")
52
53 // get all entries
54 params := newSearchParams()
55 entries, _ := l.search(params)
56 assert.Equal(t, 4, len(entries))
57 assertLogEntry(t, entries[0], "example.com", "1.1.1.4", "2.2.2.4")
58 assertLogEntry(t, entries[1], "test.example.org", "1.1.1.3", "2.2.2.3")
59 assertLogEntry(t, entries[2], "example.org", "1.1.1.2", "2.2.2.2")
60 assertLogEntry(t, entries[3], "example.org", "1.1.1.1", "2.2.2.1")
61
62 // search by domain (strict)
63 params = newSearchParams()
64 params.searchCriteria = append(params.searchCriteria, searchCriteria{
65 criteriaType: ctDomainOrClient,
66 strict: true,
67 value: "TEST.example.org",
68 })
69 entries, _ = l.search(params)
70 assert.Equal(t, 1, len(entries))
71 assertLogEntry(t, entries[0], "test.example.org", "1.1.1.3", "2.2.2.3")
72
73 // search by domain (not strict)
74 params = newSearchParams()
75 params.searchCriteria = append(params.searchCriteria, searchCriteria{
76 criteriaType: ctDomainOrClient,
77 strict: false,
78 value: "example.ORG",
79 })
80 entries, _ = l.search(params)
81 assert.Equal(t, 3, len(entries))
82 assertLogEntry(t, entries[0], "test.example.org", "1.1.1.3", "2.2.2.3")
83 assertLogEntry(t, entries[1], "example.org", "1.1.1.2", "2.2.2.2")
84 assertLogEntry(t, entries[2], "example.org", "1.1.1.1", "2.2.2.1")
85
86 // search by client IP (strict)
87 params = newSearchParams()
88 params.searchCriteria = append(params.searchCriteria, searchCriteria{
89 criteriaType: ctDomainOrClient,
90 strict: true,
91 value: "2.2.2.2",
92 })
93 entries, _ = l.search(params)
94 assert.Equal(t, 1, len(entries))
95 assertLogEntry(t, entries[0], "example.org", "1.1.1.2", "2.2.2.2")
96
97 // search by client IP (part of)
98 params = newSearchParams()
99 params.searchCriteria = append(params.searchCriteria, searchCriteria{
100 criteriaType: ctDomainOrClient,
101 strict: false,
102 value: "2.2.2",
103 })
104 entries, _ = l.search(params)
105 assert.Equal(t, 4, len(entries))
106 assertLogEntry(t, entries[0], "example.com", "1.1.1.4", "2.2.2.4")
107 assertLogEntry(t, entries[1], "test.example.org", "1.1.1.3", "2.2.2.3")
108 assertLogEntry(t, entries[2], "example.org", "1.1.1.2", "2.2.2.2")
109 assertLogEntry(t, entries[3], "example.org", "1.1.1.1", "2.2.2.1")
110 }
111
112 func TestQueryLogOffsetLimit(t *testing.T) {
113 conf := Config{
114 Enabled: true,
115 Interval: 1,
116 MemSize: 100,
117 }
118 conf.BaseDir = prepareTestDir()
119 defer func() { _ = os.RemoveAll(conf.BaseDir) }()
120 l := newQueryLog(conf)
121
122 // add 10 entries to the log
123 for i := 0; i < 10; i++ {
124 addEntry(l, "second.example.org", "1.1.1.1", "2.2.2.1")
125 }
126 // write them to disk (first file)
127 _ = l.flushLogBuffer(true)
128 // add 10 more entries to the log (memory)
129 for i := 0; i < 10; i++ {
130 addEntry(l, "first.example.org", "1.1.1.1", "2.2.2.1")
131 }
132
133 // First page
134 params := newSearchParams()
135 params.offset = 0
136 params.limit = 10
137 entries, _ := l.search(params)
138 assert.Equal(t, 10, len(entries))
139 assert.Equal(t, entries[0].QHost, "first.example.org")
140 assert.Equal(t, entries[9].QHost, "first.example.org")
141
142 // Second page
143 params.offset = 10
144 params.limit = 10
145 entries, _ = l.search(params)
146 assert.Equal(t, 10, len(entries))
147 assert.Equal(t, entries[0].QHost, "second.example.org")
148 assert.Equal(t, entries[9].QHost, "second.example.org")
149
150 // Second and a half page
151 params.offset = 15
152 params.limit = 10
153 entries, _ = l.search(params)
154 assert.Equal(t, 5, len(entries))
155 assert.Equal(t, entries[0].QHost, "second.example.org")
156 assert.Equal(t, entries[4].QHost, "second.example.org")
157
158 // Third page
159 params.offset = 20
160 params.limit = 10
161 entries, _ = l.search(params)
162 assert.Equal(t, 0, len(entries))
163 }
164
165 func TestQueryLogMaxFileScanEntries(t *testing.T) {
166 conf := Config{
167 Enabled: true,
168 FileEnabled: true,
169 Interval: 1,
170 MemSize: 100,
171 }
172 conf.BaseDir = prepareTestDir()
173 defer func() { _ = os.RemoveAll(conf.BaseDir) }()
174 l := newQueryLog(conf)
175
176 // add 10 entries to the log
177 for i := 0; i < 10; i++ {
178 addEntry(l, "example.org", "1.1.1.1", "2.2.2.1")
179 }
180 // write them to disk (first file)
181 _ = l.flushLogBuffer(true)
182
183 params := newSearchParams()
184 params.maxFileScanEntries = 5 // do not scan more than 5 records
185 entries, _ := l.search(params)
186 assert.Equal(t, 5, len(entries))
187
188 params.maxFileScanEntries = 0 // disable the limit
189 entries, _ = l.search(params)
190 assert.Equal(t, 10, len(entries))
191 }
192
193 func TestQueryLogFileDisabled(t *testing.T) {
194 conf := Config{
195 Enabled: true,
196 FileEnabled: false,
197 Interval: 1,
198 MemSize: 2,
199 }
200 conf.BaseDir = prepareTestDir()
201 defer func() { _ = os.RemoveAll(conf.BaseDir) }()
202 l := newQueryLog(conf)
203
204 addEntry(l, "example1.org", "1.1.1.1", "2.2.2.1")
205 addEntry(l, "example2.org", "1.1.1.1", "2.2.2.1")
206 addEntry(l, "example3.org", "1.1.1.1", "2.2.2.1")
207 // the oldest entry is now removed from mem buffer
208
209 params := newSearchParams()
210 ll, _ := l.search(params)
211 assert.Equal(t, 2, len(ll))
212 assert.Equal(t, "example3.org", ll[0].QHost)
213 assert.Equal(t, "example2.org", ll[1].QHost)
214 }
215
216 func addEntry(l *queryLog, host, answerStr, client string) {
217 q := dns.Msg{}
218 q.Question = append(q.Question, dns.Question{
219 Name: host + ".",
220 Qtype: dns.TypeA,
221 Qclass: dns.ClassINET,
222 })
223
224 a := dns.Msg{}
225 a.Question = append(a.Question, q.Question[0])
226 answer := new(dns.A)
227 answer.Hdr = dns.RR_Header{
228 Name: q.Question[0].Name,
229 Rrtype: dns.TypeA,
230 Class: dns.ClassINET,
231 }
232 answer.A = net.ParseIP(answerStr)
233 a.Answer = append(a.Answer, answer)
234 res := dnsfilter.Result{
235 IsFiltered: true,
236 Rule: "SomeRule",
237 Reason: dnsfilter.ReasonRewrite,
238 ServiceName: "SomeService",
239 FilterID: 1,
240 }
241 params := AddParams{
242 Question: &q,
243 Answer: &a,
244 OrigAnswer: &a,
245 Result: &res,
246 ClientIP: net.ParseIP(client),
247 Upstream: "upstream",
248 }
249 l.Add(params)
250 }
251
252 func assertLogEntry(t *testing.T, entry *logEntry, host, answer, client string) bool {
253 assert.Equal(t, host, entry.QHost)
254 assert.Equal(t, client, entry.IP)
255 assert.Equal(t, "A", entry.QType)
256 assert.Equal(t, "IN", entry.QClass)
257
258 msg := new(dns.Msg)
259 assert.Nil(t, msg.Unpack(entry.Answer))
260 assert.Equal(t, 1, len(msg.Answer))
261 ip := proxyutil.GetIPFromDNSRecord(msg.Answer[0])
262 assert.NotNil(t, ip)
263 assert.Equal(t, answer, ip.String())
264 return true
265 }