Add more tests and CI
continuous-integration/woodpecker the build failed
Details
continuous-integration/woodpecker the build failed
Details
Signed-off-by: jolheiser <john.olheiser@gmail.com>main
parent
15d69e947d
commit
dffcd8a537
|
@ -0,0 +1,54 @@
|
|||
clone:
|
||||
git:
|
||||
image: woodpeckerci/plugin-git:next
|
||||
|
||||
pipeline:
|
||||
compliance:
|
||||
image: golang:1.17
|
||||
commands:
|
||||
- go test -race ./...
|
||||
- go vet ./...
|
||||
when:
|
||||
event: pull_request
|
||||
|
||||
build:
|
||||
image: golang:1.17
|
||||
commands:
|
||||
- GOOS="linux" go build go.jolheiser.com/cabinet/cmd/cabinet
|
||||
- GOOS="windows" go build go.jolheiser.com/cabinet/cmd/cabinet
|
||||
|
||||
release-main:
|
||||
image: jolheiser/drone-gitea-main:latest
|
||||
settings:
|
||||
base_url: https://git.jojodev.com
|
||||
api_key:
|
||||
from_secret: gitea_token
|
||||
files:
|
||||
- "cabinet"
|
||||
- "cabinet.exe"
|
||||
when:
|
||||
event: push
|
||||
branch: main
|
||||
|
||||
release-tag:
|
||||
image: plugins/gitea-release:1
|
||||
settings:
|
||||
base_url: https://git.jojodev.com
|
||||
api_key:
|
||||
from_secret: gitea_token
|
||||
files:
|
||||
- "cabinet"
|
||||
- "cabinet.exe"
|
||||
when:
|
||||
event: tag
|
||||
tag: v*
|
||||
|
||||
prune:
|
||||
image: jolheiser/drone-gitea-prune
|
||||
settings:
|
||||
api_key:
|
||||
from_secret: gitea_token
|
||||
base: https://git.jojodev.com
|
||||
when:
|
||||
event: tag
|
||||
tag: v*
|
|
@ -12,7 +12,6 @@ import (
|
|||
workspace2 "go.jolheiser.com/cabinet/internal/workspace"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
|
|
@ -98,5 +98,10 @@ func (l *Limit) hasHitSizeLimit(remoteAddr string, size int64) bool {
|
|||
l.mx.Lock()
|
||||
defer l.mx.Unlock()
|
||||
|
||||
if l.request[ip] == nil {
|
||||
l.request[ip] = rate.NewLimiter(rate.Limit(l.rpm/60), l.rpm)
|
||||
l.size[ip] = rate.NewLimiter(rate.Limit(l.spm/60), l.burst)
|
||||
}
|
||||
|
||||
return !l.size[ip].AllowN(time.Now(), int(size))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/matryer/is"
|
||||
)
|
||||
|
||||
func TestLimit(t *testing.T) {
|
||||
localhost := "127.0.0.1:80"
|
||||
|
||||
t.Run("Requests Per Minute", func(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
limit := NewLimit(5, 5, 10, 10)
|
||||
for idx := 0; idx < 5; idx++ {
|
||||
assert.Equal(limit.hasHitRequestLimit(localhost), false) // Five requests is okay
|
||||
}
|
||||
assert.Equal(limit.hasHitRequestLimit(localhost), true) // A sixth requests is not okay
|
||||
})
|
||||
|
||||
t.Run("Size Per Minute", func(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
limit := NewLimit(5, 5, 5, 10)
|
||||
for idx := 0; idx < 5; idx++ {
|
||||
assert.Equal(limit.hasHitSizeLimit(localhost, 1), false) // Five requests is okay
|
||||
}
|
||||
assert.Equal(limit.hasHitSizeLimit(localhost, 1), true) // A sixth requests is not okay
|
||||
})
|
||||
|
||||
t.Run("Size Per Minute w/Burst", func(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
limit := NewLimit(5, 5, 10, 10)
|
||||
for idx := 0; idx < 10; idx++ {
|
||||
assert.Equal(limit.hasHitSizeLimit(localhost, 1), false) // Ten requests is okay (with Burst)
|
||||
}
|
||||
assert.Equal(limit.hasHitSizeLimit(localhost, 1), true) // An eleventh requests is not okay (with Burst)
|
||||
})
|
||||
}
|
|
@ -7,13 +7,16 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/matryer/is"
|
||||
"go.jolheiser.com/cabinet"
|
||||
"go.jolheiser.com/cabinet/internal/workspace"
|
||||
"go.jolheiser.com/cabinet/internal/workspace/mock"
|
||||
|
||||
"github.com/matryer/is"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
func TestRouter(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
zerolog.SetGlobalLevel(zerolog.Disabled)
|
||||
|
||||
m := mock.New()
|
||||
server := httptest.NewUnstartedServer(nil)
|
||||
|
@ -24,20 +27,68 @@ func TestRouter(t *testing.T) {
|
|||
|
||||
c := cabinet.New(server.URL, cabinet.WithHTTPClient(server.Client()))
|
||||
|
||||
// Redirect
|
||||
redir := "https://duckduckgo.com"
|
||||
u, _, err := c.Redirect(redir)
|
||||
assert.NoErr(err) // Creating a redirect should succeed
|
||||
resp, err := http.Get(u)
|
||||
assert.NoErr(err)
|
||||
assert.Equal(redir, resp.Request.URL.String()) // The redirect should match what was given
|
||||
testRouter(t, "No Token", true, true, c)
|
||||
|
||||
file := "foobar"
|
||||
f, _, err := c.File("test.txt", strings.NewReader(file))
|
||||
assert.NoErr(err) // Creating a file should succeed
|
||||
resp, err = http.Get(f)
|
||||
assert.NoErr(err)
|
||||
b, err := io.ReadAll(resp.Body)
|
||||
assert.NoErr(err)
|
||||
assert.Equal(file, string(b)) // The file should match what was given
|
||||
// All token
|
||||
aToken := workspace.Token{Key: "all", Permission: workspace.TokenFile | workspace.TokenRedirect}
|
||||
_ = m.AddToken(aToken)
|
||||
testRouter(t, "Incorrect Token", false, false, c)
|
||||
c.Token = aToken.Key
|
||||
testRouter(t, "All Token", true, true, c)
|
||||
|
||||
// Redirect token
|
||||
rToken := workspace.Token{Key: "redirect", Permission: workspace.TokenRedirect}
|
||||
_ = m.AddToken(rToken)
|
||||
c.Token = rToken.Key
|
||||
testRouter(t, "Redirect Token", true, false, c)
|
||||
|
||||
// File token
|
||||
fToken := workspace.Token{Key: "file", Permission: workspace.TokenFile}
|
||||
_ = m.AddToken(fToken)
|
||||
c.Token = fToken.Key
|
||||
testRouter(t, "File Token", false, true, c)
|
||||
}
|
||||
|
||||
func testRouter(t *testing.T, name string, rSucceed, fSucceed bool, c *cabinet.Client) {
|
||||
// Redirect
|
||||
t.Run(name+" Redirect", func(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
redir := "https://duckduckgo.com"
|
||||
u, res, err := c.Redirect(redir)
|
||||
switch {
|
||||
case rSucceed:
|
||||
assert.NoErr(err) // Creating a redirect should succeed
|
||||
resp, err := http.Get(u)
|
||||
assert.NoErr(err)
|
||||
assert.Equal(redir, resp.Request.URL.String()) // The redirect should match what was given
|
||||
case c.Token == "":
|
||||
assert.Equal(res.StatusCode, http.StatusUnauthorized) // Creating a redirect should be unauthorized
|
||||
case c.Token != "":
|
||||
assert.Equal(res.StatusCode, http.StatusForbidden) // Creating a redirect should be forbidden
|
||||
default:
|
||||
assert.Fail() // Unknown case in test
|
||||
}
|
||||
})
|
||||
|
||||
// File
|
||||
t.Run(name+" File", func(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
file := "foobar"
|
||||
f, res, err := c.File("test.txt", strings.NewReader(file))
|
||||
switch {
|
||||
case fSucceed:
|
||||
assert.NoErr(err) // Creating a file should succeed
|
||||
resp, err := http.Get(f)
|
||||
assert.NoErr(err)
|
||||
b, err := io.ReadAll(resp.Body)
|
||||
assert.NoErr(err)
|
||||
assert.Equal(file, string(b)) // The file should match what was given
|
||||
case c.Token == "":
|
||||
assert.Equal(res.StatusCode, http.StatusUnauthorized) // Creating a redirect should be unauthorized
|
||||
case c.Token != "":
|
||||
assert.Equal(res.StatusCode, http.StatusForbidden) // Creating a redirect should be forbidden
|
||||
default:
|
||||
assert.Fail() // Unknown case in test
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue