mirror of
https://github.com/umputun/reproxy.git
synced 2026-04-24 19:13:44 +02:00
089e683067
- add new linter rules to .golangci.yml (errorlint, wrapcheck, testifylint, nestif) - fix errorlint: use errors.Is/As instead of direct comparison - fix wrapcheck: wrap errors with context using %w - fix testifylint: use assert.Len, assert.Empty, assert.True/False, require.ErrorIs - fix go-require: use assert in goroutines and HTTP handlers - update CI: add disk space cleanup, bump Go to 1.25, update actions versions
86 lines
2.4 KiB
Go
86 lines
2.4 KiB
Go
package lib
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
|
|
log "github.com/go-pkgz/lgr"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestPlugin_Do(t *testing.T) {
|
|
|
|
var postCalls int32
|
|
var deleteCalls int32
|
|
tsConductor := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case "POST":
|
|
atomic.AddInt32(&postCalls, 1)
|
|
case "DELETE":
|
|
atomic.AddInt32(&deleteCalls, 1)
|
|
default:
|
|
t.Fatalf("unexpected method %s", r.Method)
|
|
}
|
|
t.Logf("registration: %+v", r)
|
|
}))
|
|
defer tsConductor.Close()
|
|
|
|
u, err := url.Parse(tsConductor.URL)
|
|
require.NoError(t, err)
|
|
p := Plugin{Name: "Test1", Address: "localhost:12345", Methods: []string{"H1", "H2"}}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
|
defer cancel()
|
|
err = p.Do(ctx, "http://"+u.Host, new(TestingHandler))
|
|
require.EqualError(t, err, "context done: context deadline exceeded")
|
|
assert.Equal(t, int32(1), atomic.LoadInt32(&postCalls))
|
|
assert.Equal(t, int32(1), atomic.LoadInt32(&deleteCalls))
|
|
}
|
|
|
|
func TestPlugin_DoFailed(t *testing.T) {
|
|
tsConductor := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(500)
|
|
}))
|
|
defer tsConductor.Close()
|
|
|
|
u, err := url.Parse(tsConductor.URL)
|
|
require.NoError(t, err)
|
|
p := Plugin{Name: "Test2", Address: "localhost:12345", Methods: []string{"H1", "H2"}}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
err = p.Do(ctx, "http://"+u.Host, new(TestingHandler))
|
|
assert.EqualError(t, err, "context done: context canceled")
|
|
}
|
|
|
|
// TestingHandler is an example of middleware handler altering headers and stastus
|
|
type TestingHandler struct{}
|
|
|
|
// HeaderThing adds key:val header to the response
|
|
func (h *TestingHandler) H1(req Request, res *Response) (err error) {
|
|
log.Printf("req: %+v", req)
|
|
res.HeadersOut = http.Header{}
|
|
res.HeadersOut.Add("key", "val")
|
|
res.HeadersIn = http.Header{}
|
|
res.HeadersIn.Add("token", "something")
|
|
res.StatusCode = 200 // each handler has to set status code
|
|
return
|
|
}
|
|
|
|
// ErrorThing returns status 500 on "/fail" url. This terminated processing chain on reproxy side immediately
|
|
func (h *TestingHandler) H2(req Request, res *Response) (err error) {
|
|
log.Printf("req: %+v", req)
|
|
if req.URL == "/fail" {
|
|
res.StatusCode = 500
|
|
return
|
|
}
|
|
res.StatusCode = 200
|
|
return
|
|
}
|