"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 }