GoDoxy/internal/task/task_test.go
yusing 53557e38b6 Fixed a few issues:
- Incorrect name being shown on dashboard "Proxies page"
- Apps being shown when homepage.show is false
- Load balanced routes are shown on homepage instead of the load balancer
- Route with idlewatcher will now be removed on container destroy
- Idlewatcher panic
- Performance improvement
- Idlewatcher infinitely loading
- Reload stucked / not working properly
- Streams stuck on shutdown / reload
- etc...
Added:
- support idlewatcher for loadbalanced routes
- partial implementation for stream type idlewatcher
Issues:
- graceful shutdown
2024-10-18 16:47:01 +08:00

147 lines
3 KiB
Go

package task_test
import (
"context"
"sync/atomic"
"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")
ExpectEqual(t, "root-task", rootTask.Name())
ExpectEqual(t, "subtask", subTask.Name())
}
func TestTaskCancellation(t *testing.T) {
defer CancelGlobalContext()
subTaskDone := make(chan struct{})
rootTask := GlobalTask("root-task")
subTask := rootTask.Subtask("subtask")
go func() {
subTask.Wait()
close(subTaskDone)
}()
go rootTask.Finish("done")
select {
case <-subTaskDone:
err := subTask.Context().Err()
ExpectError(t, context.Canceled, err)
cause := context.Cause(subTask.Context())
ExpectError(t, ErrTaskCancelled, cause)
case <-time.After(1 * time.Second):
t.Fatal("subTask context was not canceled as expected")
}
}
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()
task := GlobalTask("test")
var value atomic.Int32
task.OnComplete("set value", func() {
value.Store(1234)
})
task.Finish("done")
ExpectEqual(t, value.Load(), 1234)
}
func TestGlobalContextWait(t *testing.T) {
defer CancelGlobalContext()
rootTask := GlobalTask("root-task")
finished1, finished2 := false, false
subTask1 := rootTask.Subtask("subtask1")
subTask2 := rootTask.Subtask("subtask2")
subTask1.OnComplete("set finished", func() {
finished1 = true
})
subTask2.OnComplete("set finished", func() {
finished2 = true
})
go func() {
time.Sleep(500 * time.Millisecond)
subTask1.Finish("done")
}()
go func() {
time.Sleep(500 * time.Millisecond)
subTask2.Finish("done")
}()
go func() {
subTask1.Wait()
subTask2.Wait()
rootTask.Finish("done")
}()
GlobalContextWait(1 * time.Second)
ExpectTrue(t, finished1)
ExpectTrue(t, finished2)
ExpectError(t, context.Canceled, rootTask.Context().Err())
ExpectError(t, ErrTaskCancelled, context.Cause(subTask1.Context()))
ExpectError(t, ErrTaskCancelled, context.Cause(subTask2.Context()))
}
func TestTimeoutOnGlobalContextWait(t *testing.T) {
defer CancelGlobalContext()
rootTask := GlobalTask("root-task")
subTask := rootTask.Subtask("subtask")
done := make(chan struct{})
go func() {
GlobalContextWait(500 * time.Millisecond)
close(done)
}()
select {
case <-done:
t.Fatal("GlobalContextWait should have timed out")
case <-time.After(200 * time.Millisecond):
}
// Ensure clean exit
subTask.Finish("exit")
}
func TestGlobalContextCancel(t *testing.T) {
}