AdGuardHome/internal/filtering/filter_test.go

176 lines
3.9 KiB
Go
Raw Normal View History

2022-09-29 15:36:01 +01:00
package filtering
import (
"net"
"net/http"
"net/url"
"os"
"path/filepath"
"testing"
"time"
2023-01-19 12:04:46 +00:00
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
2023-09-07 15:13:48 +01:00
// testTimeout is the common timeout for tests.
const testTimeout = 5 * time.Second
2023-01-19 12:04:46 +00:00
// serveHTTPLocally starts a new HTTP server, that handles its index with h. It
// also gracefully closes the listener when the test under t finishes.
func serveHTTPLocally(t *testing.T, h http.Handler) (urlStr string) {
t.Helper()
2022-11-02 13:18:02 +00:00
l, err := net.Listen("tcp", ":0")
require.NoError(t, err)
2022-11-02 13:18:02 +00:00
go func() { _ = http.Serve(l, h) }()
testutil.CleanupAndRequireSuccess(t, l.Close)
2022-11-02 13:18:02 +00:00
addr := l.Addr()
2023-01-19 12:04:46 +00:00
require.IsType(t, (*net.TCPAddr)(nil), addr)
return (&url.URL{
Scheme: aghhttp.SchemeHTTP,
Host: addr.String(),
}).String()
}
2022-11-02 13:18:02 +00:00
2023-01-19 12:04:46 +00:00
// serveFiltersLocally is a helper that concurrently listens on a free port to
// respond with fltContent.
func serveFiltersLocally(t *testing.T, fltContent []byte) (urlStr string) {
t.Helper()
return serveHTTPLocally(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
pt := testutil.PanicT{}
n, werr := w.Write(fltContent)
require.NoError(pt, werr)
require.Equal(pt, len(fltContent), n)
}))
}
2023-09-07 15:13:48 +01:00
// updateAndAssert loads filter content from its URL and then asserts rules
// count.
func updateAndAssert(
t *testing.T,
dnsFilter *DNSFilter,
f *FilterYAML,
wantUpd require.BoolAssertionFunc,
wantRulesCount int,
) {
t.Helper()
2023-09-07 15:13:48 +01:00
ok, err := dnsFilter.update(f)
require.NoError(t, err)
wantUpd(t, ok)
2023-09-07 15:13:48 +01:00
assert.Equal(t, wantRulesCount, f.RulesCount)
2022-09-29 15:36:01 +01:00
2023-09-07 15:13:48 +01:00
dir, err := os.ReadDir(filepath.Join(dnsFilter.conf.DataDir, filterDir))
2022-09-29 15:36:01 +01:00
require.NoError(t, err)
2023-09-07 15:13:48 +01:00
require.FileExists(t, f.Path(dnsFilter.conf.DataDir))
2023-09-07 15:13:48 +01:00
assert.Len(t, dir, 1)
2023-09-07 15:13:48 +01:00
err = dnsFilter.load(f)
require.NoError(t, err)
}
2023-09-07 15:13:48 +01:00
// newDNSFilter returns a new properly initialized DNS filter instance.
func newDNSFilter(t *testing.T) (d *DNSFilter) {
t.Helper()
2023-09-07 15:13:48 +01:00
dnsFilter, err := New(&Config{
DataDir: t.TempDir(),
HTTPClient: &http.Client{
Timeout: testTimeout,
},
}, nil)
require.NoError(t, err)
2023-09-07 15:13:48 +01:00
return dnsFilter
}
2023-09-07 15:13:48 +01:00
func TestDNSFilter_Update(t *testing.T) {
const content = `||example.org^$third-party
# Inline comment example
||example.com^$third-party
0.0.0.0 example.com
`
2023-09-07 15:13:48 +01:00
fltContent := []byte(content)
addr := serveFiltersLocally(t, fltContent)
f := &FilterYAML{
URL: addr,
Name: "test-filter",
}
2023-09-07 15:13:48 +01:00
dnsFilter := newDNSFilter(t)
t.Run("download", func(t *testing.T) {
2023-09-07 15:13:48 +01:00
updateAndAssert(t, dnsFilter, f, require.True, 3)
})
t.Run("refresh_idle", func(t *testing.T) {
2023-09-07 15:13:48 +01:00
updateAndAssert(t, dnsFilter, f, require.False, 3)
})
t.Run("refresh_actually", func(t *testing.T) {
2022-11-02 13:18:02 +00:00
anotherContent := []byte(`||example.com^`)
oldURL := f.URL
2023-01-19 12:04:46 +00:00
f.URL = serveFiltersLocally(t, anotherContent)
2022-11-02 13:18:02 +00:00
t.Cleanup(func() { f.URL = oldURL })
2023-09-07 15:13:48 +01:00
updateAndAssert(t, dnsFilter, f, require.True, 1)
})
t.Run("load_unload", func(t *testing.T) {
2023-09-07 15:13:48 +01:00
err := dnsFilter.load(f)
require.NoError(t, err)
f.unload()
})
}
2023-09-07 15:13:48 +01:00
func TestFilterYAML_EnsureName(t *testing.T) {
dnsFilter := newDNSFilter(t)
t.Run("title_custom", func(t *testing.T) {
content := []byte("! Title: src-title\n||example.com^")
f := &FilterYAML{
URL: serveFiltersLocally(t, content),
Name: "user-custom",
}
updateAndAssert(t, dnsFilter, f, require.True, 1)
assert.Equal(t, "user-custom", f.Name)
})
t.Run("title_from_src", func(t *testing.T) {
content := []byte("! Title: src-title\n||example.com^")
f := &FilterYAML{
URL: serveFiltersLocally(t, content),
}
updateAndAssert(t, dnsFilter, f, require.True, 1)
assert.Equal(t, "src-title", f.Name)
})
t.Run("title_default", func(t *testing.T) {
content := []byte("||example.com^")
f := &FilterYAML{
URL: serveFiltersLocally(t, content),
}
updateAndAssert(t, dnsFilter, f, require.True, 1)
assert.Equal(t, "List 0", f.Name)
})
}