Pull request #2450: Update all

Merge in DNS/adguard-home from upd-all to master

Squashed commit of the following:

commit 72a41e9e2d9b9a5fbf24fa69322f9c4dcf3f5fb7
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Aug 14 19:42:11 2025 +0300

    specs: export tests

commit aa729009306e492fd8a046b5e84f49be87e2a57f
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Aug 14 19:19:54 2025 +0300

    all: upd golibs

commit 526ce744cfdf167d1e5b763422092e6f450993a6
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Aug 14 17:21:57 2025 +0300

    all: upd scripts

commit ecc4312764b31e8b84e462321e3690a9b8eebbf6
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Aug 14 17:02:53 2025 +0300

    all: upd go & tools
This commit is contained in:
Eugene Burkov
2025-08-14 20:33:05 +03:00
parent 49e2ad6799
commit 5e2b4405fd
49 changed files with 522 additions and 487 deletions

View File

@@ -1,7 +1,7 @@
'name': 'build' 'name': 'build'
'env': 'env':
'GO_VERSION': '1.24.5' 'GO_VERSION': '1.24.6'
'NODE_VERSION': '20' 'NODE_VERSION': '20'
'on': 'on':

View File

@@ -1,7 +1,7 @@
'name': 'lint' 'name': 'lint'
'env': 'env':
'GO_VERSION': '1.24.5' 'GO_VERSION': '1.24.6'
'on': 'on':
'push': 'push':

2
.gitignore vendored
View File

@@ -37,5 +37,7 @@ AdGuardHome.exe
AdGuardHome.yaml* AdGuardHome.yaml*
coverage.txt coverage.txt
node_modules/ node_modules/
test-reports/
tmp/
!/build/gitkeep !/build/gitkeep

View File

