diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml
new file mode 100644
index 0000000..88cef99
--- /dev/null
+++ b/.github/workflows/bench.yml
@@ -0,0 +1,69 @@
+name: bench
+on:
+ push:
+ tags:
+ - v*
+ branches:
+ - master
+ - main
+ pull_request:
+env:
+ GO111MODULE: "on"
+jobs:
+ bench:
+ strategy:
+ matrix:
+ go-version: [ 1.16.x ]
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install Go
+ uses: actions/setup-go@v2
+ with:
+ go-version: ${{ matrix.go-version }}
+ - name: Checkout code
+ uses: actions/checkout@v2
+ - name: Restore vendor
+ uses: actions/cache@v2
+ with:
+ path: |
+ vendor
+ key: ${{ runner.os }}-go${{ matrix.go-version }}-vendor-${{ hashFiles('**/go.mod') }}
+ - name: Populate dependencies
+ run: |
+ (test -d vendor && echo vendor found) || (go mod vendor && du -sh vendor && du -sh ~/go/pkg/mod)
+ - name: Restore benchstat
+ uses: actions/cache@v2
+ with:
+ path: ~/go/bin/benchstat
+ key: ${{ runner.os }}-benchstat
+ - name: Restore base benchmark result
+ uses: actions/cache@v2
+ with:
+ path: |
+ bench-master.txt
+ bench-main.txt
+ # Use base sha for PR or new commit hash for master/main push in benchmark result key.
+ key: ${{ runner.os }}-bench-${{ (github.event.pull_request.base.sha != github.event.after) && github.event.pull_request.base.sha || github.event.after }}
+ - name: Benchmark
+ id: bench
+ run: |
+ export REF_NAME=${GITHUB_REF##*/}
+ BENCH_COUNT=5 make bench-run bench-stat
+ OUTPUT=$(make bench-stat)
+ OUTPUT="${OUTPUT//'%'/'%25'}"
+ OUTPUT="${OUTPUT//$'\n'/'%0A'}"
+ OUTPUT="${OUTPUT//$'\r'/'%0D'}"
+ echo "::set-output name=result::$OUTPUT"
+ - name: Comment Benchmark Result
+ uses: marocchino/sticky-pull-request-comment@v2
+ with:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ header: bench
+ message: |
+ ### Benchmark Result
+ Benchmark diff with base branch
+
+ ```
+ ${{ steps.bench.outputs.result }}
+ ```
+
diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml
new file mode 100644
index 0000000..c857562
--- /dev/null
+++ b/.github/workflows/test-unit.yml
@@ -0,0 +1,75 @@
+name: test-unit
+on:
+ push:
+ branches:
+ - master
+ - main
+ pull_request:
+env:
+ GO111MODULE: "on"
+jobs:
+ test:
+ strategy:
+ matrix:
+ go-version: [ 1.16.x ]
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install Go
+ uses: actions/setup-go@v2
+ with:
+ go-version: ${{ matrix.go-version }}
+ - name: Checkout code
+ uses: actions/checkout@v2
+ - name: Restore base test coverage
+ uses: actions/cache@v2
+ with:
+ path: |
+ unit-base.txt
+ # Use base sha for PR or new commit hash for master/main push in test result key.
+ key: ${{ runner.os }}-unit-test-coverage-${{ (github.event.pull_request.base.sha != github.event.after) && github.event.pull_request.base.sha || github.event.after }}
+ - name: Restore vendor
+ uses: actions/cache@v2
+ with:
+ path: |
+ vendor
+ key: ${{ runner.os }}-go${{ matrix.go-version }}-vendor-${{ hashFiles('**/go.mod') }}
+ - name: Populate dependencies
+ run: |
+ (test -d vendor && echo vendor found) || (go mod vendor && du -sh vendor && du -sh ~/go/pkg/mod)
+ - name: Test
+ id: test
+ run: |
+ make test-unit
+ go tool cover -func=./unit.coverprofile | sed -e 's/.go:[0-9]*:\t/.go\t/g' | sed -e 's/\t\t*/\t/g' > unit.txt
+ OUTPUT=$(test -e unit-base.txt && (diff unit-base.txt unit.txt || exit 0) || cat unit.txt)
+ OUTPUT="${OUTPUT//'%'/'%25'}"
+ OUTPUT="${OUTPUT//$'\n'/'%0A'}"
+ OUTPUT="${OUTPUT//$'\r'/'%0D'}"
+ TOTAL=$(grep 'total:' unit.txt)
+ echo "::set-output name=diff::$OUTPUT"
+ echo "::set-output name=total::$TOTAL"
+ - name: Store base coverage
+ if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }}
+ run: cp unit.txt unit-base.txt
+ - name: Comment Test Coverage
+ if: matrix.go-version == '1.16.x'
+ uses: marocchino/sticky-pull-request-comment@v2
+ with:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ header: unit-test
+ message: |
+ ### Unit Test Coverage
+ ${{ steps.test.outputs.total }}
+ Coverage diff with base branch
+
+ ```diff
+ ${{ steps.test.outputs.diff }}
+ ```
+
+
+ - name: Upload code coverage
+ if: matrix.go-version == '1.16.x'
+ uses: codecov/codecov-action@v1
+ with:
+ file: ./unit.coverprofile
+ flags: unittests
diff --git a/.golangci.yml b/.golangci.yml
index 29af06a..4e30af6 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -26,6 +26,7 @@ linters:
- goerr113
- wrapcheck
- exhaustivestruct
+ - cyclop
issues:
exclude-use-default: false
diff --git a/Makefile b/Makefile
index 664b505..527347c 100644
--- a/Makefile
+++ b/Makefile
@@ -31,6 +31,7 @@ endif
-include $(DEVGO_PATH)/makefiles/main.mk
-include $(DEVGO_PATH)/makefiles/test-unit.mk
-include $(DEVGO_PATH)/makefiles/lint.mk
+-include $(DEVGO_PATH)/makefiles/bench.mk
-include $(DEVGO_PATH)/makefiles/github-actions.mk
## Run tests
diff --git a/README.md b/README.md
index c9fd569..5488dc1 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# statigz
-
+[![Build Status](https://github.com/vearutop/statigz/workflows/test-unit/badge.svg)](https://github.com/vearutop/statigz/actions?query=branch%3Amaster+workflow%3Atest-unit)
+[![Coverage Status](https://codecov.io/gh/vearutop/statigz/branch/master/graph/badge.svg)](https://codecov.io/gh/vearutop/statigz)
[![GoDevDoc](https://img.shields.io/badge/dev-doc-00ADD8?logo=go)](https://pkg.go.dev/github.com/vearutop/statigz)
[![Time Tracker](https://wakatime.com/badge/github/vearutop/statigz.svg)](https://wakatime.com/badge/github/vearutop/statigz)
![Code lines](https://sloc.xyz/github/vearutop/statigz/?category=code)
diff --git a/go.mod b/go.mod
index 264f015..fe75bc3 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.16
require (
github.com/andybalholm/brotli v1.0.1
- github.com/bool64/dev v0.1.13
+ github.com/bool64/dev v0.1.18
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/stretchr/testify v1.7.0
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..aa3408a
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,19 @@
+github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc=
+github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
+github.com/bool64/dev v0.1.18 h1:uMN5MsHrVWmtRoauefI8wD86b8vbXYnrCZlIhFGyuXI=
+github.com/bool64/dev v0.1.18/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/server_test.go b/server_test.go
index f4e6c65..e3f388f 100644
--- a/server_test.go
+++ b/server_test.go
@@ -150,6 +150,23 @@ func TestServer_ServeHTTP_head_gz(t *testing.T) {
assert.Len(t, rw.Body.String(), 0)
}
+func BenchmarkServer_ServeHTTP(b *testing.B) {
+ s := statigz.FileServer(v, statigz.EncodeOnInit)
+
+ req, err := http.NewRequest(http.MethodGet, "/_testdata/swagger.json", nil)
+ require.NoError(b, err)
+
+ req.Header.Set("Accept-Encoding", "gzip, br")
+
+ b.ResetTimer()
+ b.ReportAllocs()
+
+ for i := 0; i < b.N; i++ {
+ rw := httptest.NewRecorder()
+ s.ServeHTTP(rw, req)
+ }
+}
+
func TestServer_ServeHTTP_get_gz(t *testing.T) {
s := statigz.FileServer(v, statigz.EncodeOnInit)