mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-09-27 09:52:06 +08:00

- Refactor frame converter implementation - Update mp4 track to use ICodex - General refactoring and code improvements 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
224 lines
4.2 KiB
Go
224 lines
4.2 KiB
Go
package task
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"log/slog"
|
|
"os"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
var root Work
|
|
|
|
func init() {
|
|
root.Context, root.CancelCauseFunc = context.WithCancelCause(context.Background())
|
|
root.handler = &root
|
|
root.Logger = slog.New(slog.NewTextHandler(os.Stdout, nil))
|
|
slog.SetLogLoggerLevel(slog.LevelDebug)
|
|
}
|
|
|
|
func Test_AddTask_AddsTaskSuccessfully(t *testing.T) {
|
|
var task Task
|
|
root.AddTask(&task)
|
|
_ = task.WaitStarted()
|
|
root.RangeSubTask(func(t ITask) bool {
|
|
if t.GetTaskID() == task.GetTaskID() {
|
|
return false
|
|
}
|
|
return true
|
|
})
|
|
}
|
|
|
|
type retryDemoTask struct {
|
|
Task
|
|
}
|
|
|
|
func (task *retryDemoTask) Start() error {
|
|
return io.ErrClosedPipe
|
|
}
|
|
|
|
func Test_RetryTask(t *testing.T) {
|
|
var demoTask retryDemoTask
|
|
var parent Job
|
|
root.AddTask(&parent)
|
|
demoTask.SetRetry(3, time.Second)
|
|
parent.AddTask(&demoTask)
|
|
_ = parent.WaitStopped()
|
|
if demoTask.retry.RetryCount != 3 {
|
|
t.Errorf("expected 3 retries, got %d", demoTask.retry.RetryCount)
|
|
}
|
|
}
|
|
|
|
func Test_Call_ExecutesCallback(t *testing.T) {
|
|
called := false
|
|
root.Call(func() {
|
|
called = true
|
|
return
|
|
})
|
|
if !called {
|
|
t.Errorf("expected callback to be called")
|
|
}
|
|
}
|
|
|
|
func Test_StopByContext(t *testing.T) {
|
|
var task Task
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
root.AddTask(&task, ctx)
|
|
time.AfterFunc(time.Millisecond*100, cancel)
|
|
if !errors.Is(task.WaitStopped(), context.Canceled) {
|
|
t.Errorf("expected task to be stopped by context")
|
|
}
|
|
}
|
|
|
|
func Test_ParentStop(t *testing.T) {
|
|
var parent Job
|
|
root.AddTask(&parent)
|
|
var called atomic.Uint32
|
|
var task Task
|
|
checkCalled := func(expected uint32) {
|
|
if count := called.Add(1); count != expected {
|
|
t.Errorf("expected %d, got %d", expected, count)
|
|
}
|
|
}
|
|
task.OnDispose(func() {
|
|
checkCalled(1)
|
|
})
|
|
parent.OnDispose(func() {
|
|
checkCalled(2)
|
|
})
|
|
parent.AddTask(&task)
|
|
parent.Stop(ErrAutoStop)
|
|
if !errors.Is(task.WaitStopped(), ErrAutoStop) {
|
|
t.Errorf("expected task auto stop")
|
|
}
|
|
}
|
|
|
|
func Test_ParentAutoStop(t *testing.T) {
|
|
var parent Job
|
|
root.AddTask(&parent)
|
|
var called atomic.Uint32
|
|
var task Task
|
|
checkCalled := func(expected uint32) {
|
|
if count := called.Add(1); count != expected {
|
|
t.Errorf("expected %d, got %d", expected, count)
|
|
}
|
|
}
|
|
task.OnDispose(func() {
|
|
checkCalled(1)
|
|
})
|
|
parent.OnDispose(func() {
|
|
checkCalled(2)
|
|
})
|
|
parent.AddTask(&task)
|
|
time.AfterFunc(time.Second, func() {
|
|
task.Stop(ErrTaskComplete)
|
|
})
|
|
if !errors.Is(parent.WaitStopped(), ErrAutoStop) {
|
|
t.Errorf("expected task auto stop")
|
|
}
|
|
}
|
|
|
|
func Test_Hooks(t *testing.T) {
|
|
var called atomic.Uint32
|
|
var task Task
|
|
checkCalled := func(expected uint32) {
|
|
if count := called.Add(1); count != expected {
|
|
t.Errorf("expected %d, got %d", expected, count)
|
|
}
|
|
}
|
|
task.OnStart(func() {
|
|
checkCalled(1)
|
|
})
|
|
task.OnDispose(func() {
|
|
checkCalled(3)
|
|
})
|
|
task.OnStart(func() {
|
|
checkCalled(2)
|
|
})
|
|
task.OnDispose(func() {
|
|
checkCalled(4)
|
|
})
|
|
task.Stop(ErrTaskComplete)
|
|
root.AddTask(&task).WaitStopped()
|
|
}
|
|
|
|
type startFailTask struct {
|
|
Task
|
|
}
|
|
|
|
func (task *startFailTask) Start() error {
|
|
return errors.New("start failed")
|
|
}
|
|
|
|
func (task *startFailTask) Dispose() {
|
|
task.Logger.Info("Dispose")
|
|
}
|
|
|
|
func Test_StartFail(t *testing.T) {
|
|
var task startFailTask
|
|
root.AddTask(&task)
|
|
if err := task.WaitStarted(); err == nil {
|
|
t.Errorf("expected start to fail")
|
|
}
|
|
}
|
|
|
|
func Test_Block(t *testing.T) {
|
|
var task Task
|
|
block := make(chan struct{})
|
|
var job Job
|
|
task.OnStart(func() {
|
|
task.OnStop(func() {
|
|
close(block)
|
|
})
|
|
<-block
|
|
})
|
|
time.AfterFunc(time.Second*2, func() {
|
|
job.Stop(ErrTaskComplete)
|
|
})
|
|
root.AddTask(&job)
|
|
job.AddTask(&task)
|
|
job.WaitStopped()
|
|
}
|
|
|
|
//
|
|
//type DemoTask struct {
|
|
// Task
|
|
// file *os.File
|
|
// filePath string
|
|
//}
|
|
//
|
|
//func (d *DemoTask) Start() (err error) {
|
|
// d.file, err = os.Open(d.filePath)
|
|
// return
|
|
//}
|
|
//
|
|
//func (d *DemoTask) Run() (err error) {
|
|
// _, err = d.file.Write([]byte("hello"))
|
|
// return
|
|
//}
|
|
//
|
|
//func (d *DemoTask) Dispose() {
|
|
// d.file.Close()
|
|
//}
|
|
//
|
|
//type HelloWorld struct {
|
|
// DemoTask
|
|
//}
|
|
//
|
|
//func (h *HelloWorld) Run() (err error) {
|
|
// _, err = h.file.Write([]byte("world"))
|
|
// return nil
|
|
//}
|
|
|
|
//type HelloWorld struct {
|
|
// Task
|
|
//}
|
|
//
|
|
//func (h *HelloWorld) Start() (err error) {
|
|
// fmt.Println("Hello World")
|
|
// return nil
|
|
//}
|