mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-21 08:21:51 +02:00
test: improve tests
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
||||
"github.com/puzpuzpuz/xsync/v4"
|
||||
"github.com/rs/zerolog/log"
|
||||
@@ -50,6 +51,15 @@ var _ entrypoint.Entrypoint = &Entrypoint{}
|
||||
|
||||
var emptyCfg Config
|
||||
|
||||
func NewTestEntrypoint(t testing.TB, cfg *Config) *Entrypoint {
|
||||
t.Helper()
|
||||
|
||||
task := task.GetTestTask(t)
|
||||
ep := NewEntrypoint(task, cfg)
|
||||
entrypoint.SetCtx(task, ep)
|
||||
return ep
|
||||
}
|
||||
|
||||
func NewEntrypoint(parent task.Parent, cfg *Config) *Entrypoint {
|
||||
if cfg == nil {
|
||||
cfg = &emptyCfg
|
||||
@@ -91,6 +101,10 @@ func NewEntrypoint(parent task.Parent, cfg *Config) *Entrypoint {
|
||||
return ep
|
||||
}
|
||||
|
||||
func (ep *Entrypoint) Task() *task.Task {
|
||||
return ep.task
|
||||
}
|
||||
|
||||
func (ep *Entrypoint) SupportProxyProtocol() bool {
|
||||
return ep.cfg.SupportProxyProtocol
|
||||
}
|
||||
@@ -122,7 +136,7 @@ func (ep *Entrypoint) ExcludedRoutes() entrypoint.RWPoolLike[types.Route] {
|
||||
return ep.excludedRoutes
|
||||
}
|
||||
|
||||
func (ep *Entrypoint) GetServer(addr string) (http.Handler, bool) {
|
||||
func (ep *Entrypoint) GetServer(addr string) (HTTPServer, bool) {
|
||||
return ep.servers.Load(addr)
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ func (t noopTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
}
|
||||
|
||||
func BenchmarkEntrypointReal(b *testing.B) {
|
||||
task := task.NewTestTask(b)
|
||||
task := task.GetTestTask(b)
|
||||
ep := NewEntrypoint(task, nil)
|
||||
req := http.Request{
|
||||
Method: "GET",
|
||||
@@ -81,7 +81,7 @@ func BenchmarkEntrypointReal(b *testing.B) {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
r, err := route.NewTestRoute(b, task, &route.Route{
|
||||
r, err := route.NewStartedTestRoute(b, &route.Route{
|
||||
Alias: "test",
|
||||
Scheme: routeTypes.SchemeHTTP,
|
||||
Host: host,
|
||||
@@ -112,7 +112,7 @@ func BenchmarkEntrypointReal(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkEntrypoint(b *testing.B) {
|
||||
task := task.NewTestTask(b)
|
||||
task := task.GetTestTask(b)
|
||||
ep := NewEntrypoint(task, nil)
|
||||
req := http.Request{
|
||||
Method: "GET",
|
||||
@@ -122,7 +122,7 @@ func BenchmarkEntrypoint(b *testing.B) {
|
||||
ep.SetFindRouteDomains([]string{})
|
||||
entrypoint.SetCtx(task, ep)
|
||||
|
||||
r, err := route.NewTestRoute(b, task, &route.Route{
|
||||
r, err := route.NewStartedTestRoute(b, &route.Route{
|
||||
Alias: "test",
|
||||
Scheme: routeTypes.SchemeHTTP,
|
||||
Host: "localhost",
|
||||
|
||||
@@ -3,48 +3,70 @@ package entrypoint_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
. "github.com/yusing/godoxy/internal/entrypoint"
|
||||
entrypoint "github.com/yusing/godoxy/internal/entrypoint/types"
|
||||
"github.com/yusing/godoxy/internal/route"
|
||||
|
||||
routeTypes "github.com/yusing/godoxy/internal/route/types"
|
||||
"github.com/yusing/godoxy/internal/types"
|
||||
"github.com/yusing/goutils/task"
|
||||
expect "github.com/yusing/goutils/testing"
|
||||
)
|
||||
|
||||
func addRoute(ep *Entrypoint, alias string) {
|
||||
ep.AddRoute(&route.ReveseProxyRoute{
|
||||
Route: &route.Route{
|
||||
Alias: alias,
|
||||
Port: route.Port{
|
||||
Proxy: 80,
|
||||
},
|
||||
func addRoute(t *testing.T, alias string) {
|
||||
t.Helper()
|
||||
|
||||
ep := entrypoint.FromCtx(task.GetTestTask(t).Context())
|
||||
require.NotNil(t, ep)
|
||||
|
||||
_, err := route.NewStartedTestRoute(t, &route.Route{
|
||||
Alias: alias,
|
||||
Scheme: routeTypes.SchemeHTTP,
|
||||
Port: route.Port{
|
||||
Listening: 1000,
|
||||
Proxy: 8080,
|
||||
},
|
||||
HealthCheck: types.HealthCheckConfig{
|
||||
Disable: true,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
route, ok := ep.HTTPRoutes().Get(alias)
|
||||
require.True(t, ok, "route not found")
|
||||
require.NotNil(t, route)
|
||||
}
|
||||
|
||||
func run(t *testing.T, match []string, noMatch []string) {
|
||||
func run(t *testing.T, ep *Entrypoint, match []string, noMatch []string) {
|
||||
t.Helper()
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
|
||||
server, ok := ep.GetServer(":1000")
|
||||
require.True(t, ok, "server not found")
|
||||
require.NotNil(t, server)
|
||||
|
||||
for _, test := range match {
|
||||
t.Run(test, func(t *testing.T) {
|
||||
found, ok := ep.HTTPRoutes().Get(test)
|
||||
expect.True(t, ok)
|
||||
expect.NotNil(t, found)
|
||||
route := server.FindRoute(test)
|
||||
assert.NotNil(t, route)
|
||||
})
|
||||
}
|
||||
|
||||
for _, test := range noMatch {
|
||||
t.Run(test, func(t *testing.T) {
|
||||
found, ok := ep.HTTPRoutes().Get(test)
|
||||
expect.False(t, ok)
|
||||
expect.Nil(t, found)
|
||||
assert.False(t, ok)
|
||||
assert.Nil(t, found)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindRouteAnyDomain(t *testing.T) {
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
addRoute(ep, "app1")
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
|
||||
addRoute(t, "app1")
|
||||
|
||||
tests := []string{
|
||||
"app1.com",
|
||||
@@ -58,11 +80,12 @@ func TestFindRouteAnyDomain(t *testing.T) {
|
||||
"app2.sub.domain.com",
|
||||
}
|
||||
|
||||
run(t, tests, testsNoMatch)
|
||||
run(t, ep, tests, testsNoMatch)
|
||||
}
|
||||
|
||||
func TestFindRouteExactHostMatch(t *testing.T) {
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
|
||||
tests := []string{
|
||||
"app2.com",
|
||||
"app2.domain.com",
|
||||
@@ -76,20 +99,20 @@ func TestFindRouteExactHostMatch(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
addRoute(ep, test)
|
||||
addRoute(t, test)
|
||||
}
|
||||
|
||||
run(t, tests, testsNoMatch)
|
||||
run(t, ep, tests, testsNoMatch)
|
||||
}
|
||||
|
||||
func TestFindRouteByDomains(t *testing.T) {
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
ep.SetFindRouteDomains([]string{
|
||||
".domain.com",
|
||||
".sub.domain.com",
|
||||
})
|
||||
|
||||
addRoute(ep, "app1")
|
||||
addRoute(t, "app1")
|
||||
|
||||
tests := []string{
|
||||
"app1.domain.com",
|
||||
@@ -105,17 +128,17 @@ func TestFindRouteByDomains(t *testing.T) {
|
||||
"app2.sub.domain.com",
|
||||
}
|
||||
|
||||
run(t, tests, testsNoMatch)
|
||||
run(t, ep, tests, testsNoMatch)
|
||||
}
|
||||
|
||||
func TestFindRouteByDomainsExactMatch(t *testing.T) {
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
ep.SetFindRouteDomains([]string{
|
||||
".domain.com",
|
||||
".sub.domain.com",
|
||||
})
|
||||
|
||||
addRoute(ep, "app1.foo.bar")
|
||||
addRoute(t, "app1.foo.bar")
|
||||
|
||||
tests := []string{
|
||||
"app1.foo.bar", // exact match
|
||||
@@ -129,14 +152,14 @@ func TestFindRouteByDomainsExactMatch(t *testing.T) {
|
||||
"app1.sub.domain.com",
|
||||
}
|
||||
|
||||
run(t, tests, testsNoMatch)
|
||||
run(t, ep, tests, testsNoMatch)
|
||||
}
|
||||
|
||||
func TestFindRouteWithPort(t *testing.T) {
|
||||
t.Run("AnyDomain", func(t *testing.T) {
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
addRoute(ep, "app1")
|
||||
addRoute(ep, "app2.com")
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
addRoute(t, "app1")
|
||||
addRoute(t, "app2.com")
|
||||
|
||||
tests := []string{
|
||||
"app1:8080",
|
||||
@@ -148,17 +171,17 @@ func TestFindRouteWithPort(t *testing.T) {
|
||||
"app2.co",
|
||||
"app2.co:8080",
|
||||
}
|
||||
run(t, tests, testsNoMatch)
|
||||
run(t, ep, tests, testsNoMatch)
|
||||
})
|
||||
|
||||
t.Run("ByDomains", func(t *testing.T) {
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
ep.SetFindRouteDomains([]string{
|
||||
".domain.com",
|
||||
})
|
||||
addRoute(ep, "app1")
|
||||
addRoute(ep, "app2")
|
||||
addRoute(ep, "app3.domain.com")
|
||||
addRoute(t, "app1")
|
||||
addRoute(t, "app2")
|
||||
addRoute(t, "app3.domain.com")
|
||||
|
||||
tests := []string{
|
||||
"app1.domain.com:8080",
|
||||
@@ -174,6 +197,120 @@ func TestFindRouteWithPort(t *testing.T) {
|
||||
"app3.domain.co",
|
||||
"app3.domain.co:8080",
|
||||
}
|
||||
run(t, tests, testsNoMatch)
|
||||
run(t, ep, tests, testsNoMatch)
|
||||
})
|
||||
}
|
||||
|
||||
func TestHealthInfoQueries(t *testing.T) {
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
|
||||
// Add routes without health monitors (default case)
|
||||
addRoute(t, "app1")
|
||||
addRoute(t, "app2")
|
||||
|
||||
// Test GetHealthInfo
|
||||
t.Run("GetHealthInfo", func(t *testing.T) {
|
||||
info := ep.GetHealthInfo()
|
||||
expect.Equal(t, 2, len(info))
|
||||
for _, health := range info {
|
||||
expect.Equal(t, types.StatusUnknown, health.Status)
|
||||
expect.Equal(t, "n/a", health.Detail)
|
||||
}
|
||||
})
|
||||
|
||||
// Test GetHealthInfoWithoutDetail
|
||||
t.Run("GetHealthInfoWithoutDetail", func(t *testing.T) {
|
||||
info := ep.GetHealthInfoWithoutDetail()
|
||||
expect.Equal(t, 2, len(info))
|
||||
for _, health := range info {
|
||||
expect.Equal(t, types.StatusUnknown, health.Status)
|
||||
}
|
||||
})
|
||||
|
||||
// Test GetHealthInfoSimple
|
||||
t.Run("GetHealthInfoSimple", func(t *testing.T) {
|
||||
info := ep.GetHealthInfoSimple()
|
||||
expect.Equal(t, 2, len(info))
|
||||
for _, status := range info {
|
||||
expect.Equal(t, types.StatusUnknown, status)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestRoutesByProvider(t *testing.T) {
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
|
||||
// Add routes with provider info
|
||||
addRoute(t, "app1")
|
||||
addRoute(t, "app2")
|
||||
|
||||
byProvider := ep.RoutesByProvider()
|
||||
expect.Equal(t, 1, len(byProvider)) // All routes are from same implicit provider
|
||||
|
||||
routes, ok := byProvider[""]
|
||||
expect.True(t, ok)
|
||||
expect.Equal(t, 2, len(routes))
|
||||
}
|
||||
|
||||
func TestNumRoutes(t *testing.T) {
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
|
||||
expect.Equal(t, 0, ep.NumRoutes())
|
||||
|
||||
addRoute(t, "app1")
|
||||
expect.Equal(t, 1, ep.NumRoutes())
|
||||
|
||||
addRoute(t, "app2")
|
||||
expect.Equal(t, 2, ep.NumRoutes())
|
||||
}
|
||||
|
||||
func TestIterRoutes(t *testing.T) {
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
|
||||
addRoute(t, "app1")
|
||||
addRoute(t, "app2")
|
||||
addRoute(t, "app3")
|
||||
|
||||
count := 0
|
||||
for r := range ep.IterRoutes {
|
||||
count++
|
||||
expect.NotNil(t, r)
|
||||
}
|
||||
expect.Equal(t, 3, count)
|
||||
}
|
||||
|
||||
func TestGetRoute(t *testing.T) {
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
|
||||
// Route not found case
|
||||
_, ok := ep.GetRoute("nonexistent")
|
||||
expect.False(t, ok)
|
||||
|
||||
addRoute(t, "app1")
|
||||
|
||||
route, ok := ep.GetRoute("app1")
|
||||
expect.True(t, ok)
|
||||
expect.NotNil(t, route)
|
||||
}
|
||||
|
||||
func TestHTTPRoutesPool(t *testing.T) {
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
|
||||
pool := ep.HTTPRoutes()
|
||||
expect.Equal(t, 0, pool.Size())
|
||||
|
||||
addRoute(t, "app1")
|
||||
expect.Equal(t, 1, pool.Size())
|
||||
|
||||
// Verify route is accessible
|
||||
route, ok := pool.Get("app1")
|
||||
expect.True(t, ok)
|
||||
expect.NotNil(t, route)
|
||||
}
|
||||
|
||||
func TestExcludedRoutesPool(t *testing.T) {
|
||||
ep := NewTestEntrypoint(t, nil)
|
||||
|
||||
excludedPool := ep.ExcludedRoutes()
|
||||
expect.Equal(t, 0, excludedPool.Size())
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func TestShortLinkMatcher_FQDNAlias(t *testing.T) {
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
ep := NewEntrypoint(task.GetTestTask(t), nil)
|
||||
matcher := ep.ShortLinkMatcher()
|
||||
matcher.AddRoute("app.domain.com")
|
||||
|
||||
@@ -47,7 +47,7 @@ func TestShortLinkMatcher_FQDNAlias(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestShortLinkMatcher_SubdomainAlias(t *testing.T) {
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
ep := NewEntrypoint(task.GetTestTask(t), nil)
|
||||
matcher := ep.ShortLinkMatcher()
|
||||
matcher.SetDefaultDomainSuffix(".example.com")
|
||||
matcher.AddRoute("app")
|
||||
@@ -72,7 +72,7 @@ func TestShortLinkMatcher_SubdomainAlias(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestShortLinkMatcher_NotFound(t *testing.T) {
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
ep := NewEntrypoint(task.GetTestTask(t), nil)
|
||||
matcher := ep.ShortLinkMatcher()
|
||||
matcher.SetDefaultDomainSuffix(".example.com")
|
||||
matcher.AddRoute("app")
|
||||
@@ -95,7 +95,7 @@ func TestShortLinkMatcher_NotFound(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestShortLinkMatcher_AddDelRoute(t *testing.T) {
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
ep := NewEntrypoint(task.GetTestTask(t), nil)
|
||||
matcher := ep.ShortLinkMatcher()
|
||||
matcher.SetDefaultDomainSuffix(".example.com")
|
||||
|
||||
@@ -133,7 +133,7 @@ func TestShortLinkMatcher_AddDelRoute(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestShortLinkMatcher_NoDefaultDomainSuffix(t *testing.T) {
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
ep := NewEntrypoint(task.GetTestTask(t), nil)
|
||||
matcher := ep.ShortLinkMatcher()
|
||||
// no SetDefaultDomainSuffix called
|
||||
|
||||
@@ -160,7 +160,7 @@ func TestShortLinkMatcher_NoDefaultDomainSuffix(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEntrypoint_ShortLinkDispatch(t *testing.T) {
|
||||
ep := NewEntrypoint(task.NewTestTask(t), nil)
|
||||
ep := NewEntrypoint(task.GetTestTask(t), nil)
|
||||
ep.ShortLinkMatcher().SetDefaultDomainSuffix(".example.com")
|
||||
ep.ShortLinkMatcher().AddRoute("app")
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/yusing/godoxy/internal/common"
|
||||
"github.com/yusing/godoxy/internal/entrypoint"
|
||||
. "github.com/yusing/godoxy/internal/net/gphttp/middleware"
|
||||
"github.com/yusing/godoxy/internal/route"
|
||||
routeTypes "github.com/yusing/godoxy/internal/route/types"
|
||||
"github.com/yusing/goutils/http/reverseproxy"
|
||||
"github.com/yusing/goutils/task"
|
||||
expect "github.com/yusing/goutils/testing"
|
||||
)
|
||||
|
||||
@@ -231,14 +231,15 @@ func TestEntrypointBypassRoute(t *testing.T) {
|
||||
expect.NoError(t, err)
|
||||
|
||||
expect.NoError(t, err)
|
||||
entry := entrypoint.NewEntrypoint(task.NewTestTask(t), nil)
|
||||
r := &route.Route{
|
||||
entry := entrypoint.NewTestEntrypoint(t, nil)
|
||||
_, err = route.NewStartedTestRoute(t, &route.Route{
|
||||
Alias: "test-route",
|
||||
Host: host,
|
||||
Port: routeTypes.Port{
|
||||
Proxy: portInt,
|
||||
},
|
||||
}
|
||||
})
|
||||
expect.NoError(t, err)
|
||||
|
||||
err = entry.SetMiddlewares([]map[string]any{
|
||||
{
|
||||
@@ -254,13 +255,9 @@ func TestEntrypointBypassRoute(t *testing.T) {
|
||||
})
|
||||
expect.NoError(t, err)
|
||||
|
||||
err = r.Validate()
|
||||
expect.NoError(t, err)
|
||||
r.Start(task.RootTask("test", false))
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
req := httptest.NewRequest("GET", "http://test-route.example.com", nil)
|
||||
server, ok := entry.GetServer(r.ListenURL().Host)
|
||||
server, ok := entry.GetServer(common.ProxyHTTPAddr)
|
||||
if !ok {
|
||||
t.Fatal("server not found")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user