-
-
Notifications
You must be signed in to change notification settings - Fork 214
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
build(tests): e2e integration tests with docker and testcontainers
- Loading branch information
Showing
17 changed files
with
1,835 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,4 10,5 @@ node_modules | |
.gitignore | ||
*.md | ||
LICENSE | ||
vendor | ||
vendor | ||
e2e/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,27 @@ | ||
name: Run e2e tests | ||
|
||
on: | ||
push: | ||
pull_request: | ||
|
||
jobs: | ||
e2e-test: | ||
name: Build Docker image | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Set up Go | ||
uses: actions/setup-go@v3 | ||
with: | ||
go-version-file: go.mod | ||
id: go | ||
|
||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v2 | ||
|
||
- name: Run e2e | ||
run: make e2e-test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 1,7 @@ | ||
.idea/ | ||
.vscode/ | ||
*.iml | ||
*.test | ||
/*.pem | ||
bin/ | ||
dist/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,3 77,4 @@ issues: | |
linters: | ||
- gochecknoglobals | ||
- dupl | ||
- gosec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 1,4 @@ | ||
.PHONY: all clean build swagger test lint run fmt docker-build help | ||
.PHONY: all clean build swagger test e2e-test lint run fmt docker-build help | ||
.DEFAULT_GOAL:=help | ||
|
||
VERSION?=$(shell git describe --always --tags) | ||
|
@@ -54,11 54,20 @@ ifdef BIN_AUTOCAB | |
setcap 'cap_net_bind_service= ep' $(GO_BUILD_OUTPUT) | ||
endif | ||
|
||
test: ## run tests | ||
go run github.com/onsi/ginkgo/v2/ginkgo -v --coverprofile=coverage.txt --covermode=atomic -cover ./... | ||
test: ## run tests | ||
go run github.com/onsi/ginkgo/v2/ginkgo --label-filter="!e2e" --coverprofile=coverage.txt --covermode=atomic -cover ./... | ||
|
||
e2e-test: ## run e2e tests | ||
docker buildx build \ | ||
--build-arg VERSION=blocky-e2e \ | ||
--network=host \ | ||
-o type=docker \ | ||
-t blocky-e2e \ | ||
. | ||
go run github.com/onsi/ginkgo/v2/ginkgo --label-filter="e2e" ./... | ||
|
||
race: ## run tests with race detector | ||
go run github.com/onsi/ginkgo/v2/ginkgo --race ./... | ||
go run github.com/onsi/ginkgo/v2/ginkgo --label-filter="!e2e" --race ./... | ||
|
||
lint: ## run golangcli-lint checks | ||
go install github.com/golangci/golangci-lint/cmd/[email protected] | ||
|
@@ -81,4 90,4 @@ docker-build: ## Build docker image | |
. | ||
|
||
help: ## Shows help | ||
@grep -E '^[a-zA-Z_-] :.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' | ||
@grep -E '^[0-9a-zA-Z_-] :.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,110 @@ | ||
package e2e | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net" | ||
"net/http" | ||
|
||
. "github.com/0xERR0R/blocky/helpertest" | ||
"github.com/0xERR0R/blocky/util" | ||
"github.com/miekg/dns" | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
"github.com/testcontainers/testcontainers-go" | ||
) | ||
|
||
var _ = Describe("Basic functional tests", func() { | ||
var blocky, moka testcontainers.Container | ||
var err error | ||
|
||
Describe("Container start", func() { | ||
BeforeEach(func() { | ||
moka, err = createDNSMokkaContainer("moka1", `A google/NOERROR("A 1.2.3.4 123")`) | ||
|
||
Expect(err).Should(Succeed()) | ||
DeferCleanup(moka.Terminate) | ||
}) | ||
When("Minimal configuration is provided", func() { | ||
BeforeEach(func() { | ||
|
||
blocky, err = createBlockyContainer(tmpDir, | ||
"upstream:", | ||
" default:", | ||
" - moka1", | ||
) | ||
|
||
Expect(err).Should(Succeed()) | ||
DeferCleanup(blocky.Terminate) | ||
}) | ||
It("Should start and answer DNS queries", func() { | ||
msg := util.NewMsgWithQuestion("google.de.", dns.Type(dns.TypeA)) | ||
|
||
Expect(doDNSRequest(blocky, msg)).Should(BeDNSRecord("google.de.", dns.TypeA, 123, "1.2.3.4")) | ||
}) | ||
It("should return 'healthy' container status (healthcheck)", func() { | ||
Eventually(func(g Gomega) string { | ||
state, err := blocky.State(context.Background()) | ||
g.Expect(err).NotTo(HaveOccurred()) | ||
|
||
return state.Health.Status | ||
}, "2m", "1s").Should(Equal("healthy")) | ||
}) | ||
}) | ||
Context("http port configuration", func() { | ||
When("'httpPort' is not defined", func() { | ||
BeforeEach(func() { | ||
blocky, err = createBlockyContainer(tmpDir, | ||
"upstream:", | ||
" default:", | ||
" - moka1", | ||
) | ||
|
||
Expect(err).Should(Succeed()) | ||
DeferCleanup(blocky.Terminate) | ||
}) | ||
|
||
It("should not open http port", func() { | ||
host, port, err := getContainerHostPort(blocky, "4000/tcp") | ||
Expect(err).Should(Succeed()) | ||
|
||
_, err = http.Get(fmt.Sprintf("http://%s", net.JoinHostPort(host, port))) | ||
Expect(err).Should(HaveOccurred()) | ||
}) | ||
}) | ||
When("'httpPort' is defined", func() { | ||
BeforeEach(func() { | ||
blocky, err = createBlockyContainer(tmpDir, | ||
"upstream:", | ||
" default:", | ||
" - moka1", | ||
"httpPort: 4000", | ||
) | ||
|
||
Expect(err).Should(Succeed()) | ||
DeferCleanup(blocky.Terminate) | ||
}) | ||
It("should serve http content", func() { | ||
host, port, err := getContainerHostPort(blocky, "4000/tcp") | ||
Expect(err).Should(Succeed()) | ||
url := fmt.Sprintf("http://%s", net.JoinHostPort(host, port)) | ||
|
||
By("serve static html content", func() { | ||
Eventually(http.Get).WithArguments(url).Should(HaveHTTPStatus(http.StatusOK)) | ||
}) | ||
By("serve pprof endpoint", func() { | ||
Eventually(http.Get).WithArguments(url "/debug/").Should(HaveHTTPStatus(http.StatusOK)) | ||
}) | ||
By("prometheus endpoint should be disabled", func() { | ||
Eventually(http.Get).WithArguments(url "/metrics").Should(HaveHTTPStatus(http.StatusNotFound)) | ||
}) | ||
By("serve DoH endpoint", func() { | ||
Eventually(http.Get).WithArguments(url | ||
"/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB").Should(HaveHTTPStatus(http.StatusOK)) | ||
}) | ||
}) | ||
}) | ||
}) | ||
|
||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,117 @@ | ||
package e2e | ||
|
||
import ( | ||
. "github.com/0xERR0R/blocky/helpertest" | ||
"github.com/0xERR0R/blocky/util" | ||
"github.com/miekg/dns" | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
"github.com/testcontainers/testcontainers-go" | ||
) | ||
|
||
var _ = Describe("External lists and query blocking", func() { | ||
var blocky, httpServer, moka testcontainers.Container | ||
var err error | ||
BeforeEach(func() { | ||
moka, err = createDNSMokkaContainer("moka", `A google/NOERROR("A 1.2.3.4 123")`) | ||
|
||
Expect(err).Should(Succeed()) | ||
DeferCleanup(moka.Terminate) | ||
}) | ||
Describe("List download on startup", func() { | ||
When("external blacklist ist not available", func() { | ||
Context("startStrategy = blocking", func() { | ||
BeforeEach(func() { | ||
blocky, err = createBlockyContainer(tmpDir, | ||
"logLevel: warn", | ||
"upstream:", | ||
" default:", | ||
" - moka", | ||
"blocking:", | ||
" startStrategy: blocking", | ||
" blackLists:", | ||
" ads:", | ||
" - http://wrong.domain.url/list.txt", | ||
" clientGroupsBlock:", | ||
" default:", | ||
" - ads", | ||
) | ||
|
||
Expect(err).Should(Succeed()) | ||
DeferCleanup(blocky.Terminate) | ||
}) | ||
|
||
It("should start with warning in log work without errors", func() { | ||
|
||
msg := util.NewMsgWithQuestion("google.com.", dns.Type(dns.TypeA)) | ||
|
||
Expect(doDNSRequest(blocky, msg)).Should(BeDNSRecord("google.com.", dns.TypeA, 123, "1.2.3.4")) | ||
|
||
Expect(getContainerLogs(blocky)).Should(ContainElement(ContainSubstring("error during file processing"))) | ||
}) | ||
}) | ||
Context("startStrategy = failOnError", func() { | ||
BeforeEach(func() { | ||
blocky, err = createBlockyContainer(tmpDir, | ||
"logLevel: warn", | ||
"upstream:", | ||
" default:", | ||
" - moka", | ||
"blocking:", | ||
" startStrategy: failOnError", | ||
" blackLists:", | ||
" ads:", | ||
" - http://wrong.domain.url/list.txt", | ||
" clientGroupsBlock:", | ||
" default:", | ||
" - ads", | ||
) | ||
|
||
Expect(err).Should(HaveOccurred()) | ||
DeferCleanup(blocky.Terminate) | ||
}) | ||
|
||
It("should fail to start", func() { | ||
Expect(blocky.IsRunning()).Should(BeFalse()) | ||
|
||
Expect(getContainerLogs(blocky)). | ||
Should(ContainElement(ContainSubstring("Error: can't start server: 1 error occurred"))) | ||
}) | ||
}) | ||
}) | ||
}) | ||
Describe("Query blocking against external blacklists", func() { | ||
When("external blacklists are defined and available", func() { | ||
BeforeEach(func() { | ||
httpServer, err = createHTTPServerContainer("httpserver", tmpDir, "list.txt", "blockeddomain.com") | ||
|
||
Expect(err).Should(Succeed()) | ||
DeferCleanup(httpServer.Terminate) | ||
|
||
blocky, err = createBlockyContainer(tmpDir, | ||
"logLevel: warn", | ||
"upstream:", | ||
" default:", | ||
" - moka", | ||
"blocking:", | ||
" blackLists:", | ||
" ads:", | ||
" - http://httpserver:8080/list.txt", | ||
" clientGroupsBlock:", | ||
" default:", | ||
" - ads", | ||
) | ||
|
||
Expect(err).Should(Succeed()) | ||
DeferCleanup(blocky.Terminate) | ||
}) | ||
It("should download external list on startup and block queries", func() { | ||
msg := util.NewMsgWithQuestion("blockeddomain.com.", dns.Type(dns.TypeA)) | ||
|
||
Expect(doDNSRequest(blocky, msg)).Should(BeDNSRecord("blockeddomain.com.", dns.TypeA, 6*60*60, "0.0.0.0")) | ||
|
||
Expect(getContainerLogs(blocky)).Should(BeEmpty()) | ||
}) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.