fixed and updated tests

This commit is contained in:
yusing 2024-11-28 06:52:26 +08:00
parent 23614fe0d0
commit 4533cc592f
4 changed files with 89 additions and 94 deletions

View file

@ -8,8 +8,10 @@ import (
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
"github.com/yusing/go-proxy/internal/common"
"github.com/yusing/go-proxy/internal/docker"
D "github.com/yusing/go-proxy/internal/docker"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/route"
"github.com/yusing/go-proxy/internal/route/entry"
T "github.com/yusing/go-proxy/internal/route/types"
. "github.com/yusing/go-proxy/internal/utils/testing"
@ -17,9 +19,23 @@ import (
var (
dummyNames = []string{"/a"}
p DockerProvider
)
func makeEntries(cont *types.Container, dockerHost ...string) route.RawEntries {
var p DockerProvider
var host string
if len(dockerHost) > 0 {
host = dockerHost[0]
} else {
host = client.DefaultDockerHost
}
entries := E.Must(p.entriesFromContainerLabels(docker.FromDocker(cont, host)))
entries.RangeAll(func(k string, v *route.RawEntry) {
v.Finalize()
})
return entries
}
func TestApplyLabel(t *testing.T) {
pathPatterns := `
- /
@ -41,8 +57,7 @@ func TestApplyLabel(t *testing.T) {
"prop4": "value4",
},
}
var p DockerProvider
entries, err := p.entriesFromContainerLabels(D.FromDocker(&types.Container{
entries := makeEntries(&types.Container{
Names: dummyNames,
Labels: map[string]string{
D.LabelAliases: "a,b",
@ -65,8 +80,7 @@ func TestApplyLabel(t *testing.T) {
"proxy.a.healthcheck.path": "/ping",
"proxy.a.healthcheck.interval": "10s",
},
}, client.DefaultDockerHost))
ExpectNoError(t, err)
})
a, ok := entries.Load("a")
ExpectTrue(t, ok)
@ -114,7 +128,7 @@ func TestApplyLabel(t *testing.T) {
}
func TestApplyLabelWithAlias(t *testing.T) {
entries, err := p.entriesFromContainerLabels(D.FromDocker(&types.Container{
entries := makeEntries(&types.Container{
Names: dummyNames,
State: "running",
Labels: map[string]string{
@ -124,7 +138,7 @@ func TestApplyLabelWithAlias(t *testing.T) {
"proxy.b.port": "1234",
"proxy.c.scheme": "https",
},
}, client.DefaultDockerHost))
})
a, ok := entries.Load("a")
ExpectTrue(t, ok)
b, ok := entries.Load("b")
@ -132,7 +146,6 @@ func TestApplyLabelWithAlias(t *testing.T) {
c, ok := entries.Load("c")
ExpectTrue(t, ok)
ExpectNoError(t, err)
ExpectEqual(t, a.Scheme, "http")
ExpectEqual(t, a.Port, "3333")
ExpectEqual(t, a.NoTLSVerify, true)
@ -142,7 +155,7 @@ func TestApplyLabelWithAlias(t *testing.T) {
}
func TestApplyLabelWithRef(t *testing.T) {
entries := E.Must(p.entriesFromContainerLabels(D.FromDocker(&types.Container{
entries := makeEntries(&types.Container{
Names: dummyNames,
State: "running",
Labels: map[string]string{
@ -153,7 +166,7 @@ func TestApplyLabelWithRef(t *testing.T) {
"proxy.#3.port": "1111",
"proxy.#3.scheme": "https",
},
}, client.DefaultDockerHost)))
})
a, ok := entries.Load("a")
ExpectTrue(t, ok)
b, ok := entries.Load("b")
@ -179,91 +192,92 @@ func TestApplyLabelWithRefIndexError(t *testing.T) {
"proxy.#4.scheme": "https",
},
}, "")
var p DockerProvider
_, err := p.entriesFromContainerLabels(c)
ExpectError(t, ErrAliasRefIndexOutOfRange, err)
_, err = p.entriesFromContainerLabels(D.FromDocker(&types.Container{
c = D.FromDocker(&types.Container{
Names: dummyNames,
State: "running",
Labels: map[string]string{
D.LabelAliases: "a,b",
"proxy.#0.host": "localhost",
},
}, ""))
}, "")
_, err = p.entriesFromContainerLabels(c)
ExpectError(t, ErrAliasRefIndexOutOfRange, err)
}
func TestDynamicAliases(t *testing.T) {
c := D.FromDocker(&types.Container{
c := &types.Container{
Names: []string{"app1"},
State: "running",
Labels: map[string]string{
"proxy.app1.port": "1234",
"proxy.app1_backend.port": "5678",
},
}, client.DefaultDockerHost)
}
raw, ok := E.Must(p.entriesFromContainerLabels(c)).Load("app1")
entries := makeEntries(c)
raw, ok := entries.Load("app1")
ExpectTrue(t, ok)
ExpectEqual(t, raw.Scheme, "http")
ExpectEqual(t, raw.Port, "1234")
raw, ok = E.Must(p.entriesFromContainerLabels(c)).Load("app1_backend")
raw, ok = entries.Load("app1_backend")
ExpectTrue(t, ok)
ExpectEqual(t, raw.Scheme, "http")
ExpectEqual(t, raw.Port, "5678")
}
func TestDisableHealthCheck(t *testing.T) {
c := D.FromDocker(&types.Container{
c := &types.Container{
Names: dummyNames,
State: "running",
Labels: map[string]string{
"proxy.a.healthcheck.disable": "true",
"proxy.a.port": "1234",
},
}, client.DefaultDockerHost)
raw, ok := E.Must(p.entriesFromContainerLabels(c)).Load("a")
}
raw, ok := makeEntries(c).Load("a")
ExpectTrue(t, ok)
ExpectEqual(t, raw.HealthCheck, nil)
}
func TestPublicIPLocalhost(t *testing.T) {
c := D.FromDocker(&types.Container{Names: dummyNames, State: "running"}, client.DefaultDockerHost)
raw, ok := E.Must(p.entriesFromContainerLabels(c)).Load("a")
c := &types.Container{Names: dummyNames, State: "running"}
raw, ok := makeEntries(c).Load("a")
ExpectTrue(t, ok)
ExpectEqual(t, raw.Container.PublicIP, "127.0.0.1")
ExpectEqual(t, raw.Host, raw.Container.PublicIP)
}
func TestPublicIPRemote(t *testing.T) {
c := D.FromDocker(&types.Container{Names: dummyNames, State: "running"}, "tcp://1.2.3.4:2375")
raw, ok := E.Must(p.entriesFromContainerLabels(c)).Load("a")
c := &types.Container{Names: dummyNames, State: "running"}
raw, ok := makeEntries(c, "tcp://1.2.3.4:2375").Load("a")
ExpectTrue(t, ok)
ExpectEqual(t, raw.Container.PublicIP, "1.2.3.4")
ExpectEqual(t, raw.Host, raw.Container.PublicIP)
}
func TestPrivateIPLocalhost(t *testing.T) {
c := D.FromDocker(&types.Container{
c := &types.Container{
Names: dummyNames,
NetworkSettings: &types.SummaryNetworkSettings{
Networks: map[string]*network.EndpointSettings{
"network": {
IPAddress: "172.17.0.123",
},
},
},
}, client.DefaultDockerHost)
raw, ok := E.Must(p.entriesFromContainerLabels(c)).Load("a")
}}}
raw, ok := makeEntries(c).Load("a")
ExpectTrue(t, ok)
ExpectEqual(t, raw.Container.PrivateIP, "172.17.0.123")
ExpectEqual(t, raw.Host, raw.Container.PrivateIP)
}
func TestPrivateIPRemote(t *testing.T) {
c := D.FromDocker(&types.Container{
c := &types.Container{
Names: dummyNames,
State: "running",
NetworkSettings: &types.SummaryNetworkSettings{
@ -272,9 +286,8 @@ func TestPrivateIPRemote(t *testing.T) {
IPAddress: "172.17.0.123",
},
},
},
}, "tcp://1.2.3.4:2375")
raw, ok := E.Must(p.entriesFromContainerLabels(c)).Load("a")
}}
raw, ok := makeEntries(c, "tcp://1.2.3.4:2375").Load("a")
ExpectTrue(t, ok)
ExpectEqual(t, raw.Container.PrivateIP, "")
ExpectEqual(t, raw.Container.PublicIP, "1.2.3.4")
@ -301,9 +314,7 @@ func TestStreamDefaultValues(t *testing.T) {
}
t.Run("local", func(t *testing.T) {
c := D.FromDocker(cont, client.DefaultDockerHost)
raw, ok := E.Must(p.entriesFromContainerLabels(c)).Load("a")
raw, ok := makeEntries(cont).Load("a")
ExpectTrue(t, ok)
en := E.Must(entry.ValidateEntry(raw))
a := ExpectType[*entry.StreamEntry](t, en)
@ -315,8 +326,7 @@ func TestStreamDefaultValues(t *testing.T) {
})
t.Run("remote", func(t *testing.T) {
c := D.FromDocker(cont, "tcp://1.2.3.4:2375")
raw, ok := E.Must(p.entriesFromContainerLabels(c)).Load("a")
raw, ok := makeEntries(cont, "tcp://1.2.3.4:2375").Load("a")
ExpectTrue(t, ok)
en := E.Must(entry.ValidateEntry(raw))
a := ExpectType[*entry.StreamEntry](t, en)
@ -329,34 +339,34 @@ func TestStreamDefaultValues(t *testing.T) {
}
func TestExplicitExclude(t *testing.T) {
_, ok := E.Must(p.entriesFromContainerLabels(D.FromDocker(&types.Container{
_, ok := makeEntries(&types.Container{
Names: dummyNames,
Labels: map[string]string{
D.LabelAliases: "a",
D.LabelExclude: "true",
"proxy.a.no_tls_verify": "true",
},
}, ""))).Load("a")
}, "").Load("a")
ExpectFalse(t, ok)
}
func TestImplicitExcludeDatabase(t *testing.T) {
t.Run("mount path detection", func(t *testing.T) {
_, ok := E.Must(p.entriesFromContainerLabels(D.FromDocker(&types.Container{
_, ok := makeEntries(&types.Container{
Names: dummyNames,
Mounts: []types.MountPoint{
{Source: "/data", Destination: "/var/lib/postgresql/data"},
},
}, ""))).Load("a")
}).Load("a")
ExpectFalse(t, ok)
})
t.Run("exposed port detection", func(t *testing.T) {
_, ok := E.Must(p.entriesFromContainerLabels(D.FromDocker(&types.Container{
_, ok := makeEntries(&types.Container{
Names: dummyNames,
Ports: []types.Port{
{Type: "tcp", PrivatePort: 5432, PublicPort: 5432},
},
}, ""))).Load("a")
}).Load("a")
ExpectFalse(t, ok)
})
}

View file

@ -24,6 +24,10 @@ func createGlobalTask() (t *task) {
return
}
func testResetGlobalTask() {
globalTask = createGlobalTask()
}
type (
// Task controls objects' lifetime.
//
@ -146,7 +150,7 @@ func CancelGlobalContext() {
// If the timeout is exceeded, it prints a list of all tasks that were
// still running when the timeout was reached, and their current tree
// of subtasks.
func GlobalContextWait(timeout time.Duration) {
func GlobalContextWait(timeout time.Duration) (err error) {
done := make(chan struct{})
after := time.After(timeout)
go func() {
@ -159,7 +163,7 @@ func GlobalContextWait(timeout time.Duration) {
return
case <-after:
logger.Warn().Msg("Timeout waiting for these tasks to finish:\n" + globalTask.tree())
return
return context.DeadlineExceeded
}
}
}

View file

@ -1,4 +1,4 @@
package task_test
package task
import (
"context"
@ -6,13 +6,10 @@ import (
"testing"
"time"
. "github.com/yusing/go-proxy/internal/task"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
func TestTaskCreation(t *testing.T) {
defer CancelGlobalContext()
rootTask := GlobalTask("root-task")
subTask := rootTask.Subtask("subtask")
@ -21,8 +18,6 @@ func TestTaskCreation(t *testing.T) {
}
func TestTaskCancellation(t *testing.T) {
defer CancelGlobalContext()
subTaskDone := make(chan struct{})
rootTask := GlobalTask("root-task")
@ -46,33 +41,10 @@ func TestTaskCancellation(t *testing.T) {
}
}
func TestGlobalContextCancellation(t *testing.T) {
taskDone := make(chan struct{})
rootTask := GlobalTask("root-task")
go func() {
rootTask.Wait()
close(taskDone)
}()
CancelGlobalContext()
select {
case <-taskDone:
err := rootTask.Context().Err()
ExpectError(t, context.Canceled, err)
cause := context.Cause(rootTask.Context())
ExpectError(t, ErrProgramExiting, cause)
case <-time.After(1 * time.Second):
t.Fatal("subTask context was not canceled as expected")
}
}
func TestOnComplete(t *testing.T) {
defer CancelGlobalContext()
rootTask := GlobalTask("root-task")
task := rootTask.Subtask("test")
task := GlobalTask("test")
var value atomic.Int32
task.OnFinished("set value", func() {
value.Store(1234)
@ -82,6 +54,7 @@ func TestOnComplete(t *testing.T) {
}
func TestGlobalContextWait(t *testing.T) {
testResetGlobalTask()
defer CancelGlobalContext()
rootTask := GlobalTask("root-task")
@ -122,26 +95,34 @@ func TestGlobalContextWait(t *testing.T) {
}
func TestTimeoutOnGlobalContextWait(t *testing.T) {
defer CancelGlobalContext()
testResetGlobalTask()
rootTask := GlobalTask("root-task")
subTask := rootTask.Subtask("subtask")
rootTask.Subtask("subtask")
ExpectError(t, context.DeadlineExceeded, GlobalContextWait(200*time.Millisecond))
}
func TestGlobalContextCancellation(t *testing.T) {
testResetGlobalTask()
taskDone := make(chan struct{})
rootTask := GlobalTask("root-task")
done := make(chan struct{})
go func() {
GlobalContextWait(500 * time.Millisecond)
close(done)
rootTask.Wait()
close(taskDone)
}()
CancelGlobalContext()
select {
case <-done:
t.Fatal("GlobalContextWait should have timed out")
case <-time.After(200 * time.Millisecond):
case <-taskDone:
err := rootTask.Context().Err()
ExpectError(t, context.Canceled, err)
cause := context.Cause(rootTask.Context())
ExpectError(t, ErrProgramExiting, cause)
case <-time.After(1 * time.Second):
t.Fatal("subTask context was not canceled as expected")
}
// Ensure clean exit
subTask.Finish("exit")
}
func TestGlobalContextCancel(t *testing.T) {
}

View file

@ -23,7 +23,7 @@ func IgnoreError[Result any](r Result, _ error) Result {
func ExpectNoError(t *testing.T, err error) {
t.Helper()
if err != nil && !reflect.ValueOf(err).IsNil() {
t.Errorf("expected err=nil, got %s", err)
t.Errorf("expected err=nil, got %v", err)
t.FailNow()
}
}
@ -31,7 +31,7 @@ func ExpectNoError(t *testing.T, err error) {
func ExpectError(t *testing.T, expected error, err error) {
t.Helper()
if !errors.Is(err, expected) {
t.Errorf("expected err %s, got %s", expected, err)
t.Errorf("expected err %s, got %v", expected, err)
t.FailNow()
}
}
@ -39,7 +39,7 @@ func ExpectError(t *testing.T, expected error, err error) {
func ExpectError2(t *testing.T, input any, expected error, err error) {
t.Helper()
if !errors.Is(err, expected) {
t.Errorf("%v: expected err %s, got %s", input, expected, err)
t.Errorf("%v: expected err %s, got %v", input, expected, err)
t.FailNow()
}
}