@@ -18,6 +18,10 @@ See also the [v0.107.65 GitHub milestone][ms-v0.107.65].
NOTE: Add new changes BELOW THIS COMMENT. NOTE: Add new changes BELOW THIS COMMENT.
--> -->
### Security
- Go version has been updated to prevent the possibility of exploiting the Go vulnerabilities fixed in [1.24.6][go-1.24.6].
### Added ### Added
- A separate checkbox in the Web UI to enable or disable the global DNS response cache without losing the configured cache size. - A separate checkbox in the Web UI to enable or disable the global DNS response cache without losing the configured cache size.
@@ -53,6 +57,8 @@ In this release, the schema version has changed from 29 to 30.
[#7923]: https://github.com/AdguardTeam/AdGuardHome/issues/7923 [#7923]: https://github.com/AdguardTeam/AdGuardHome/issues/7923
[go-1.24.6]: https://groups.google.com/g/golang-announce/c/x5MKroML2yM
<!-- <!--
NOTE: Add new changes ABOVE THIS COMMENT. NOTE: Add new changes ABOVE THIS COMMENT.
--> -->

View File

@@ -27,7 +27,7 @@ DIST_DIR = dist
GOAMD64 = v1 GOAMD64 = v1
GOPROXY = https://proxy.golang.org|direct GOPROXY = https://proxy.golang.org|direct
GOTELEMETRY = off GOTELEMETRY = off
GOTOOLCHAIN = go1.24.5 GOTOOLCHAIN = go1.24.6
GPG_KEY = devteam@adguard.com GPG_KEY = devteam@adguard.com
GPG_KEY_PASSPHRASE = not-a-real-password GPG_KEY_PASSPHRASE = not-a-real-password
NPM = npm NPM = npm

View File

@@ -8,7 +8,7 @@
'variables': 'variables':
'channel': 'edge' 'channel': 'edge'
'dockerFrontend': 'adguard/home-js-builder:3.1' 'dockerFrontend': 'adguard/home-js-builder:3.1'
'dockerGo': 'adguard/go-builder:1.24.5--2' 'dockerGo': 'adguard/go-builder:1.24.6--1'
'stages': 'stages':
- 'Build frontend': - 'Build frontend':
@@ -279,7 +279,7 @@
'variables': 'variables':
'channel': 'beta' 'channel': 'beta'
'dockerFrontend': 'adguard/home-js-builder:3.1' 'dockerFrontend': 'adguard/home-js-builder:3.1'
'dockerGo': 'adguard/go-builder:1.24.5--2' 'dockerGo': 'adguard/go-builder:1.24.6--1'
# release-vX.Y.Z branches are the branches from which the actual final # release-vX.Y.Z branches are the branches from which the actual final
# release is built. # release is built.
- '^release-v[0-9]+\.[0-9]+\.[0-9]+': - '^release-v[0-9]+\.[0-9]+\.[0-9]+':
@@ -295,4 +295,4 @@
'variables': 'variables':
'channel': 'release' 'channel': 'release'
'dockerFrontend': 'adguard/home-js-builder:3.1' 'dockerFrontend': 'adguard/home-js-builder:3.1'
'dockerGo': 'adguard/go-builder:1.24.5--2' 'dockerGo': 'adguard/go-builder:1.24.6--1'

View File

@@ -6,7 +6,7 @@
'name': 'AdGuard Home - Build and run tests' 'name': 'AdGuard Home - Build and run tests'
'variables': 'variables':
'dockerFrontend': 'adguard/home-js-builder:3.1' 'dockerFrontend': 'adguard/home-js-builder:3.1'
'dockerGo': 'adguard/go-builder:1.24.5--2' 'dockerGo': 'adguard/go-builder:1.24.6--1'
'channel': 'development' 'channel': 'development'
'stages': 'stages':
@@ -67,6 +67,13 @@
'volumes': 'volumes':
'${system.GO_CACHE_DIR}': '${bamboo.cacheGo}' '${system.GO_CACHE_DIR}': '${bamboo.cacheGo}'
'${system.GO_PKG_CACHE_DIR}': '${bamboo.cacheGoPkg}' '${system.GO_PKG_CACHE_DIR}': '${bamboo.cacheGoPkg}'
'final-tasks':
- 'test-parser':
# The default pattern, '**/test-reports/*.xml', works, so don't set
# the test-results property.
'type': 'junit'
'ignore-time': true
- 'clean'
'key': 'GOTEST' 'key': 'GOTEST'
'other': 'other':
'clean-working-dir': true 'clean-working-dir': true
@@ -81,16 +88,26 @@
set -e -f -u -x set -e -f -u -x
make\ make \
GOMAXPROCS=1\ GOMAXPROCS=1 \
VERBOSE=1\ VERBOSE=1 \
go-deps go-tools go-lint go-deps go-tools go-lint
make\ make \
VERBOSE=1\ TEST_REPORTS_DIR="./test-reports/" \
go-test VERBOSE=1 \
'final-tasks': go-test \
- 'clean' ;
exit_code="$(cat ./test-reports/test-exit-code.txt)"
readonly exit_code
make VERBOSE=1 \
go-fuzz \
go-bench \
;
exit "$exit_code"
'requirements': 'requirements':
- 'adg-docker': 'true' - 'adg-docker': 'true'
@@ -234,5 +251,5 @@
# may need to build a few of these. # may need to build a few of these.
'variables': 'variables':
'dockerFrontend': 'adguard/home-js-builder:3.1' 'dockerFrontend': 'adguard/home-js-builder:3.1'
'dockerGo': 'adguard/go-builder:1.24.5--2' 'dockerGo': 'adguard/go-builder:1.24.6--1'
'channel': 'candidate' 'channel': 'candidate'

47
go.mod
View File

@@ -1,10 +1,11 @@
module github.com/AdguardTeam/AdGuardHome module github.com/AdguardTeam/AdGuardHome
go 1.24.5 go 1.24.6
require ( require (
github.com/AdguardTeam/dnsproxy v0.76.1 github.com/AdguardTeam/dnsproxy v0.76.1
github.com/AdguardTeam/golibs v0.32.15 // TODO(s.chzhen): Use osutil/executil and fakeos/fakeexec.
github.com/AdguardTeam/golibs v0.34.0
github.com/AdguardTeam/urlfilter v0.20.0 github.com/AdguardTeam/urlfilter v0.20.0
github.com/NYTimes/gziphandler v1.1.1 github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.4.0 github.com/ameshkov/dnscrypt/v2 v2.4.0
@@ -32,21 +33,21 @@ require (
github.com/stretchr/testify v1.10.0 github.com/stretchr/testify v1.10.0
github.com/ti-mo/netfilter v0.5.3 github.com/ti-mo/netfilter v0.5.3
go.etcd.io/bbolt v1.4.1 go.etcd.io/bbolt v1.4.1
golang.org/x/crypto v0.39.0 golang.org/x/crypto v0.41.0
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b golang.org/x/exp v0.0.0-20250813145105-42675adae3e6
golang.org/x/net v0.41.0 golang.org/x/net v0.43.0
golang.org/x/sys v0.33.0 golang.org/x/sys v0.35.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
howett.net/plist v1.0.1 howett.net/plist v1.0.1
) )
require ( require (
cloud.google.com/go v0.121.3 // indirect cloud.google.com/go v0.121.5 // indirect
cloud.google.com/go/ai v0.12.1 // indirect cloud.google.com/go/ai v0.12.1 // indirect
cloud.google.com/go/auth v0.16.2 // indirect cloud.google.com/go/auth v0.16.4 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/compute/metadata v0.7.0 // indirect cloud.google.com/go/compute/metadata v0.8.0 // indirect
cloud.google.com/go/longrunning v0.6.7 // indirect cloud.google.com/go/longrunning v0.6.7 // indirect
github.com/BurntSushi/toml v1.5.0 // indirect github.com/BurntSushi/toml v1.5.0 // indirect
github.com/ameshkov/dnsstamps v1.0.3 // indirect github.com/ameshkov/dnsstamps v1.0.3 // indirect
@@ -61,7 +62,7 @@ require (
github.com/google/generative-ai-go v0.20.1 // indirect github.com/google/generative-ai-go v0.20.1 // indirect
github.com/google/s2a-go v0.1.9 // indirect github.com/google/s2a-go v0.1.9 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.14.2 // indirect github.com/googleapis/gax-go/v2 v2.15.0 // indirect
github.com/gookit/color v1.5.4 // indirect github.com/gookit/color v1.5.4 // indirect
github.com/gordonklaus/ineffassign v0.1.0 // indirect github.com/gordonklaus/ineffassign v0.1.0 // indirect
github.com/josharian/native v1.1.0 // indirect github.com/josharian/native v1.1.0 // indirect
@@ -75,7 +76,7 @@ require (
github.com/quic-go/qpack v0.5.1 // indirect github.com/quic-go/qpack v0.5.1 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/securego/gosec/v2 v2.22.5 // indirect github.com/securego/gosec/v2 v2.22.8 // indirect
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
github.com/uudashr/gocognit v1.2.0 // indirect github.com/uudashr/gocognit v1.2.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
@@ -86,22 +87,22 @@ require (
go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect
go.opentelemetry.io/otel/trace v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect
go.uber.org/mock v0.5.2 // indirect go.uber.org/mock v0.5.2 // indirect
golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b // indirect golang.org/x/exp/typeparams v0.0.0-20250813145105-42675adae3e6 // indirect
golang.org/x/mod v0.25.0 // indirect golang.org/x/mod v0.27.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.15.0 // indirect golang.org/x/sync v0.16.0 // indirect
golang.org/x/telemetry v0.0.0-20250708141652-5a6bbb13955f // indirect golang.org/x/telemetry v0.0.0-20250813145757-41cd51e6ab6a // indirect
golang.org/x/term v0.32.0 // indirect golang.org/x/term v0.34.0 // indirect
golang.org/x/text v0.26.0 // indirect golang.org/x/text v0.28.0 // indirect
golang.org/x/time v0.12.0 // indirect golang.org/x/time v0.12.0 // indirect
golang.org/x/tools v0.34.0 // indirect golang.org/x/tools v0.36.0 // indirect
golang.org/x/vuln v1.1.4 // indirect golang.org/x/vuln v1.1.4 // indirect
gonum.org/v1/gonum v0.16.0 // indirect gonum.org/v1/gonum v0.16.0 // indirect
google.golang.org/api v0.240.0 // indirect google.golang.org/api v0.247.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a // indirect
google.golang.org/grpc v1.73.0 // indirect google.golang.org/grpc v1.74.2 // indirect
google.golang.org/protobuf v1.36.6 // indirect google.golang.org/protobuf v1.36.7 // indirect
honnef.co/go/tools v0.6.1 // indirect honnef.co/go/tools v0.6.1 // indirect
mvdan.cc/editorconfig v0.3.0 // indirect mvdan.cc/editorconfig v0.3.0 // indirect
mvdan.cc/gofumpt v0.8.0 // indirect mvdan.cc/gofumpt v0.8.0 // indirect

100
go.sum
View File

@@ -1,19 +1,19 @@
cloud.google.com/go v0.121.3 h1:84RD+hQXNdY5Sw/MWVAx5O9Aui/rd5VQ9HEcdN19afo= cloud.google.com/go v0.121.5 h1:KU9tFP5NeZiVDSWcsgjJ2P/HosAlD4fCGBimBlGiNXA=
cloud.google.com/go v0.121.3/go.mod h1:6vWF3nJWRrEUv26mMB3FEIU/o1MQNVPG1iHdisa2SJc= cloud.google.com/go v0.121.5/go.mod h1:coChdst4Ea5vUpiALcYKXEpR1S9ZgXbhEzzMcMR66vI=
cloud.google.com/go/ai v0.12.1 h1:m1n/VjUuHS+pEO/2R4/VbuuEIkgk0w67fDQvFaMngM0= cloud.google.com/go/ai v0.12.1 h1:m1n/VjUuHS+pEO/2R4/VbuuEIkgk0w67fDQvFaMngM0=
cloud.google.com/go/ai v0.12.1/go.mod h1:5vIPNe1ZQsVZqCliXIPL4QnhObQQY4d9hAGHdVc4iw4= cloud.google.com/go/ai v0.12.1/go.mod h1:5vIPNe1ZQsVZqCliXIPL4QnhObQQY4d9hAGHdVc4iw4=
cloud.google.com/go/auth v0.16.2 h1:QvBAGFPLrDeoiNjyfVunhQ10HKNYuOwZ5noee0M5df4= cloud.google.com/go/auth v0.16.4 h1:fXOAIQmkApVvcIn7Pc2+5J8QTMVbUGLscnSVNl11su8=
cloud.google.com/go/auth v0.16.2/go.mod h1:sRBas2Y1fB1vZTdurouM0AzuYQBMZinrUYL8EufhtEA= cloud.google.com/go/auth v0.16.4/go.mod h1:j10ncYwjX/g3cdX7GpEzsdM+d+ZNsXAbb6qXA7p1Y5M=
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= cloud.google.com/go/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA=
cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw=
cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
github.com/AdguardTeam/dnsproxy v0.76.1 h1:ms5vgdbYYXrKGPEpMFqUeql2j3aSfK1tGbCKju9rUgM= github.com/AdguardTeam/dnsproxy v0.76.1 h1:ms5vgdbYYXrKGPEpMFqUeql2j3aSfK1tGbCKju9rUgM=
github.com/AdguardTeam/dnsproxy v0.76.1/go.mod h1:9Mw3wQMTYwM/HR9FdtatQAd+m0S8mbwq2J+UZiy/gXc= github.com/AdguardTeam/dnsproxy v0.76.1/go.mod h1:9Mw3wQMTYwM/HR9FdtatQAd+m0S8mbwq2J+UZiy/gXc=
github.com/AdguardTeam/golibs v0.32.15 h1:arDRDWiZCH3g5Onr8AqMnOHhaOppNoBpgC3DNhmeDeA= github.com/AdguardTeam/golibs v0.34.0 h1:JQK024DkTYxE7vsPVsYsoyDHW/53Nun7OYb9qscniK8=
github.com/AdguardTeam/golibs v0.32.15/go.mod h1:G9CzUOzx87J+2u+eClJrrwWD7lMbROvuUnT8uvDUzIA= github.com/AdguardTeam/golibs v0.34.0/go.mod h1:K4C2EbfSEM1zY5YXoti9SfbTAHN/kIX97LpDtCwORrM=
github.com/AdguardTeam/urlfilter v0.20.0 h1:X32qiuVCVd8WDYCEsbdZKfXMzwdVqrdulamtUi4rmzs= github.com/AdguardTeam/urlfilter v0.20.0 h1:X32qiuVCVd8WDYCEsbdZKfXMzwdVqrdulamtUi4rmzs=
github.com/AdguardTeam/urlfilter v0.20.0/go.mod h1:gjrywLTxfJh6JOkwi9SU+frhP7kVVEZ5exFGkR99qpk= github.com/AdguardTeam/urlfilter v0.20.0/go.mod h1:gjrywLTxfJh6JOkwi9SU+frhP7kVVEZ5exFGkR99qpk=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
@@ -85,8 +85,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
github.com/googleapis/gax-go/v2 v2.14.2 h1:eBLnkZ9635krYIPD+ag1USrOAI0Nr0QYF3+/3GqO0k0= github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
github.com/googleapis/gax-go/v2 v2.14.2/go.mod h1:ON64QhlJkhVtSqp4v1uaK92VyZ2gmvDQsweuyLV+8+w= github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
github.com/gordonklaus/ineffassign v0.1.0 h1:y2Gd/9I7MdY1oEIt+n+rowjBNDcLQq3RsH5hwJd0f9s= github.com/gordonklaus/ineffassign v0.1.0 h1:y2Gd/9I7MdY1oEIt+n+rowjBNDcLQq3RsH5hwJd0f9s=
@@ -128,8 +128,8 @@ github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE=
github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE= github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus= github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8= github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
@@ -149,8 +149,8 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/securego/gosec/v2 v2.22.5 h1:ySws9uwOeE42DsG54v2moaJfh7r08Ev7SAYJuoMDfRA= github.com/securego/gosec/v2 v2.22.8 h1:3NMpmfXO8wAVFZPNsd3EscOTa32Jyo6FLLlW53bexMI=
github.com/securego/gosec/v2 v2.22.5/go.mod h1:AWfgrFsVewk5LKobsPWlygCHt8K91boVPyL6GUZG5NY= github.com/securego/gosec/v2 v2.22.8/go.mod h1:ZAw8K2ikuH9qDlfdV87JmNghnVfKB1XC7+TVzk6Utto=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk= github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
@@ -203,17 +203,17 @@ go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 h1:SbTAbRFnd5kjQXbczszQ0hdk3ctwYf3qBNH9jIsGclE=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/exp v0.0.0-20250813145105-42675adae3e6/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4=
golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b h1:KdrhdYPDUvJTvrDK9gdjfFd6JTk8vA1WJoldYSi0kHo= golang.org/x/exp/typeparams v0.0.0-20250813145105-42675adae3e6 h1:zAfbUfwhYzU4abt1UJxExk7WVbeTsYEnOPySl6RVucI=
golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b/go.mod h1:LKZHyeOpPuZcMgxeHjJp4p5yvxrCX1xDvH10zYHhjjQ= golang.org/x/exp/typeparams v0.0.0-20250813145105-42675adae3e6/go.mod h1:4Mzdyp/6jzw9auFDJ3OMF5qksa7UvPnzKqTVGcb04ms=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -221,14 +221,14 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -240,25 +240,29 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20250708141652-5a6bbb13955f h1:GnwFSf1cKD9qa+VRJWGjDBK0OHWJgTMaj49bSkN3agw= golang.org/x/telemetry v0.0.0-20250813145757-41cd51e6ab6a h1:60aHXv7uIB0ngdMlalCWv6pSC/giLMowErJBA/5xbPQ=
golang.org/x/telemetry v0.0.0-20250708141652-5a6bbb13955f/go.mod h1:mUcjA5g0luJpMYCLjhH91f4t4RAUNp+zq9ZmUoqPD7M= golang.org/x/telemetry v0.0.0-20250813145757-41cd51e6ab6a/go.mod h1:JIJwPkb04vX0KeIBbQ7epGtgIjA8ihHbsAtW4A/lIQ4=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM=
golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=
golang.org/x/vuln v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I= golang.org/x/vuln v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I=
golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s= golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -267,18 +271,18 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/api v0.240.0 h1:PxG3AA2UIqT1ofIzWV2COM3j3JagKTKSwy7L6RHNXNU= google.golang.org/api v0.247.0 h1:tSd/e0QrUlLsrwMKmkbQhYVa109qIintOls2Wh6bngc=
google.golang.org/api v0.240.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= google.golang.org/api v0.247.0/go.mod h1:r1qZOPmxXffXg6xS5uhx16Fa/UFY8QU/K4bfKrnvovM=
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4=
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s=
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 h1:FiusG7LWj+4byqhbvmB+Q93B/mOxJLN2DTozDuZm4EU= google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a h1:DMCgtIAIQGZqJXMVzJF4MV8BlWoJh2ZuFiRdAleyr58=
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:kXqgZtrWaf6qS3jZOCnCH7WYfrvFjkC51bM8fz3RsCA= google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a/go.mod h1:y2yVLIE/CSMCPXaHnSKXxu1spLPnglFLegmgdY23uuE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY= google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a h1:tPE/Kp+x9dMSwUm/uM0JKK0IfdiJkwAbSMSeZBXXJXc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo=
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

View File

@@ -7,7 +7,8 @@ import (
"testing/fstest" "testing/fstest"
"github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/testutil/fakefs" "github.com/AdguardTeam/golibs/testutil"
"github.com/AdguardTeam/golibs/testutil/fakeio/fakefs"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -64,7 +65,7 @@ func TestHostsContainer_PathsToPatterns(t *testing.T) {
const errStat errors.Error = "bad file" const errStat errors.Error = "bad file"
badFS := &fakefs.StatFS{ badFS := &fakefs.StatFS{
OnOpen: func(_ string) (f fs.File, err error) { panic("not implemented") }, OnOpen: func(s string) (f fs.File, err error) { panic(testutil.UnexpectedCall(s)) },
OnStat: func(name string) (fi fs.FileInfo, err error) { OnStat: func(name string) (fi fs.FileInfo, err error) {
return nil, errStat return nil, errStat
}, },

View File

@@ -68,7 +68,9 @@ func TestNewHostsContainer(t *testing.T) {
} }
hc, err := aghnet.NewHostsContainer(testFS, &aghtest.FSWatcher{ hc, err := aghnet.NewHostsContainer(testFS, &aghtest.FSWatcher{
OnStart: func(_ context.Context) (_ error) { panic("not implemented") }, OnStart: func(ctx context.Context) (_ error) {
panic(testutil.UnexpectedCall(ctx))
},
OnEvents: onEvents, OnEvents: onEvents,
OnAdd: onAdd, OnAdd: onAdd,
OnShutdown: func(_ context.Context) (err error) { return nil }, OnShutdown: func(_ context.Context) (err error) { return nil },
@@ -95,10 +97,12 @@ func TestNewHostsContainer(t *testing.T) {
t.Run("nil_fs", func(t *testing.T) { t.Run("nil_fs", func(t *testing.T) {
require.Panics(t, func() { require.Panics(t, func() {
_, _ = aghnet.NewHostsContainer(nil, &aghtest.FSWatcher{ _, _ = aghnet.NewHostsContainer(nil, &aghtest.FSWatcher{
OnStart: func(_ context.Context) (_ error) { panic("not implemented") }, OnStart: func(ctx context.Context) (_ error) {
panic(testutil.UnexpectedCall(ctx))
},
// Those shouldn't panic. // Those shouldn't panic.
OnEvents: func() (e <-chan struct{}) { return nil }, OnEvents: func() (e <-chan struct{}) { return nil },
OnAdd: func(name string) (err error) { return nil }, OnAdd: func(_ string) (err error) { return nil },
OnShutdown: func(_ context.Context) (err error) { return nil }, OnShutdown: func(_ context.Context) (err error) { return nil },
}, p) }, p)
}) })
@@ -114,9 +118,9 @@ func TestNewHostsContainer(t *testing.T) {
const errOnAdd errors.Error = "error" const errOnAdd errors.Error = "error"
errWatcher := &aghtest.FSWatcher{ errWatcher := &aghtest.FSWatcher{
OnStart: func(_ context.Context) (_ error) { panic("not implemented") }, OnStart: func(ctx context.Context) (_ error) { panic(testutil.UnexpectedCall(ctx)) },
OnEvents: func() (e <-chan struct{}) { panic("not implemented") }, OnEvents: func() (_ <-chan struct{}) { panic(testutil.UnexpectedCall()) },
OnAdd: func(name string) (err error) { return errOnAdd }, OnAdd: func(_ string) (err error) { return errOnAdd },
OnShutdown: func(_ context.Context) (err error) { return nil }, OnShutdown: func(_ context.Context) (err error) { return nil },
} }
@@ -159,7 +163,7 @@ func TestHostsContainer_refresh(t *testing.T) {
t.Cleanup(func() { close(eventsCh) }) t.Cleanup(func() { close(eventsCh) })
w := &aghtest.FSWatcher{ w := &aghtest.FSWatcher{
OnStart: func(_ context.Context) (_ error) { panic("not implemented") }, OnStart: func(ctx context.Context) (_ error) { panic(testutil.UnexpectedCall(ctx)) },
OnEvents: func() (e <-chan event) { return eventsCh }, OnEvents: func() (e <-chan event) { return eventsCh },
OnAdd: func(name string) (err error) { OnAdd: func(name string) (err error) {
assert.Equal(t, "dir", name) assert.Equal(t, "dir", name)

View File

@@ -9,7 +9,7 @@ import (
"github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/testutil" "github.com/AdguardTeam/golibs/testutil"
"github.com/AdguardTeam/golibs/testutil/fakefs" "github.com/AdguardTeam/golibs/testutil/fakeio/fakefs"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -121,7 +121,7 @@ func TestIfaceSetStaticIP(t *testing.T) {
}, },
} }
panicFsys := &fakefs.FS{ panicFsys := &fakefs.FS{
OnOpen: func(name string) (fs.File, error) { panic("not implemented") }, OnOpen: func(name string) (_ fs.File, _ error) { panic(testutil.UnexpectedCall(name)) },
} }
testCases := []struct { testCases := []struct {

View File

@@ -19,11 +19,11 @@ import (
// substRootDirFS replaces the aghos.RootDirFS function used throughout the // substRootDirFS replaces the aghos.RootDirFS function used throughout the
// package with fsys for tests ran under t. // package with fsys for tests ran under t.
func substRootDirFS(t testing.TB, fsys fs.FS) { func substRootDirFS(tb testing.TB, fsys fs.FS) {
t.Helper() tb.Helper()
prev := rootDirFS prev := rootDirFS
t.Cleanup(func() { rootDirFS = prev }) tb.Cleanup(func() { rootDirFS = prev })
rootDirFS = fsys rootDirFS = fsys
} }
@@ -32,11 +32,11 @@ type RunCmdFunc func(cmd string, args ...string) (code int, out []byte, err erro
// substShell replaces the the aghos.RunCommand function used throughout the // substShell replaces the the aghos.RunCommand function used throughout the
// package with rc for tests ran under t. // package with rc for tests ran under t.
func substShell(t testing.TB, rc RunCmdFunc) { func substShell(tb testing.TB, rc RunCmdFunc) {
t.Helper() tb.Helper()
prev := aghosRunCommand prev := aghosRunCommand
t.Cleanup(func() { aghosRunCommand = prev }) tb.Cleanup(func() { aghosRunCommand = prev })
aghosRunCommand = rc aghosRunCommand = rc
} }
@@ -72,11 +72,11 @@ type ifaceAddrsFunc func() (ifaces []net.Addr, err error)
// substNetInterfaceAddrs replaces the the net.InterfaceAddrs function used // substNetInterfaceAddrs replaces the the net.InterfaceAddrs function used
// throughout the package with f for tests ran under t. // throughout the package with f for tests ran under t.
func substNetInterfaceAddrs(t *testing.T, f ifaceAddrsFunc) { func substNetInterfaceAddrs(tb testing.TB, f ifaceAddrsFunc) {
t.Helper() tb.Helper()
prev := netInterfaceAddrs prev := netInterfaceAddrs
t.Cleanup(func() { netInterfaceAddrs = prev }) tb.Cleanup(func() { netInterfaceAddrs = prev })
netInterfaceAddrs = f netInterfaceAddrs = f
} }

View File

@@ -43,14 +43,14 @@ func TestPendingFile(t *testing.T) {
// newInitialFile is a test helper that returns the path to the file containing // newInitialFile is a test helper that returns the path to the file containing
// [initialData]. // [initialData].
func newInitialFile(t *testing.T) (targetPath string) { func newInitialFile(tb testing.TB) (targetPath string) {
t.Helper() tb.Helper()
dir := t.TempDir() dir := tb.TempDir()
targetPath = filepath.Join(dir, "target") targetPath = filepath.Join(dir, "target")
err := os.WriteFile(targetPath, initialData, 0o644) err := os.WriteFile(targetPath, initialData, 0o644)
require.NoError(t, err) require.NoError(tb, err)
return targetPath return targetPath
} }

View File

@@ -34,16 +34,16 @@ func HostToIPs(host string) (ipv4, ipv6 netip.Addr) {
// StartHTTPServer is a helper that starts the HTTP server, which is configured // StartHTTPServer is a helper that starts the HTTP server, which is configured
// to return data on every request, and returns the client and server URL. // to return data on every request, and returns the client and server URL.
func StartHTTPServer(t testing.TB, data []byte) (c *http.Client, u *url.URL) { func StartHTTPServer(tb testing.TB, data []byte) (c *http.Client, u *url.URL) {
t.Helper() tb.Helper()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write(data) _, _ = w.Write(data)
})) }))
t.Cleanup(srv.Close) tb.Cleanup(srv.Close)
u, err := url.Parse(srv.URL) u, err := url.Parse(srv.URL)
require.NoError(t, err) require.NoError(tb, err)
return srv.Client(), u return srv.Client(), u
} }
@@ -55,8 +55,8 @@ const testTimeout = 1 * time.Second
// StartLocalhostUpstream is a test helper that starts a DNS server on // StartLocalhostUpstream is a test helper that starts a DNS server on
// localhost. // localhost.
func StartLocalhostUpstream(t *testing.T, h dns.Handler) (addr *url.URL) { func StartLocalhostUpstream(tb *testing.T, h dns.Handler) (addr *url.URL) {
t.Helper() tb.Helper()
startCh := make(chan netip.AddrPort) startCh := make(chan netip.AddrPort)
defer close(startCh) defer close(startCh)
@@ -83,12 +83,12 @@ func StartLocalhostUpstream(t *testing.T, h dns.Handler) (addr *url.URL) {
Host: addrPort.String(), Host: addrPort.String(),
} }
testutil.CleanupAndRequireSuccess(t, func() (err error) { return <-errCh }) testutil.CleanupAndRequireSuccess(tb, func() (err error) { return <-errCh })
testutil.CleanupAndRequireSuccess(t, srv.Shutdown) testutil.CleanupAndRequireSuccess(tb, srv.Shutdown)
case err := <-errCh: case err := <-errCh:
require.NoError(t, err) require.NoError(tb, err)
case <-time.After(testTimeout): case <-time.After(testTimeout):
require.FailNow(t, "timeout exceeded") require.FailNow(tb, "timeout exceeded")
} }
return addr return addr

View File

@@ -2,7 +2,6 @@ package aghtest
import ( import (
"context" "context"
"net"
"net/netip" "net/netip"
"time" "time"
@@ -15,14 +14,6 @@ import (
"github.com/miekg/dns" "github.com/miekg/dns"
) )
// Interface Mocks
//
// Keep entities in this file in alphabetic order.
// Module adguard-home
// Package aghos
// FSWatcher is a fake [aghos.FSWatcher] implementation for tests. // FSWatcher is a fake [aghos.FSWatcher] implementation for tests.
type FSWatcher struct { type FSWatcher struct {
OnStart func(ctx context.Context) (err error) OnStart func(ctx context.Context) (err error)
@@ -54,8 +45,6 @@ func (w *FSWatcher) Add(name string) (err error) {
return w.OnAdd(name) return w.OnAdd(name)
} }
// Package nextagh
// ServiceWithConfig is a fake [nextagh.ServiceWithConfig] implementation for // ServiceWithConfig is a fake [nextagh.ServiceWithConfig] implementation for
// tests. // tests.
type ServiceWithConfig[ConfigType any] struct { type ServiceWithConfig[ConfigType any] struct {
@@ -85,8 +74,6 @@ func (s *ServiceWithConfig[ConfigType]) Config() (c ConfigType) {
return s.OnConfig() return s.OnConfig()
} }
// Package client
// AddressProcessor is a fake [client.AddressProcessor] implementation for // AddressProcessor is a fake [client.AddressProcessor] implementation for
// tests. // tests.
type AddressProcessor struct { type AddressProcessor struct {
@@ -122,20 +109,6 @@ func (p *AddressUpdater) UpdateAddress(
p.OnUpdateAddress(ctx, ip, host, info) p.OnUpdateAddress(ctx, ip, host, info)
} }
// Package filtering
// Resolver is a fake [filtering.Resolver] implementation for tests.
type Resolver struct {
OnLookupIP func(ctx context.Context, network, host string) (ips []net.IP, err error)
}
// LookupIP implements the [filtering.Resolver] interface for *Resolver.
func (r *Resolver) LookupIP(ctx context.Context, network, host string) (ips []net.IP, err error) {
return r.OnLookupIP(ctx, network, host)
}
// Package rdns
// Exchanger is a fake [rdns.Exchanger] implementation for tests. // Exchanger is a fake [rdns.Exchanger] implementation for tests.
type Exchanger struct { type Exchanger struct {
OnExchange func(ip netip.Addr) (host string, ttl time.Duration, err error) OnExchange func(ip netip.Addr) (host string, ttl time.Duration, err error)
@@ -149,10 +122,6 @@ func (e *Exchanger) Exchange(ip netip.Addr) (host string, ttl time.Duration, err
return e.OnExchange(ip) return e.OnExchange(ip)
} }
// Module dnsproxy
// Package upstream
// UpstreamMock is a fake [upstream.Upstream] implementation for tests. // UpstreamMock is a fake [upstream.Upstream] implementation for tests.
// //
// TODO(a.garipov): Replace with all uses of Upstream with UpstreamMock and // TODO(a.garipov): Replace with all uses of Upstream with UpstreamMock and

View File

@@ -3,20 +3,12 @@ package aghtest_test
import ( import (
"github.com/AdguardTeam/AdGuardHome/internal/aghtest" "github.com/AdguardTeam/AdGuardHome/internal/aghtest"
"github.com/AdguardTeam/AdGuardHome/internal/client" "github.com/AdguardTeam/AdGuardHome/internal/client"
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
) )
// Put interface checks that cause import cycles here.
// type check
var _ filtering.Resolver = (*aghtest.Resolver)(nil)
// type check // type check
// //
// TODO(s.chzhen): It's here to avoid the import cycle. Remove it. // TODO(s.chzhen): Resolve the import cycles and move it to aghtest.
var _ client.AddressProcessor = (*aghtest.AddressProcessor)(nil) var (
_ client.AddressProcessor = (*aghtest.AddressProcessor)(nil)
// type check _ client.AddressUpdater = (*aghtest.AddressUpdater)(nil)
// )
// TODO(s.chzhen): It's here to avoid the import cycle. Remove it.
var _ client.AddressUpdater = (*aghtest.AddressUpdater)(nil)

View File

@@ -220,7 +220,7 @@ func NewErrorUpstream() (u *UpstreamMock) {
return &UpstreamMock{ return &UpstreamMock{
OnAddress: func() (addr string) { return "error.upstream.example" }, OnAddress: func() (addr string) { return "error.upstream.example" },
OnExchange: func(_ *dns.Msg) (resp *dns.Msg, err error) { OnExchange: func(_ *dns.Msg) (resp *dns.Msg, err error) {
return nil, errors.Error("test upstream error") return nil, ErrUpstream
}, },
OnClose: func() (err error) { return nil }, OnClose: func() (err error) { return nil },
} }

View File

@@ -24,12 +24,12 @@ var testdata fs.FS = os.DirFS("./testdata")
type RunCmdFunc func(cmd string, args ...string) (code int, out []byte, err error) type RunCmdFunc func(cmd string, args ...string) (code int, out []byte, err error)
// substShell replaces the the aghos.RunCommand function used throughout the // substShell replaces the the aghos.RunCommand function used throughout the
// package with rc for tests ran under t. // package with rc for tests ran under tb.
func substShell(t testing.TB, rc RunCmdFunc) { func substShell(tb testing.TB, rc RunCmdFunc) {
t.Helper() tb.Helper()
prev := aghosRunCommand prev := aghosRunCommand
t.Cleanup(func() { aghosRunCommand = prev }) tb.Cleanup(func() { aghosRunCommand = prev })
aghosRunCommand = rc aghosRunCommand = rc
} }

View File

@@ -1208,12 +1208,8 @@ func TestStorage_CustomUpstreamConfig(t *testing.T) {
} }
dhcp := &testDHCP{ dhcp := &testDHCP{
OnLeases: func() (ls []*dhcpsvc.Lease) { OnLeases: func() (_ []*dhcpsvc.Lease) { panic(testutil.UnexpectedCall()) },
panic("not implemented") OnHostBy: func(ip netip.Addr) (_ string) { panic(testutil.UnexpectedCall(ip)) },
},
OnHostBy: func(ip netip.Addr) (host string) {
panic("not implemented")
},
OnMACBy: func(ip netip.Addr) (mac net.HardwareAddr) { OnMACBy: func(ip netip.Addr) (mac net.HardwareAddr) {
return ipToMAC[ip] return ipToMAC[ip]
}, },

View File

@@ -242,8 +242,8 @@ func TestUpgradeSchema8to9(t *testing.T) {
} }
// assertEqualExcept removes entries from configs and compares them. // assertEqualExcept removes entries from configs and compares them.
func assertEqualExcept(t *testing.T, oldConf, newConf yobj, oldKeys, newKeys []string) { func assertEqualExcept(tb testing.TB, oldConf, newConf yobj, oldKeys, newKeys []string) {
t.Helper() tb.Helper()
for _, k := range oldKeys { for _, k := range oldKeys {
delete(oldConf, k) delete(oldConf, k)
@@ -252,7 +252,7 @@ func assertEqualExcept(t *testing.T, oldConf, newConf yobj, oldKeys, newKeys []s
delete(newConf, k) delete(newConf, k)
} }
assert.Equal(t, oldConf, newConf) assert.Equal(tb, oldConf, newConf)
} }
func testDiskConf(schemaVersion int) (diskConf yobj) { func testDiskConf(schemaVersion int) (diskConf yobj) {

View File

@@ -54,6 +54,8 @@ func getField[T any](t require.TestingT, obj any, indexes ...any) (val T) {
} }
func TestMigrateConfig_Migrate(t *testing.T) { func TestMigrateConfig_Migrate(t *testing.T) {
t.Parallel()
const ( const (
inputFileName = "input.yml" inputFileName = "input.yml"
outputFileName = "output.yml" outputFileName = "output.yml"
@@ -201,6 +203,8 @@ func TestMigrateConfig_Migrate(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel()
body, err := fs.ReadFile(testdata, path.Join(t.Name(), inputFileName)) body, err := fs.ReadFile(testdata, path.Join(t.Name(), inputFileName))
require.NoError(t, err) require.NoError(t, err)

View File

@@ -34,18 +34,18 @@ func defaultResponse() *dhcpStatusResponse {
// handleLease is the helper function that calls handler with provided static // handleLease is the helper function that calls handler with provided static
// lease as body and returns modified response recorder. // lease as body and returns modified response recorder.
func handleLease(t *testing.T, lease *leaseStatic, handler http.HandlerFunc) (w *httptest.ResponseRecorder) { func handleLease(tb testing.TB, lease *leaseStatic, handler http.HandlerFunc) (w *httptest.ResponseRecorder) {
t.Helper() tb.Helper()
w = httptest.NewRecorder() w = httptest.NewRecorder()
b := &bytes.Buffer{} b := &bytes.Buffer{}
err := json.NewEncoder(b).Encode(lease) err := json.NewEncoder(b).Encode(lease)
require.NoError(t, err) require.NoError(tb, err)
var r *http.Request var r *http.Request
r, err = http.NewRequest(http.MethodPost, "", b) r, err = http.NewRequest(http.MethodPost, "", b)
require.NoError(t, err) require.NoError(tb, err)
handler(w, r) handler(w, r)

View File

@@ -44,12 +44,12 @@ func defaultV4ServerConf() (conf *V4ServerConf) {
// defaultSrv prepares the default DHCPServer to use in tests. The underlying // defaultSrv prepares the default DHCPServer to use in tests. The underlying
// type of s is *v4Server. // type of s is *v4Server.
func defaultSrv(t *testing.T) (s DHCPServer) { func defaultSrv(tb testing.TB) (s DHCPServer) {
t.Helper() tb.Helper()
var err error var err error
s, err = v4Create(defaultV4ServerConf()) s, err = v4Create(defaultV4ServerConf())
require.NoError(t, err) require.NoError(tb, err)
return s return s
} }

View File

@@ -27,16 +27,16 @@ const maxDNS64SynTTL uint32 = 600
// newRR is a helper that creates a new dns.RR with the given name, qtype, ttl // newRR is a helper that creates a new dns.RR with the given name, qtype, ttl
// and value. It fails the test if the qtype is not supported or the type of // and value. It fails the test if the qtype is not supported or the type of
// value doesn't match the qtype. // value doesn't match the qtype.
func newRR(t *testing.T, name string, qtype uint16, ttl uint32, val any) (rr dns.RR) { func newRR(tb testing.TB, name string, qtype uint16, ttl uint32, val any) (rr dns.RR) {
t.Helper() tb.Helper()
switch qtype { switch qtype {
case dns.TypeA: case dns.TypeA:
rr = &dns.A{A: testutil.RequireTypeAssert[net.IP](t, val)} rr = &dns.A{A: testutil.RequireTypeAssert[net.IP](tb, val)}
case dns.TypeAAAA: case dns.TypeAAAA:
rr = &dns.AAAA{AAAA: testutil.RequireTypeAssert[net.IP](t, val)} rr = &dns.AAAA{AAAA: testutil.RequireTypeAssert[net.IP](tb, val)}
case dns.TypeCNAME: case dns.TypeCNAME:
rr = &dns.CNAME{Target: testutil.RequireTypeAssert[string](t, val)} rr = &dns.CNAME{Target: testutil.RequireTypeAssert[string](tb, val)}
case dns.TypeSOA: case dns.TypeSOA:
rr = &dns.SOA{ rr = &dns.SOA{
Ns: "ns." + name, Ns: "ns." + name,
@@ -48,9 +48,9 @@ func newRR(t *testing.T, name string, qtype uint16, ttl uint32, val any) (rr dns
Minttl: 1, Minttl: 1,
} }
case dns.TypePTR: case dns.TypePTR:
rr = &dns.PTR{Ptr: testutil.RequireTypeAssert[string](t, val)} rr = &dns.PTR{Ptr: testutil.RequireTypeAssert[string](tb, val)}
default: default:
t.Fatalf("unsupported qtype: %d", qtype) tb.Fatalf("unsupported qtype: %d", qtype)
} }
*rr.Header() = dns.RR_Header{ *rr.Header() = dns.RR_Header{
@@ -325,7 +325,7 @@ func TestServer_dns64WithDisabledRDNS(t *testing.T) {
// Shouldn't go to upstream at all. // Shouldn't go to upstream at all.
panicHdlr := dns.HandlerFunc(func(w dns.ResponseWriter, m *dns.Msg) { panicHdlr := dns.HandlerFunc(func(w dns.ResponseWriter, m *dns.Msg) {
panic("not implemented") panic(testutil.UnexpectedCall(w, m))
}) })
upsAddr := aghtest.StartLocalhostUpstream(t, panicHdlr).String() upsAddr := aghtest.StartLocalhostUpstream(t, panicHdlr).String()
localUpsAddr := aghtest.StartLocalhostUpstream(t, panicHdlr).String() localUpsAddr := aghtest.StartLocalhostUpstream(t, panicHdlr).String()

View File

@@ -104,13 +104,16 @@ func (c *clientsContainer) ClearUpstreamCache() {
c.OnClearUpstreamCache() c.OnClearUpstreamCache()
} }
func startDeferStop(t *testing.T, s *Server) { // startDeferStop starts the server and stops it when the test ends.
t.Helper() //
// TODO(e.burkov): Replace with [servicetest.RequireRun].
func startDeferStop(tb testing.TB, s *Server) {
tb.Helper()
err := s.Start(testutil.ContextWithTimeout(t, testTimeout)) err := s.Start(testutil.ContextWithTimeout(tb, testTimeout))
require.NoError(t, err) require.NoError(tb, err)
testutil.CleanupAndRequireSuccess(t, func() (err error) { testutil.CleanupAndRequireSuccess(tb, func() (err error) {
return s.Stop(testutil.ContextWithTimeout(t, testTimeout)) return s.Stop(testutil.ContextWithTimeout(tb, testTimeout))
}) })
} }
@@ -130,11 +133,11 @@ func emptyFilteringBlockedServices() (bsvc *filtering.BlockedServices) {
// *Server for use in tests, given the provided parameters. It also populates // *Server for use in tests, given the provided parameters. It also populates
// the filtering configuration with default parameters. // the filtering configuration with default parameters.
func createTestServer( func createTestServer(
t *testing.T, tb testing.TB,
filterConf *filtering.Config, filterConf *filtering.Config,
forwardConf ServerConfig, forwardConf ServerConfig,
) (s *Server) { ) (s *Server) {
t.Helper() tb.Helper()
filterConf.Logger = cmp.Or(filterConf.Logger, testLogger) filterConf.Logger = cmp.Or(filterConf.Logger, testLogger)
@@ -155,14 +158,14 @@ func createTestServer(
} }
f, err := filtering.New(filterConf, filters) f, err := filtering.New(filterConf, filters)
require.NoError(t, err) require.NoError(tb, err)
f.SetEnabled(true) f.SetEnabled(true)
dhcp := &testDHCP{ dhcp := &testDHCP{
OnEnabled: func() (ok bool) { return false }, OnEnabled: func() (ok bool) { return false },
OnHostByIP: func(ip netip.Addr) (host string) { return "" }, OnHostByIP: func(ip netip.Addr) (host string) { return "" },
OnIPByHost: func(host string) (ip netip.Addr) { panic("not implemented") }, OnIPByHost: func(host string) (_ netip.Addr) { panic(testutil.UnexpectedCall(host)) },
} }
s, err = NewServer(DNSCreateParams{ s, err = NewServer(DNSCreateParams{
DHCPServer: dhcp, DHCPServer: dhcp,
@@ -170,23 +173,23 @@ func createTestServer(
PrivateNets: netutil.SubnetSetFunc(netutil.IsLocallyServed), PrivateNets: netutil.SubnetSetFunc(netutil.IsLocallyServed),
Logger: testLogger, Logger: testLogger,
}) })
require.NoError(t, err) require.NoError(tb, err)
err = s.Prepare(testutil.ContextWithTimeout(t, testTimeout), &forwardConf) err = s.Prepare(testutil.ContextWithTimeout(tb, testTimeout), &forwardConf)
require.NoError(t, err) require.NoError(tb, err)
return s return s
} }
func createServerTLSConfig(t *testing.T) (*tls.Config, []byte, []byte) { func createServerTLSConfig(tb testing.TB) (*tls.Config, []byte, []byte) {
t.Helper() tb.Helper()
privateKey, err := rsa.GenerateKey(rand.Reader, 2048) privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
require.NoErrorf(t, err, "cannot generate RSA key: %s", err) require.NoErrorf(tb, err, "cannot generate RSA key: %s", err)
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
require.NoErrorf(t, err, "failed to generate serial number: %s", err) require.NoErrorf(tb, err, "failed to generate serial number: %s", err)
notBefore := time.Now() notBefore := time.Now()
notAfter := notBefore.Add(5 * 365 * timeutil.Day) notAfter := notBefore.Add(5 * 365 * timeutil.Day)
@@ -207,13 +210,13 @@ func createServerTLSConfig(t *testing.T) (*tls.Config, []byte, []byte) {
template.DNSNames = append(template.DNSNames, tlsServerName) template.DNSNames = append(template.DNSNames, tlsServerName)
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(privateKey), privateKey) derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(privateKey), privateKey)
require.NoErrorf(t, err, "failed to create certificate: %s", err) require.NoErrorf(tb, err, "failed to create certificate: %s", err)
certPem := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certPem := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
keyPem := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}) keyPem := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)})
cert, err := tls.X509KeyPair(certPem, keyPem) cert, err := tls.X509KeyPair(certPem, keyPem)
require.NoErrorf(t, err, "failed to create certificate: %s", err) require.NoErrorf(tb, err, "failed to create certificate: %s", err)
return &tls.Config{ return &tls.Config{
Certificates: []tls.Certificate{cert}, Certificates: []tls.Certificate{cert},
@@ -222,18 +225,18 @@ func createServerTLSConfig(t *testing.T) (*tls.Config, []byte, []byte) {
}, certPem, keyPem }, certPem, keyPem
} }
func createTestTLS(t *testing.T, tlsConf *TLSConfig) (s *Server, certPem []byte) { func createTestTLS(tb testing.TB, tlsConf *TLSConfig) (s *Server, certPem []byte) {
t.Helper() tb.Helper()
var keyPem []byte var keyPem []byte
_, certPem, keyPem = createServerTLSConfig(t) _, certPem, keyPem = createServerTLSConfig(tb)
cert, err := tls.X509KeyPair(certPem, keyPem) cert, err := tls.X509KeyPair(certPem, keyPem)
require.NoError(t, err) require.NoError(tb, err)
tlsConf.Cert = &cert tlsConf.Cert = &cert
s = createTestServer(t, &filtering.Config{ s = createTestServer(tb, &filtering.Config{
BlockingMode: filtering.BlockingModeDefault, BlockingMode: filtering.BlockingModeDefault,
}, ServerConfig{ }, ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}}, UDPListenAddrs: []*net.UDPAddr{{}},
@@ -247,8 +250,8 @@ func createTestTLS(t *testing.T, tlsConf *TLSConfig) (s *Server, certPem []byte)
ServePlainDNS: true, ServePlainDNS: true,
}) })
err = s.Prepare(testutil.ContextWithTimeout(t, testTimeout), &s.conf) err = s.Prepare(testutil.ContextWithTimeout(tb, testTimeout), &s.conf)
require.NoErrorf(t, err, "failed to prepare server: %s", err) require.NoErrorf(tb, err, "failed to prepare server: %s", err)
return s, certPem return s, certPem
} }
@@ -304,25 +307,27 @@ func newResp(rcode int, req *dns.Msg, ans []dns.RR) (resp *dns.Msg) {
return resp return resp
} }
func assertGoogleAResponse(t *testing.T, reply *dns.Msg) { func assertGoogleAResponse(tb testing.TB, reply *dns.Msg) {
assertResponse(t, reply, netip.AddrFrom4([4]byte{8, 8, 8, 8})) tb.Helper()
assertResponse(tb, reply, netip.AddrFrom4([4]byte{8, 8, 8, 8}))
} }
func assertResponse(t *testing.T, reply *dns.Msg, ip netip.Addr) { func assertResponse(tb testing.TB, reply *dns.Msg, ip netip.Addr) {
t.Helper() tb.Helper()
require.Lenf(t, reply.Answer, 1, "dns server returned reply with wrong number of answers - %d", len(reply.Answer)) require.Lenf(tb, reply.Answer, 1, "dns server returned reply with wrong number of answers - %d", len(reply.Answer))
a, ok := reply.Answer[0].(*dns.A) a, ok := reply.Answer[0].(*dns.A)
require.Truef(t, ok, "dns server returned wrong answer type instead of A: %v", reply.Answer[0]) require.Truef(tb, ok, "dns server returned wrong answer type instead of A: %v", reply.Answer[0])
assert.Equal(t, net.IP(ip.AsSlice()), a.A) assert.Equal(tb, net.IP(ip.AsSlice()), a.A)
} }
// sendTestMessagesAsync sends messages in parallel to check for race issues. // sendTestMessagesAsync sends messages in parallel to check for race issues.
// //
//lint:ignore U1000 it's called from the function which is skipped for now. //lint:ignore U1000 it's called from the function which is skipped for now.
func sendTestMessagesAsync(t *testing.T, conn *dns.Conn) { func sendTestMessagesAsync(tb testing.TB, conn *dns.Conn) {
t.Helper() tb.Helper()
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
@@ -334,29 +339,29 @@ func sendTestMessagesAsync(t *testing.T, conn *dns.Conn) {
defer wg.Done() defer wg.Done()
err := conn.WriteMsg(msg) err := conn.WriteMsg(msg)
require.NoErrorf(t, err, "cannot write message: %s", err) require.NoErrorf(tb, err, "cannot write message: %s", err)
res, err := conn.ReadMsg() res, err := conn.ReadMsg()
require.NoErrorf(t, err, "cannot read response to message: %s", err) require.NoErrorf(tb, err, "cannot read response to message: %s", err)
assertGoogleAResponse(t, res) assertGoogleAResponse(tb, res)
}() }()
} }
wg.Wait() wg.Wait()
} }
func sendTestMessages(t *testing.T, conn *dns.Conn) { func sendTestMessages(tb testing.TB, conn *dns.Conn) {
t.Helper() tb.Helper()
for i := range testMessagesCount { for i := range testMessagesCount {
req := createGoogleATestMessage() req := createGoogleATestMessage()
err := conn.WriteMsg(req) err := conn.WriteMsg(req)
assert.NoErrorf(t, err, "cannot write message #%d: %s", i, err) assert.NoErrorf(tb, err, "cannot write message #%d: %s", i, err)
res, err := conn.ReadMsg() res, err := conn.ReadMsg()
assert.NoErrorf(t, err, "cannot read response to message #%d: %s", i, err) assert.NoErrorf(tb, err, "cannot read response to message #%d: %s", i, err)
assertGoogleAResponse(t, res) assertGoogleAResponse(tb, res)
} }
} }
@@ -1080,8 +1085,8 @@ func TestBlockedCustomIP(t *testing.T) {
dhcp := &testDHCP{ dhcp := &testDHCP{
OnEnabled: func() (ok bool) { return false }, OnEnabled: func() (ok bool) { return false },
OnHostByIP: func(_ netip.Addr) (host string) { panic("not implemented") }, OnHostByIP: func(ip netip.Addr) (_ string) { panic(testutil.UnexpectedCall(ip)) },
OnIPByHost: func(_ string) (ip netip.Addr) { panic("not implemented") }, OnIPByHost: func(host string) (_ netip.Addr) { panic(testutil.UnexpectedCall(host)) },
} }
s, err := NewServer(DNSCreateParams{ s, err := NewServer(DNSCreateParams{
DHCPServer: dhcp, DHCPServer: dhcp,
@@ -1256,8 +1261,8 @@ func TestRewrite(t *testing.T) {
dhcp := &testDHCP{ dhcp := &testDHCP{
OnEnabled: func() (ok bool) { return false }, OnEnabled: func() (ok bool) { return false },
OnHostByIP: func(ip netip.Addr) (host string) { panic("not implemented") }, OnHostByIP: func(ip netip.Addr) (_ string) { panic(testutil.UnexpectedCall(ip)) },
OnIPByHost: func(host string) (ip netip.Addr) { panic("not implemented") }, OnIPByHost: func(host string) (_ netip.Addr) { panic(testutil.UnexpectedCall(host)) },
} }
s, err := NewServer(DNSCreateParams{ s, err := NewServer(DNSCreateParams{
DHCPServer: dhcp, DHCPServer: dhcp,
@@ -1392,7 +1397,7 @@ func TestPTRResponseFromDHCPLeases(t *testing.T) {
DNSFilter: flt, DNSFilter: flt,
DHCPServer: &testDHCP{ DHCPServer: &testDHCP{
OnEnabled: func() (ok bool) { return true }, OnEnabled: func() (ok bool) { return true },
OnIPByHost: func(host string) (ip netip.Addr) { panic("not implemented") }, OnIPByHost: func(host string) (_ netip.Addr) { panic(testutil.UnexpectedCall(host)) },
OnHostByIP: func(ip netip.Addr) (host string) { OnHostByIP: func(ip netip.Addr) (host string) {
return "myhost" return "myhost"
}, },
@@ -1449,13 +1454,13 @@ func TestPTRResponseFromHosts(t *testing.T) {
dhcp := &testDHCP{ dhcp := &testDHCP{
OnEnabled: func() (ok bool) { return false }, OnEnabled: func() (ok bool) { return false },
OnIPByHost: func(host string) (ip netip.Addr) { panic("not implemented") }, OnIPByHost: func(host string) (_ netip.Addr) { panic(testutil.UnexpectedCall(host)) },
OnHostByIP: func(ip netip.Addr) (host string) { return "" }, OnHostByIP: func(ip netip.Addr) (host string) { return "" },
} }
var eventsCalledCounter uint32 var eventsCalledCounter uint32
hc, err := aghnet.NewHostsContainer(testFS, &aghtest.FSWatcher{ hc, err := aghnet.NewHostsContainer(testFS, &aghtest.FSWatcher{
OnStart: func(_ context.Context) (_ error) { panic("not implemented") }, OnStart: func(ctx context.Context) (_ error) { panic(testutil.UnexpectedCall(ctx)) },
OnEvents: func() (e <-chan struct{}) { OnEvents: func() (e <-chan struct{}) {
assert.Equal(t, uint32(1), atomic.AddUint32(&eventsCalledCounter, 1)) assert.Equal(t, uint32(1), atomic.AddUint32(&eventsCalledCounter, 1))
@@ -1466,7 +1471,7 @@ func TestPTRResponseFromHosts(t *testing.T) {
return nil return nil
}, },
OnShutdown: func(_ context.Context) (err error) { panic("not implemented") }, OnShutdown: func(ctx context.Context) (err error) { panic(testutil.UnexpectedCall(ctx)) },
}, hostsFilename) }, hostsFilename)
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {

View File

@@ -58,8 +58,8 @@ func TestHandleDNSRequest_handleDNSRequest(t *testing.T) {
s, err := NewServer(DNSCreateParams{ s, err := NewServer(DNSCreateParams{
DHCPServer: &testDHCP{ DHCPServer: &testDHCP{
OnEnabled: func() (ok bool) { return false }, OnEnabled: func() (ok bool) { return false },
OnHostByIP: func(ip netip.Addr) (host string) { panic("not implemented") }, OnHostByIP: func(ip netip.Addr) (_ string) { panic(testutil.UnexpectedCall(ip)) },
OnIPByHost: func(host string) (ip netip.Addr) { panic("not implemented") }, OnIPByHost: func(host string) (_ netip.Addr) { panic(testutil.UnexpectedCall(host)) },
}, },
DNSFilter: f, DNSFilter: f,
PrivateNets: netutil.SubnetSetFunc(netutil.IsLocallyServed), PrivateNets: netutil.SubnetSetFunc(netutil.IsLocallyServed),

View File

@@ -44,16 +44,18 @@ func (emptySysResolvers) Addrs() (addrs []netip.AddrPort) {
return nil return nil
} }
func loadTestData(t *testing.T, casesFileName string, cases any) { // loadTestData loads the test data from the file with the given name into
t.Helper() // cases.
func loadTestData(tb testing.TB, casesFileName string, cases any) {
tb.Helper()
var f *os.File var f *os.File
f, err := os.Open(filepath.Join("testdata", casesFileName)) f, err := os.Open(filepath.Join("testdata", casesFileName))
require.NoError(t, err) require.NoError(tb, err)
testutil.CleanupAndRequireSuccess(t, f.Close) testutil.CleanupAndRequireSuccess(tb, f.Close)
err = json.NewDecoder(f).Decode(cases) err = json.NewDecoder(f).Decode(cases)
require.NoError(t, err) require.NoError(tb, err)
} }
const ( const (
@@ -312,14 +314,17 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
} }
} }
func newLocalUpstreamListener(t *testing.T, port uint16, handler dns.Handler) (real netip.AddrPort) { // newLocalUpstreamListener creates a local upstream listener and returns its
t.Helper() // address. The listener is started in a separate goroutine and stopped when
// the tb's test is finished.
func newLocalUpstreamListener(tb testing.TB, port uint16, h dns.Handler) (real netip.AddrPort) {
tb.Helper()
startCh := make(chan struct{}) startCh := make(chan struct{})
upsSrv := &dns.Server{ upsSrv := &dns.Server{
Addr: netip.AddrPortFrom(netutil.IPv4Localhost(), port).String(), Addr: netip.AddrPortFrom(netutil.IPv4Localhost(), port).String(),
Net: "tcp", Net: "tcp",
Handler: handler, Handler: h,
NotifyStartedFunc: func() { close(startCh) }, NotifyStartedFunc: func() { close(startCh) },
} }
go func() { go func() {
@@ -328,9 +333,9 @@ func newLocalUpstreamListener(t *testing.T, port uint16, handler dns.Handler) (r
}() }()
<-startCh <-startCh
testutil.CleanupAndRequireSuccess(t, upsSrv.Shutdown) testutil.CleanupAndRequireSuccess(tb, upsSrv.Shutdown)
return testutil.RequireTypeAssert[*net.TCPAddr](t, upsSrv.Listener.Addr()).AddrPort() return testutil.RequireTypeAssert[*net.TCPAddr](tb, upsSrv.Listener.Addr()).AddrPort()
} }
func TestServer_HandleTestUpstreamDNS(t *testing.T) { func TestServer_HandleTestUpstreamDNS(t *testing.T) {
@@ -364,7 +369,7 @@ func TestServer_HandleTestUpstreamDNS(t *testing.T) {
}, },
}, },
&aghtest.FSWatcher{ &aghtest.FSWatcher{
OnStart: func(_ context.Context) (_ error) { panic("not implemented") }, OnStart: func(ctx context.Context) (_ error) { panic(testutil.UnexpectedCall(ctx)) },
OnEvents: func() (e <-chan struct{}) { return nil }, OnEvents: func() (e <-chan struct{}) { return nil },
OnAdd: func(_ string) (err error) { return nil }, OnAdd: func(_ string) (err error) { return nil },
OnShutdown: func(_ context.Context) (err error) { return nil }, OnShutdown: func(_ context.Context) (err error) { return nil },
@@ -469,10 +474,8 @@ func TestServer_HandleTestUpstreamDNS(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Contains(t, resp, sleepyUps) require.Contains(t, resp, sleepyUps)
require.IsType(t, "", resp[sleepyUps]) sleepyRes := testutil.RequireTypeAssert[string](t, resp[sleepyUps])
sleepyRes, _ := resp[sleepyUps].(string)
// TODO(e.burkov): Improve the format of an error in dnsproxy.
assert.True(t, strings.HasSuffix(sleepyRes, "i/o timeout")) assert.True(t, strings.HasSuffix(sleepyRes, "i/o timeout"))
}) })
} }

View File

@@ -94,7 +94,7 @@ func TestServer_ProcessInitial(t *testing.T) {
var gotAddr netip.Addr var gotAddr netip.Addr
s.addrProc = &aghtest.AddressProcessor{ s.addrProc = &aghtest.AddressProcessor{
OnProcess: func(ctx context.Context, ip netip.Addr) { gotAddr = ip }, OnProcess: func(ctx context.Context, ip netip.Addr) { gotAddr = ip },
OnClose: func() (err error) { panic("not implemented") }, OnClose: func() (_ error) { panic(testutil.UnexpectedCall()) },
} }
dctx := &dnsContext{ dctx := &dnsContext{
@@ -373,14 +373,14 @@ func TestServer_ProcessDDRQuery(t *testing.T) {
} }
// createTestDNSFilter returns the minimum valid DNSFilter. // createTestDNSFilter returns the minimum valid DNSFilter.
func createTestDNSFilter(t *testing.T) (f *filtering.DNSFilter) { func createTestDNSFilter(tb testing.TB) (f *filtering.DNSFilter) {
t.Helper() tb.Helper()
f, err := filtering.New(&filtering.Config{ f, err := filtering.New(&filtering.Config{
Logger: testLogger, Logger: testLogger,
BlockingMode: filtering.BlockingModeDefault, BlockingMode: filtering.BlockingModeDefault,
}, []filtering.Filter{}) }, []filtering.Filter{})
require.NoError(t, err) require.NoError(tb, err)
return f return f
} }
@@ -519,7 +519,7 @@ func TestServer_ProcessDHCPHosts(t *testing.T) {
OnIPByHost: func(host string) (ip netip.Addr) { OnIPByHost: func(host string) (ip netip.Addr) {
return knownClients[host] return knownClients[host]
}, },
OnHostByIP: func(ip netip.Addr) (host string) { panic("not implemented") }, OnHostByIP: func(ip netip.Addr) (_ string) { panic(testutil.UnexpectedCall(ip)) },
} }
testCases := []struct { testCases := []struct {

View File

@@ -22,17 +22,16 @@ const testTimeout = 5 * time.Second
// serveHTTPLocally starts a new HTTP server, that handles its index with h. It // serveHTTPLocally starts a new HTTP server, that handles its index with h. It
// also gracefully closes the listener when the test under t finishes. // also gracefully closes the listener when the test under t finishes.
func serveHTTPLocally(t *testing.T, h http.Handler) (urlStr string) { func serveHTTPLocally(tb testing.TB, h http.Handler) (urlStr string) {
t.Helper() tb.Helper()
l, err := net.Listen("tcp", ":0") l, err := net.Listen("tcp", ":0")
require.NoError(t, err) require.NoError(tb, err)
go func() { _ = http.Serve(l, h) }() go func() { _ = http.Serve(l, h) }()
testutil.CleanupAndRequireSuccess(t, l.Close) testutil.CleanupAndRequireSuccess(tb, l.Close)
addr := l.Addr() addr := testutil.RequireTypeAssert[*net.TCPAddr](tb, l.Addr())
require.IsType(t, (*net.TCPAddr)(nil), addr)
return (&url.URL{ return (&url.URL{
Scheme: urlutil.SchemeHTTP, Scheme: urlutil.SchemeHTTP,
@@ -42,10 +41,10 @@ func serveHTTPLocally(t *testing.T, h http.Handler) (urlStr string) {
// serveFiltersLocally is a helper that concurrently listens on a free port to // serveFiltersLocally is a helper that concurrently listens on a free port to
// respond with fltContent. // respond with fltContent.
func serveFiltersLocally(t *testing.T, fltContent []byte) (urlStr string) { func serveFiltersLocally(tb testing.TB, fltContent []byte) (urlStr string) {
t.Helper() tb.Helper()
return serveHTTPLocally(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { return serveHTTPLocally(tb, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
pt := testutil.PanicT{} pt := testutil.PanicT{}
n, werr := w.Write(fltContent) n, werr := w.Write(fltContent)
@@ -57,43 +56,43 @@ func serveFiltersLocally(t *testing.T, fltContent []byte) (urlStr string) {
// updateAndAssert loads filter content from its URL and then asserts rules // updateAndAssert loads filter content from its URL and then asserts rules
// count. // count.
func updateAndAssert( func updateAndAssert(
t *testing.T, tb testing.TB,
ctx context.Context, ctx context.Context,
dnsFilter *DNSFilter, dnsFilter *DNSFilter,
f *FilterYAML, f *FilterYAML,
wantUpd require.BoolAssertionFunc, wantUpd require.BoolAssertionFunc,
wantRulesCount int, wantRulesCount int,
) { ) {
t.Helper() tb.Helper()
ok, err := dnsFilter.update(f) ok, err := dnsFilter.update(f)
require.NoError(t, err) require.NoError(tb, err)
wantUpd(t, ok) wantUpd(tb, ok)
assert.Equal(t, wantRulesCount, f.RulesCount) assert.Equal(tb, wantRulesCount, f.RulesCount)
dir, err := os.ReadDir(filepath.Join(dnsFilter.conf.DataDir, filterDir)) dir, err := os.ReadDir(filepath.Join(dnsFilter.conf.DataDir, filterDir))
require.NoError(t, err) require.NoError(tb, err)
require.FileExists(t, f.Path(dnsFilter.conf.DataDir)) require.FileExists(tb, f.Path(dnsFilter.conf.DataDir))
assert.Len(t, dir, 1) assert.Len(tb, dir, 1)
err = dnsFilter.load(ctx, f) err = dnsFilter.load(ctx, f)
require.NoError(t, err) require.NoError(tb, err)
} }
// newDNSFilter returns a new properly initialized DNS filter instance. // newDNSFilter returns a new properly initialized DNS filter instance.
func newDNSFilter(t *testing.T) (d *DNSFilter) { func newDNSFilter(tb testing.TB) (d *DNSFilter) {
t.Helper() tb.Helper()
dnsFilter, err := New(&Config{ dnsFilter, err := New(&Config{
Logger: slogutil.NewDiscardLogger(), Logger: slogutil.NewDiscardLogger(),
DataDir: t.TempDir(), DataDir: tb.TempDir(),
HTTPClient: &http.Client{ HTTPClient: &http.Client{
Timeout: testTimeout, Timeout: testTimeout,
}, },
}, nil) }, nil)
require.NoError(t, err) require.NoError(tb, err)
return dnsFilter return dnsFilter
} }

View File

@@ -63,37 +63,37 @@ func newChecker(host string) Checker {
}) })
} }
func (d *DNSFilter) checkMatch(t *testing.T, hostname string, setts *Settings) { func (d *DNSFilter) checkMatch(tb testing.TB, hostname string, setts *Settings) {
t.Helper() tb.Helper()
res, err := d.CheckHost(hostname, dns.TypeA, setts) res, err := d.CheckHost(hostname, dns.TypeA, setts)
require.NoErrorf(t, err, "host %q", hostname) require.NoErrorf(tb, err, "host %q", hostname)
assert.Truef(t, res.IsFiltered, "host %q", hostname) assert.Truef(tb, res.IsFiltered, "host %q", hostname)
} }
func (d *DNSFilter) checkMatchIP(t *testing.T, hostname, ip string, qtype uint16, setts *Settings) { func (d *DNSFilter) checkMatchIP(tb testing.TB, hostname, ip string, qtype uint16, setts *Settings) {
t.Helper() tb.Helper()
res, err := d.CheckHost(hostname, qtype, setts) res, err := d.CheckHost(hostname, qtype, setts)
require.NoErrorf(t, err, "host %q", hostname, err) require.NoErrorf(tb, err, "host %q", hostname, err)
require.NotEmpty(t, res.Rules, "host %q", hostname) require.NotEmpty(tb, res.Rules, "host %q", hostname)
assert.Truef(t, res.IsFiltered, "host %q", hostname) assert.Truef(tb, res.IsFiltered, "host %q", hostname)
r := res.Rules[0] r := res.Rules[0]
require.NotNilf(t, r.IP, "Expected ip %s to match, actual: %v", ip, r.IP) require.NotNilf(tb, r.IP, "Expected ip %s to match, actual: %v", ip, r.IP)
assert.Equalf(t, ip, r.IP.String(), "host %q", hostname) assert.Equalf(tb, ip, r.IP.String(), "host %q", hostname)
} }
func (d *DNSFilter) checkMatchEmpty(t *testing.T, hostname string, setts *Settings) { func (d *DNSFilter) checkMatchEmpty(tb testing.TB, hostname string, setts *Settings) {
t.Helper() tb.Helper()
res, err := d.CheckHost(hostname, dns.TypeA, setts) res, err := d.CheckHost(hostname, dns.TypeA, setts)
require.NoErrorf(t, err, "host %q", hostname) require.NoErrorf(tb, err, "host %q", hostname)
assert.Falsef(t, res.IsFiltered, "host %q", hostname) assert.Falsef(tb, res.IsFiltered, "host %q", hostname)
} }
func TestDNSFilter_CheckHost_hostRules(t *testing.T) { func TestDNSFilter_CheckHost_hostRules(t *testing.T) {

View File

@@ -44,7 +44,7 @@ func TestDNSFilter_CheckHost_hostsContainer(t *testing.T) {
}, },
} }
watcher := &aghtest.FSWatcher{ watcher := &aghtest.FSWatcher{
OnStart: func(_ context.Context) (_ error) { panic("not implemented") }, OnStart: func(ctx context.Context) (_ error) { panic(testutil.UnexpectedCall(ctx)) },
OnEvents: func() (e <-chan struct{}) { return nil }, OnEvents: func() (e <-chan struct{}) { return nil },
OnAdd: func(name string) (err error) { return nil }, OnAdd: func(name string) (err error) { return nil },
OnShutdown: func(_ context.Context) (err error) { return nil }, OnShutdown: func(_ context.Context) (err error) { return nil },

View File

@@ -75,13 +75,13 @@ func TestIDGenerator_Fix(t *testing.T) {
// assertUniqueIDs is a test helper that asserts that the IDs of filters are // assertUniqueIDs is a test helper that asserts that the IDs of filters are
// unique. // unique.
func assertUniqueIDs(t testing.TB, flts []FilterYAML) { func assertUniqueIDs(tb testing.TB, flts []FilterYAML) {
t.Helper() tb.Helper()
uc := aghalg.UniqChecker[rulelist.URLFilterID]{} uc := aghalg.UniqChecker[rulelist.URLFilterID]{}
for _, f := range flts { for _, f := range flts {
uc.Add(f.ID) uc.Add(f.ID)
} }
assert.NoError(t, uc.Validate()) assert.NoError(tb, uc.Validate())
} }

View File

@@ -209,20 +209,20 @@ func TestDNSFilter_handleRewriteHTTP(t *testing.T) {
// assertRewritesList checks if rewrites list equals the list received from the // assertRewritesList checks if rewrites list equals the list received from the
// handler by listURL. // handler by listURL.
func assertRewritesList(t *testing.T, handler http.Handler, wantList []*rewriteJSON) { func assertRewritesList(tb testing.TB, handler http.Handler, wantList []*rewriteJSON) {
t.Helper() tb.Helper()
r := httptest.NewRequest(http.MethodGet, listURL, nil) r := httptest.NewRequest(http.MethodGet, listURL, nil)
w := httptest.NewRecorder() w := httptest.NewRecorder()
handler.ServeHTTP(w, r) handler.ServeHTTP(w, r)
require.Equal(t, http.StatusOK, w.Code) require.Equal(tb, http.StatusOK, w.Code)
var actual []*rewriteJSON var actual []*rewriteJSON
err := json.NewDecoder(w.Body).Decode(&actual) err := json.NewDecoder(w.Body).Decode(&actual)
require.NoError(t, err) require.NoError(tb, err)
assert.Equal(t, wantList, actual) assert.Equal(tb, wantList, actual)
} }
// rewriteEntriesToLegacyRewrites gets legacy rewrites from json entries. // rewriteEntriesToLegacyRewrites gets legacy rewrites from json entries.

View File

@@ -52,8 +52,8 @@ func newURLFilterID() (id rulelist.URLFilterID) {
// newFilter is a helper for creating new filters in tests. It does not // newFilter is a helper for creating new filters in tests. It does not
// register the closing of the filter using t.Cleanup; callers must do that // register the closing of the filter using t.Cleanup; callers must do that
// either directly or by using the filter in an engine. // either directly or by using the filter in an engine.
func newFilter(t testing.TB, u *url.URL, name string) (f *rulelist.Filter) { func newFilter(tb testing.TB, u *url.URL, name string) (f *rulelist.Filter) {
t.Helper() tb.Helper()
f, err := rulelist.NewFilter(&rulelist.FilterConfig{ f, err := rulelist.NewFilter(&rulelist.FilterConfig{
URL: u, URL: u,
@@ -62,7 +62,7 @@ func newFilter(t testing.TB, u *url.URL, name string) (f *rulelist.Filter) {
URLFilterID: newURLFilterID(), URLFilterID: newURLFilterID(),
Enabled: true, Enabled: true,
}) })
require.NoError(t, err) require.NoError(tb, err)
return f return f
} }
@@ -71,24 +71,24 @@ func newFilter(t testing.TB, u *url.URL, name string) (f *rulelist.Filter) {
// file and the HTTP-server. It also registers file removal and server stopping // file and the HTTP-server. It also registers file removal and server stopping
// using t.Cleanup. // using t.Cleanup.
func newFilterLocations( func newFilterLocations(
t testing.TB, tb testing.TB,
cacheDir string, cacheDir string,
fileData string, fileData string,
httpData string, httpData string,
) (fileURL, srvURL *url.URL) { ) (fileURL, srvURL *url.URL) {
t.Helper() tb.Helper()
f, err := os.CreateTemp(cacheDir, "") f, err := os.CreateTemp(cacheDir, "")
require.NoError(t, err) require.NoError(tb, err)
err = f.Close() err = f.Close()
require.NoError(t, err) require.NoError(tb, err)
filePath := f.Name() filePath := f.Name()
err = os.WriteFile(filePath, []byte(fileData), 0o644) err = os.WriteFile(filePath, []byte(fileData), 0o644)
require.NoError(t, err) require.NoError(tb, err)
testutil.CleanupAndRequireSuccess(t, func() (err error) { testutil.CleanupAndRequireSuccess(tb, func() (err error) {
return os.Remove(filePath) return os.Remove(filePath)
}) })
@@ -98,10 +98,10 @@ func newFilterLocations(
} }
srv := newStringHTTPServer(httpData) srv := newStringHTTPServer(httpData)
t.Cleanup(srv.Close) tb.Cleanup(srv.Close)
srvURL, err = url.Parse(srv.URL) srvURL, err = url.Parse(srv.URL)
require.NoError(t, err) require.NoError(tb, err)
return fileURL, srvURL return fileURL, srvURL
} }

View File

@@ -7,7 +7,6 @@ import (
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt"
"maps" "maps"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
@@ -48,20 +47,20 @@ var _ aghuser.SessionStorage = (*testSessionStorage)(nil)
// panic. // panic.
func newTestSessionStorage() (ts *testSessionStorage) { func newTestSessionStorage() (ts *testSessionStorage) {
return &testSessionStorage{ return &testSessionStorage{
onNew: func(_ context.Context, u *aghuser.User) (_ *aghuser.Session, _ error) { onNew: func(ctx context.Context, u *aghuser.User) (_ *aghuser.Session, _ error) {
panic(fmt.Errorf("unexpected call to testSessionStorage.New(%v)", u)) panic(testutil.UnexpectedCall(ctx, u))
}, },
onFindByToken: func( onFindByToken: func(
_ context.Context, ctx context.Context,
t aghuser.SessionToken, t aghuser.SessionToken,
) (_ *aghuser.Session, err error) { ) (_ *aghuser.Session, err error) {
panic(fmt.Errorf("unexpected call to testSessionStorage.FindByToken(%v)", t)) panic(testutil.UnexpectedCall(ctx, t))
}, },
onDeleteByToken: func(_ context.Context, t aghuser.SessionToken) (_ error) { onDeleteByToken: func(ctx context.Context, t aghuser.SessionToken) (_ error) {
panic(fmt.Errorf("unexpected call to testSessionStorage.DeleteByToken(%v)", t)) panic(testutil.UnexpectedCall(ctx, t))
}, },
onClose: func() (_ error) { onClose: func() (_ error) {
panic("unexpected call to testSessionStorage.Close") panic(testutil.UnexpectedCall())
}, },
} }
} }
@@ -110,17 +109,17 @@ type testUsersDB struct {
// newTestUsersDB returns a new *testUsersDB all methods of which panic. // newTestUsersDB returns a new *testUsersDB all methods of which panic.
func newTestUsersDB() (ts *testUsersDB) { func newTestUsersDB() (ts *testUsersDB) {
return &testUsersDB{ return &testUsersDB{
onAll: func(_ context.Context) (_ []*aghuser.User, _ error) { onAll: func(ctx context.Context) (_ []*aghuser.User, _ error) {
panic("unexpected call to testUsersDB.All") panic(testutil.UnexpectedCall(ctx))
}, },
onByLogin: func(_ context.Context, l aghuser.Login) (_ *aghuser.User, _ error) { onByLogin: func(ctx context.Context, l aghuser.Login) (_ *aghuser.User, _ error) {
panic(fmt.Errorf("unexpected call to testUsersDB.ByLogin(%v)", l)) panic(testutil.UnexpectedCall(ctx, l))
}, },
onByUUID: func(_ context.Context, id aghuser.UserID) (_ *aghuser.User, _ error) { onByUUID: func(ctx context.Context, id aghuser.UserID) (_ *aghuser.User, _ error) {
panic(fmt.Errorf("unexpected call to testUsersDB.ByUUID(%v)", id)) panic(testutil.UnexpectedCall(ctx, id))
}, },
onCreate: func(_ context.Context, u *aghuser.User) (_ error) { onCreate: func(ctx context.Context, u *aghuser.User) (_ error) {
panic(fmt.Errorf("unexpected call to testUsersDB.Create(%v)", u)) panic(testutil.UnexpectedCall(ctx, u))
}, },
} }
} }
@@ -574,11 +573,11 @@ func TestAuth_ServeHTTP_auth(t *testing.T) {
// generateAuthCookie is a helper function that logs in with the provided // generateAuthCookie is a helper function that logs in with the provided
// credentials and returns the resulting authentication cookie. // credentials and returns the resulting authentication cookie.
func generateAuthCookie(t *testing.T, mux http.Handler, name, password string) (ac *http.Cookie) { func generateAuthCookie(tb testing.TB, mux http.Handler, name, password string) (ac *http.Cookie) {
t.Helper() tb.Helper()
creds, err := json.Marshal(&loginJSON{Name: name, Password: password}) creds, err := json.Marshal(&loginJSON{Name: name, Password: password})
require.NoError(t, err) require.NoError(tb, err)
r := httptest.NewRequest(http.MethodPost, "/control/login", bytes.NewReader(creds)) r := httptest.NewRequest(http.MethodPost, "/control/login", bytes.NewReader(creds))
r.Header.Set(httphdr.ContentType, aghhttp.HdrValApplicationJSON) r.Header.Set(httphdr.ContentType, aghhttp.HdrValApplicationJSON)
@@ -594,20 +593,20 @@ func generateAuthCookie(t *testing.T, mux http.Handler, name, password string) (
} }
} }
require.NotNil(t, ac) require.NotNil(tb, ac)
return ac return ac
} }
// assertHandlerStatusCode is a helper function that asserts the response status // assertHandlerStatusCode is a helper function that asserts the response status
// code of a HTTP handler. // code of a HTTP handler.
func assertHandlerStatusCode(t *testing.T, h http.Handler, r *http.Request, wantCode int) { func assertHandlerStatusCode(tb testing.TB, h http.Handler, r *http.Request, wantCode int) {
t.Helper() tb.Helper()
w := httptest.NewRecorder() w := httptest.NewRecorder()
h.ServeHTTP(w, r) h.ServeHTTP(w, r)
assert.Equal(t, wantCode, w.Code) assert.Equal(tb, wantCode, w.Code)
} }
func TestAuth_ServeHTTP_logout(t *testing.T) { func TestAuth_ServeHTTP_logout(t *testing.T) {

View File

@@ -12,12 +12,12 @@ import (
// newClientsContainer is a helper that creates a new clients container for // newClientsContainer is a helper that creates a new clients container for
// tests. // tests.
func newClientsContainer(t *testing.T) (c *clientsContainer) { func newClientsContainer(tb testing.TB) (c *clientsContainer) {
t.Helper() tb.Helper()
c = &clientsContainer{} c = &clientsContainer{}
ctx := testutil.ContextWithTimeout(t, testTimeout) ctx := testutil.ContextWithTimeout(tb, testTimeout)
err := c.Init( err := c.Init(
ctx, ctx,
testLogger, testLogger,
@@ -32,7 +32,7 @@ func newClientsContainer(t *testing.T) (c *clientsContainer) {
agh.EmptyConfigModifier{}, agh.EmptyConfigModifier{},
) )
require.NoError(t, err) require.NoError(tb, err)
return c return c
} }

View File

@@ -39,14 +39,14 @@ func TestLimitRequestBody(t *testing.T) {
want: []byte(nil), want: []byte(nil),
}} }}
makeHandler := func(t *testing.T, err *error) http.HandlerFunc { makeHandler := func(tb testing.TB, err *error) http.HandlerFunc {
t.Helper() tb.Helper()
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var b []byte var b []byte
b, *err = io.ReadAll(r.Body) b, *err = io.ReadAll(r.Body)
_, werr := w.Write(b) _, werr := w.Write(b)
require.NoError(t, werr) require.NoError(tb, werr)
}) })
} }

View File

@@ -15,11 +15,11 @@ import (
// setupDNSIPs is a helper that sets up the server IP address configuration for // setupDNSIPs is a helper that sets up the server IP address configuration for
// tests and also tears it down in a cleanup function. // tests and also tears it down in a cleanup function.
func setupDNSIPs(t testing.TB) { func setupDNSIPs(tb testing.TB) {
t.Helper() tb.Helper()
prevConfig := config prevConfig := config
t.Cleanup(func() { tb.Cleanup(func() {
config = prevConfig config = prevConfig
}) })

View File

@@ -9,26 +9,34 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func testParseOK(t *testing.T, ss ...string) options { // testParseOK is a helper that parses the command-line options and returns the
t.Helper() // parsed options.
func testParseOK(tb testing.TB, ss ...string) (o options) {
tb.Helper()
o, _, err := parseCmdOpts("", ss) o, _, err := parseCmdOpts("", ss)
require.NoError(t, err) require.NoError(tb, err)
return o return o
} }
func testParseErr(t *testing.T, descr string, ss ...string) { // testParseErr is a helper that asserts that parsing the command-line options
t.Helper() // fails with error.
//
// TODO(a.garipov): Search descr within an error.
func testParseErr(tb testing.TB, descr string, ss ...string) {
tb.Helper()
_, _, err := parseCmdOpts("", ss) _, _, err := parseCmdOpts("", ss)
require.Error(t, err) require.Errorf(tb, err, "should have got error: %s", descr)
} }
func testParseParamMissing(t *testing.T, param string) { // testParseParamMissing is a helper that asserts that parsing the command-line
t.Helper() // options fails with error due to missing parameter.
func testParseParamMissing(tb testing.TB, param string) {
tb.Helper()
testParseErr(t, fmt.Sprintf("%s parameter missing", param), param) testParseErr(tb, fmt.Sprintf("%s parameter missing", param), param)
} }
func TestParseVerbose(t *testing.T) { func TestParseVerbose(t *testing.T) {

View File

@@ -17,6 +17,7 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/next/websvc" "github.com/AdguardTeam/AdGuardHome/internal/next/websvc"
"github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/netutil/urlutil" "github.com/AdguardTeam/golibs/netutil/urlutil"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -45,7 +46,7 @@ func TestService_HandlePatchSettingsDNS(t *testing.T) {
return nil return nil
}, },
OnShutdown: func(_ context.Context) (err error) { panic("not implemented") }, OnShutdown: func(ctx context.Context) (_ error) { panic(testutil.UnexpectedCall(ctx)) },
OnConfig: func() (c *dnssvc.Config) { return &dnssvc.Config{} }, OnConfig: func() (c *dnssvc.Config) { return &dnssvc.Config{} },
} }
} }

View File

@@ -19,7 +19,7 @@ import (
"github.com/AdguardTeam/golibs/netutil/httputil" "github.com/AdguardTeam/golibs/netutil/httputil"
"github.com/AdguardTeam/golibs/netutil/urlutil" "github.com/AdguardTeam/golibs/netutil/urlutil"
"github.com/AdguardTeam/golibs/testutil" "github.com/AdguardTeam/golibs/testutil"
"github.com/AdguardTeam/golibs/testutil/fakefs" "github.com/AdguardTeam/golibs/testutil/fakeio/fakefs"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -65,13 +65,17 @@ func (m *configManager) UpdateWeb(ctx context.Context, c *websvc.Config) (err er
// newConfigManager returns a *configManager all methods of which panic. // newConfigManager returns a *configManager all methods of which panic.
func newConfigManager() (m *configManager) { func newConfigManager() (m *configManager) {
return &configManager{ return &configManager{
onDNS: func() (svc agh.ServiceWithConfig[*dnssvc.Config]) { panic("not implemented") }, onDNS: func() (_ agh.ServiceWithConfig[*dnssvc.Config]) {
onWeb: func() (svc agh.ServiceWithConfig[*websvc.Config]) { panic("not implemented") }, panic(testutil.UnexpectedCall())
onUpdateDNS: func(_ context.Context, _ *dnssvc.Config) (err error) {
panic("not implemented")
}, },
onUpdateWeb: func(_ context.Context, _ *websvc.Config) (err error) { onWeb: func() (_ agh.ServiceWithConfig[*websvc.Config]) {
panic("not implemented") panic(testutil.UnexpectedCall())
},
onUpdateDNS: func(ctx context.Context, c *dnssvc.Config) (_ error) {
panic(testutil.UnexpectedCall(ctx, c))
},
onUpdateWeb: func(ctx context.Context, c *websvc.Config) (_ error) {
panic(testutil.UnexpectedCall(ctx, c))
}, },
} }
} }
@@ -80,10 +84,10 @@ func newConfigManager() (m *configManager) {
// sole address. It also registers a cleanup procedure, which shuts the // sole address. It also registers a cleanup procedure, which shuts the
// instance down. // instance down.
func newTestServer( func newTestServer(
t testing.TB, tb testing.TB,
confMgr websvc.ConfigManager, confMgr websvc.ConfigManager,
) (svc *websvc.Service, addr netip.AddrPort) { ) (svc *websvc.Service, addr netip.AddrPort) {
t.Helper() tb.Helper()
c := &websvc.Config{ c := &websvc.Config{
Logger: slogutil.NewDiscardLogger(), Logger: slogutil.NewDiscardLogger(),
@@ -103,17 +107,17 @@ func newTestServer(
} }
svc, err := websvc.New(c) svc, err := websvc.New(c)
require.NoError(t, err) require.NoError(tb, err)
err = svc.Start(testutil.ContextWithTimeout(t, testTimeout)) err = svc.Start(testutil.ContextWithTimeout(tb, testTimeout))
require.NoError(t, err) require.NoError(tb, err)
testutil.CleanupAndRequireSuccess(t, func() (err error) { testutil.CleanupAndRequireSuccess(tb, func() (err error) {
return svc.Shutdown(testutil.ContextWithTimeout(t, testTimeout)) return svc.Shutdown(testutil.ContextWithTimeout(tb, testTimeout))
}) })
c = svc.Config() c = svc.Config()
require.NotNil(t, c) require.NotNil(tb, c)
require.Len(t, c.Addresses, 1) require.Len(tb, c.Addresses, 1)
return svc, c.Addresses[0] return svc, c.Addresses[0]
} }
@@ -125,23 +129,23 @@ type jobj map[string]any
// the response as well as checks that the status code is correct. // the response as well as checks that the status code is correct.
// //
// TODO(a.garipov): Add helpers for other methods. // TODO(a.garipov): Add helpers for other methods.
func httpGet(t testing.TB, u *url.URL, wantCode int) (body []byte) { func httpGet(tb testing.TB, u *url.URL, wantCode int) (body []byte) {
t.Helper() tb.Helper()
req, err := http.NewRequest(http.MethodGet, u.String(), nil) req, err := http.NewRequest(http.MethodGet, u.String(), nil)
require.NoErrorf(t, err, "creating req") require.NoErrorf(tb, err, "creating req")
httpCli := &http.Client{ httpCli := &http.Client{
Timeout: testTimeout, Timeout: testTimeout,
} }
resp, err := httpCli.Do(req) resp, err := httpCli.Do(req)
require.NoErrorf(t, err, "performing req") require.NoErrorf(tb, err, "performing req")
require.Equal(t, wantCode, resp.StatusCode) require.Equal(tb, wantCode, resp.StatusCode)
testutil.CleanupAndRequireSuccess(t, resp.Body.Close) testutil.CleanupAndRequireSuccess(tb, resp.Body.Close)
body, err = io.ReadAll(resp.Body) body, err = io.ReadAll(resp.Body)
require.NoErrorf(t, err, "reading body") require.NoErrorf(tb, err, "reading body")
return body return body
} }
@@ -151,26 +155,26 @@ func httpGet(t testing.TB, u *url.URL, wantCode int) (body []byte) {
// checks that the status code is correct. // checks that the status code is correct.
// //
// TODO(a.garipov): Add helpers for other methods. // TODO(a.garipov): Add helpers for other methods.
func httpPatch(t testing.TB, u *url.URL, reqBody any, wantCode int) (body []byte) { func httpPatch(tb testing.TB, u *url.URL, reqBody any, wantCode int) (body []byte) {
t.Helper() tb.Helper()
b, err := json.Marshal(reqBody) b, err := json.Marshal(reqBody)
require.NoErrorf(t, err, "marshaling reqBody") require.NoErrorf(tb, err, "marshaling reqBody")
req, err := http.NewRequest(http.MethodPatch, u.String(), bytes.NewReader(b)) req, err := http.NewRequest(http.MethodPatch, u.String(), bytes.NewReader(b))
require.NoErrorf(t, err, "creating req") require.NoErrorf(tb, err, "creating req")
httpCli := &http.Client{ httpCli := &http.Client{
Timeout: testTimeout, Timeout: testTimeout,
} }
resp, err := httpCli.Do(req) resp, err := httpCli.Do(req)
require.NoErrorf(t, err, "performing req") require.NoErrorf(tb, err, "performing req")
require.Equal(t, wantCode, resp.StatusCode) require.Equal(tb, wantCode, resp.StatusCode)
testutil.CleanupAndRequireSuccess(t, resp.Body.Close) testutil.CleanupAndRequireSuccess(tb, resp.Body.Close)
body, err = io.ReadAll(resp.Body) body, err = io.ReadAll(resp.Body)
require.NoErrorf(t, err, "reading body") require.NoErrorf(tb, err, "reading body")
return body return body
} }

View File

@@ -390,20 +390,20 @@ func addEntry(l *queryLog, host string, answerStr, client net.IP) {
l.Add(params) l.Add(params)
} }
func assertLogEntry(t *testing.T, entry *logEntry, host string, answer, client net.IP) { func assertLogEntry(tb testing.TB, entry *logEntry, host string, answer, client net.IP) {
t.Helper() tb.Helper()
require.NotNil(t, entry) require.NotNil(tb, entry)
assert.Equal(t, host, entry.QHost) assert.Equal(tb, host, entry.QHost)
assert.Equal(t, client, entry.IP) assert.Equal(tb, client, entry.IP)
assert.Equal(t, "A", entry.QType) assert.Equal(tb, "A", entry.QType)
assert.Equal(t, "IN", entry.QClass) assert.Equal(tb, "IN", entry.QClass)
msg := &dns.Msg{} msg := &dns.Msg{}
require.NoError(t, msg.Unpack(entry.Answer)) require.NoError(tb, msg.Unpack(entry.Answer))
require.Len(t, msg.Answer, 1) require.Len(tb, msg.Answer, 1)
a := testutil.RequireTypeAssert[*dns.A](t, msg.Answer[0]) a := testutil.RequireTypeAssert[*dns.A](tb, msg.Answer[0])
assert.Equal(t, answer, a.A.To16()) assert.Equal(tb, answer, a.A.To16())
} }

View File

@@ -20,17 +20,17 @@ import (
// prepareTestFile prepares one test query log file with the specified lines // prepareTestFile prepares one test query log file with the specified lines
// count. // count.
func prepareTestFile(t *testing.T, dir string, linesNum int) (name string) { func prepareTestFile(tb testing.TB, dir string, linesNum int) (name string) {
t.Helper() tb.Helper()
f, err := os.CreateTemp(dir, "*.txt") f, err := os.CreateTemp(dir, "*.txt")
require.NoError(t, err) require.NoError(tb, err)
// Use defer and not t.Cleanup to make sure that the file is closed // Use defer and not t.Cleanup to make sure that the file is closed
// after this function is done. // after this function is done.
defer func() { defer func() {
derr := f.Close() derr := f.Close()
require.NoError(t, derr) require.NoError(tb, derr)
}() }()
const ans = `"AAAAAAABAAEAAAAAB2V4YW1wbGUDb3JnAAABAAEHZXhhbXBsZQNvcmcAAAEAAQAAAAAABAECAwQ="` const ans = `"AAAAAAABAAEAAAAAB2V4YW1wbGUDb3JnAAABAAEHZXhhbXBsZQNvcmcAAAEAAQAAAAAABAECAwQ="`
@@ -49,7 +49,7 @@ func prepareTestFile(t *testing.T, dir string, linesNum int) (name string) {
line := fmt.Sprintf(format, ip, lineTime.Format(time.RFC3339Nano)) line := fmt.Sprintf(format, ip, lineTime.Format(time.RFC3339Nano))
_, err = f.WriteString(line) _, err = f.WriteString(line)
require.NoError(t, err) require.NoError(tb, err)
} }
return f.Name() return f.Name()
@@ -57,18 +57,18 @@ func prepareTestFile(t *testing.T, dir string, linesNum int) (name string) {
// prepareTestFiles prepares several test query log files, each with the // prepareTestFiles prepares several test query log files, each with the
// specified lines count. // specified lines count.
func prepareTestFiles(t *testing.T, filesNum, linesNum int) []string { func prepareTestFiles(tb testing.TB, filesNum, linesNum int) []string {
t.Helper() tb.Helper()
if filesNum == 0 { if filesNum == 0 {
return []string{} return []string{}
} }
dir := t.TempDir() dir := tb.TempDir()
files := make([]string, filesNum) files := make([]string, filesNum)
for i := range files { for i := range files {
files[filesNum-i-1] = prepareTestFile(t, dir, linesNum) files[filesNum-i-1] = prepareTestFile(tb, dir, linesNum)
} }
return files return files
@@ -76,17 +76,17 @@ func prepareTestFiles(t *testing.T, filesNum, linesNum int) []string {
// newTestQLogFile creates new *qLogFile for tests and registers the required // newTestQLogFile creates new *qLogFile for tests and registers the required
// cleanup functions. // cleanup functions.
func newTestQLogFile(t *testing.T, linesNum int) (file *qLogFile) { func newTestQLogFile(tb testing.TB, linesNum int) (file *qLogFile) {
t.Helper() tb.Helper()
testFile := prepareTestFiles(t, 1, linesNum)[0] testFile := prepareTestFiles(tb, 1, linesNum)[0]
// Create the new qLogFile instance. // Create the new qLogFile instance.
file, err := newQLogFile(testFile) file, err := newQLogFile(testFile)
require.NoError(t, err) require.NoError(tb, err)
assert.NotNil(t, file) assert.NotNil(tb, file)
testutil.CleanupAndRequireSuccess(t, file.Close) testutil.CleanupAndRequireSuccess(tb, file.Close)
return file return file
} }

View File

@@ -13,20 +13,20 @@ import (
// newTestQLogReader creates new *qLogReader for tests and registers the // newTestQLogReader creates new *qLogReader for tests and registers the
// required cleanup functions. // required cleanup functions.
func newTestQLogReader(t *testing.T, filesNum, linesNum int) (reader *qLogReader) { func newTestQLogReader(tb testing.TB, filesNum, linesNum int) (reader *qLogReader) {
t.Helper() tb.Helper()
testFiles := prepareTestFiles(t, filesNum, linesNum) testFiles := prepareTestFiles(tb, filesNum, linesNum)
logger := slogutil.NewDiscardLogger() logger := slogutil.NewDiscardLogger()
ctx := testutil.ContextWithTimeout(t, testTimeout) ctx := testutil.ContextWithTimeout(tb, testTimeout)
// Create the new qLogReader instance. // Create the new qLogReader instance.
reader, err := newQLogReader(ctx, logger, testFiles) reader, err := newQLogReader(ctx, logger, testFiles)
require.NoError(t, err) require.NoError(tb, err)
assert.NotNil(t, reader) assert.NotNil(tb, reader)
testutil.CleanupAndRequireSuccess(t, reader.Close) testutil.CleanupAndRequireSuccess(tb, reader.Close)
return reader return reader
} }

View File

@@ -26,25 +26,25 @@ import (
// constUnitID is the UnitIDGenFunc which always return 0. // constUnitID is the UnitIDGenFunc which always return 0.
func constUnitID() (id uint32) { return 0 } func constUnitID() (id uint32) { return 0 }
func assertSuccessAndUnmarshal(t *testing.T, to any, handler http.Handler, req *http.Request) { func assertSuccessAndUnmarshal(tb testing.TB, to any, handler http.Handler, req *http.Request) {
t.Helper() tb.Helper()
require.NotNil(t, handler) require.NotNil(tb, handler)
rw := httptest.NewRecorder() rw := httptest.NewRecorder()
handler.ServeHTTP(rw, req) handler.ServeHTTP(rw, req)
require.Equal(t, http.StatusOK, rw.Code) require.Equal(tb, http.StatusOK, rw.Code)
data := rw.Body.Bytes() data := rw.Body.Bytes()
if to == nil { if to == nil {
assert.Empty(t, data) assert.Empty(tb, data)
return return
} }
err := json.Unmarshal(data, to) err := json.Unmarshal(data, to)
require.NoError(t, err) require.NoError(tb, err)
} }
func TestStats(t *testing.T) { func TestStats(t *testing.T) {

View File

@@ -3,7 +3,7 @@
# This comment is used to simplify checking local copies of the script. Bump # This comment is used to simplify checking local copies of the script. Bump
# this number every time a significant change is made to this script. # this number every time a significant change is made to this script.
# #
# AdGuard-Project-Version: 13 # AdGuard-Project-Version: 14
verbose="${VERBOSE:-0}" verbose="${VERBOSE:-0}"
readonly verbose readonly verbose
@@ -26,11 +26,11 @@ set -f -u
# Simple analyzers # Simple analyzers
# blocklist_imports is a simple check against unwanted packages. The following # blocklist_imports is a simple best-effort check against unwanted packages.
# packages are banned: # The following packages are banned:
# #
# * Package errors is replaced by our own package in the # * Package errors is replaced by our own package in the
# github.com/AdguardTeam/golibs module. # github.com/AdguardTeam/golibs module.
# #
# * Packages log and github.com/AdguardTeam/golibs/log are replaced by # * Packages log and github.com/AdguardTeam/golibs/log are replaced by
# stdlib's new package log/slog and AdGuard's new utilities package # stdlib's new package log/slog and AdGuard's new utilities package
@@ -67,7 +67,10 @@ set -f -u
# #
# TODO(a.garipov): Add golibs/log. # TODO(a.garipov): Add golibs/log.
blocklist_imports() { blocklist_imports() {
find . \ import_or_tab="$(printf '^\\(import \\|\t\\)')"
readonly import_or_tab
find_with_ignore \
-type 'f' \ -type 'f' \
-name '*.go' \ -name '*.go' \
'!' '(' \ '!' '(' \
@@ -77,16 +80,16 @@ blocklist_imports() {
-exec \ -exec \
'grep' \ 'grep' \
'-H' \ '-H' \
'-e' '[[:space:]]"errors"$' \ '-e' "$import_or_tab"'"errors"$' \
'-e' '[[:space:]]"github.com/prometheus/client_golang/prometheus/promauto"$' \ '-e' "$import_or_tab"'"github.com/prometheus/client_golang/prometheus/promauto"$' \
'-e' '[[:space:]]"golang.org/x/exp/maps"$' \ '-e' "$import_or_tab"'"golang.org/x/exp/maps"$' \
'-e' '[[:space:]]"golang.org/x/exp/slices"$' \ '-e' "$import_or_tab"'"golang.org/x/exp/slices"$' \
'-e' '[[:space:]]"golang.org/x/net/context"$' \ '-e' "$import_or_tab"'"golang.org/x/net/context"$' \
'-e' '[[:space:]]"io/ioutil"$' \ '-e' "$import_or_tab"'"io/ioutil"$' \
'-e' '[[:space:]]"log"$' \ '-e' "$import_or_tab"'"log"$' \
'-e' '[[:space:]]"reflect"$' \ '-e' "$import_or_tab"'"reflect"$' \
'-e' '[[:space:]]"sort"$' \ '-e' "$import_or_tab"'"sort"$' \
'-e' '[[:space:]]"unsafe"$' \ '-e' "$import_or_tab"'"unsafe"$' \
'-n' \ '-n' \
'{}' \ '{}' \
';' ';'
@@ -94,8 +97,11 @@ blocklist_imports() {
# method_const is a simple check against the usage of some raw strings and # method_const is a simple check against the usage of some raw strings and
# numbers where one should use named constants. # numbers where one should use named constants.
#
# NOTE: Flag -H for grep is non-POSIX but all of Busybox, GNU, macOS, and
# OpenBSD support it.
method_const() { method_const() {
find . \ find_with_ignore \
-type 'f' \ -type 'f' \
-name '*.go' \ -name '*.go' \
-exec \ -exec \
@@ -116,10 +122,11 @@ method_const() {
# use of filenames like client_manager.go. # use of filenames like client_manager.go.
underscores() { underscores() {
underscore_files="$( underscore_files="$(
find . \ find_with_ignore \
-type 'f' \ -type 'f' \
-name '*_*.go' \ -name '*_*.go' \
'!' '(' -name '*_bsd.go' \ '!' '(' \
-name '*_bsd.go' \
-o -name '*_darwin.go' \ -o -name '*_darwin.go' \
-o -name '*_freebsd.go' \ -o -name '*_freebsd.go' \
-o -name '*_generate.go' \ -o -name '*_generate.go' \
@@ -206,13 +213,7 @@ run_linter ineffassign ./...
run_linter unparam ./... run_linter unparam ./...
find . \ find_with_ignore \
'(' \
-name 'node_modules' \
-type 'd' \
-prune \
')' \
-o \
-type 'f' \ -type 'f' \
'(' \ '(' \
-name 'Makefile' \ -name 'Makefile' \

View File

@@ -8,13 +8,13 @@
# This comment is used to simplify checking local copies of the script. Bump # This comment is used to simplify checking local copies of the script. Bump
# this number every time a remarkable change is made to this script. # this number every time a remarkable change is made to this script.
# #
# AdGuard-Project-Version: 4 # AdGuard-Project-Version: 5
# Deferred helpers # Deferred helpers
not_found_msg=' not_found_msg='
looks like a binary not found error. looks like a binary not found error.
make sure you have installed the linter binaries using: make sure you have installed the linter binaries, including using:
$ make go-tools $ make go-tools
' '
@@ -73,3 +73,41 @@ run_linter() (
return "$exitcode" return "$exitcode"
) )
# find_with_ignore is a wrapper around find that does not descend into ignored
# directories, such as ./tmp/.
#
# NOTE: The arguments must contain on of -exec, -ok, or -print; see
# https://pubs.opengroup.org/onlinepubs/9799919799/utilities/find.html.
#
# TODO(a.garipov): Find a way to integrate the entire gitignore, including the
# global one, without using git, as .git is not copied into the build container.
#
# Keep in sync with .gitignore.
find_with_ignore() {
find . \
'(' \
-type 'd' \
'(' \
-name '.git' \
-o -path '/agh-backup' \
-o -path './bin' \
-o -path './build' \
-o -path './client/blob-report' \
-o -path './client/playwright-report' \
-o -path './client/playwright/.cache' \
-o -path './client/test-results' \
-o -path './data' \
-o -path './dist' \
-o -path './launchpad_credentials' \
-o -path './snapcraft_login' \
-o -name 'node_modules' \
-o -name 'test-reports' \
-o -name 'tmp' \
')' \
-prune \
')' \
-o \
"$@" \
;
}

View File

@@ -3,7 +3,7 @@
# This comment is used to simplify checking local copies of the script. Bump # This comment is used to simplify checking local copies of the script. Bump
# this number every time a remarkable change is made to this script. # this number every time a remarkable change is made to this script.
# #
# AdGuard-Project-Version: 8 # AdGuard-Project-Version: 9
verbose="${VERBOSE:-0}" verbose="${VERBOSE:-0}"
readonly verbose readonly verbose
@@ -33,19 +33,7 @@ trailing_newlines() (
nl="$(printf '\n')" nl="$(printf '\n')"
readonly nl readonly nl
find . \ find_with_ignore \
'(' \
-type 'd' \
'(' \
-name 'node_modules' \
-o -path './.git' \
-o -path './bin' \
-o -path './build' \
-o -path './client/playwright-report' \
')' \
-prune \
')' \
-o \
-type 'f' \ -type 'f' \
'!' '(' \ '!' '(' \
-name '*.db' \ -name '*.db' \
@@ -71,7 +59,7 @@ trailing_newlines() (
# trailing_whitespace is a simple check that makes sure that there are no # trailing_whitespace is a simple check that makes sure that there are no
# trailing whitespace in plain-text files. # trailing whitespace in plain-text files.
trailing_whitespace() { trailing_whitespace() {
find . \ find_with_ignore \
-type 'f' \ -type 'f' \
'!' '(' \ '!' '(' \
-name '*.db' \ -name '*.db' \
@@ -84,11 +72,8 @@ trailing_whitespace() {
-o -name '*.zip' \ -o -name '*.zip' \
-o -name 'AdGuardHome' \ -o -name 'AdGuardHome' \
-o -name 'adguard-home' \ -o -name 'adguard-home' \
-o -path '*/node_modules/*' \
-o -path './.git/*' \
-o -path './bin/*' \
-o -path './build/*' \
')' \ ')' \
-print \
| while read -r f; do | while read -r f; do
grep -e '[[:space:]]$' -n -- "$f" \ grep -e '[[:space:]]$' -n -- "$f" \
| sed -e "s:^:${f}\::" -e 's/ \+$/>>>&<<</' | sed -e "s:^:${f}\::" -e 's/ \+$/>>>&<<</'
@@ -99,12 +84,8 @@ run_linter -e trailing_newlines
run_linter -e trailing_whitespace run_linter -e trailing_whitespace
find . \ find_with_ignore \
-type 'f' \ -type 'f' \
'!' '(' \
-path '*/node_modules/*' \
-o -path './data/filters/*' \
')' \
'(' \ '(' \
-name 'Makefile' \ -name 'Makefile' \
-o -name '*.conf' \ -o -name '*.conf' \