mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-09-28 07:36:38 +08:00
122 lines
3.0 KiB
Go
122 lines
3.0 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"path/filepath"
|
|
"sync"
|
|
"testing"
|
|
)
|
|
|
|
func TestGlobalReturnsDetachedSnapshot(t *testing.T) {
|
|
original := Global()
|
|
t.Cleanup(func() { Set(original) })
|
|
|
|
Set(&Config{Services: []*ServiceConfig{{
|
|
Name: "snapshot-service",
|
|
Metadata: map[string]any{"paused": false},
|
|
Handler: &HandlerConfig{
|
|
Type: "relay",
|
|
Metadata: map[string]any{"retries": 2},
|
|
},
|
|
}}})
|
|
|
|
snapshot := Global()
|
|
snapshot.Services[0].Name = "changed"
|
|
snapshot.Services[0].Metadata["paused"] = true
|
|
snapshot.Services[0].Handler.Metadata["retries"] = 9
|
|
|
|
current := Global()
|
|
if current.Services[0].Name != "snapshot-service" {
|
|
t.Fatalf("snapshot mutated global service name: %q", current.Services[0].Name)
|
|
}
|
|
if paused, _ := current.Services[0].Metadata["paused"].(bool); paused {
|
|
t.Fatalf("snapshot mutated global service metadata")
|
|
}
|
|
if retries, _ := current.Services[0].Handler.Metadata["retries"].(int); retries != 2 {
|
|
t.Fatalf("snapshot mutated nested handler metadata: %v", current.Services[0].Handler.Metadata["retries"])
|
|
}
|
|
}
|
|
|
|
func TestConcurrentGlobalSnapshotAndUpdate(t *testing.T) {
|
|
original := Global()
|
|
t.Cleanup(func() { Set(original) })
|
|
|
|
Set(&Config{Services: []*ServiceConfig{{
|
|
Name: "concurrent-service",
|
|
Metadata: map[string]any{"generation": 0},
|
|
}}})
|
|
|
|
var wg sync.WaitGroup
|
|
for worker := 0; worker < 4; worker++ {
|
|
wg.Add(1)
|
|
go func(worker int) {
|
|
defer wg.Done()
|
|
for i := 0; i < 500; i++ {
|
|
if err := OnUpdate(func(c *Config) error {
|
|
c.Services[0] = &ServiceConfig{
|
|
Name: "concurrent-service",
|
|
Metadata: map[string]any{"generation": worker*500 + i},
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
t.Errorf("OnUpdate: %v", err)
|
|
return
|
|
}
|
|
}
|
|
}(worker)
|
|
}
|
|
|
|
for i := 0; i < 2000; i++ {
|
|
if _, err := json.Marshal(Global()); err != nil {
|
|
t.Fatalf("marshal snapshot: %v", err)
|
|
}
|
|
}
|
|
wg.Wait()
|
|
}
|
|
|
|
func TestConcurrentPersistProducesValidConfig(t *testing.T) {
|
|
original := Global()
|
|
originalPath := PersistPath()
|
|
persistMu.Lock()
|
|
originalEnabled := persistEnable
|
|
persistMu.Unlock()
|
|
t.Cleanup(func() {
|
|
Set(original)
|
|
SetPersistPath(originalPath)
|
|
persistMu.Lock()
|
|
persistEnable = originalEnabled
|
|
persistMu.Unlock()
|
|
})
|
|
|
|
path := filepath.Join(t.TempDir(), "gost.json")
|
|
SetPersistPath(path)
|
|
EnablePersist()
|
|
Set(&Config{Services: []*ServiceConfig{{Name: "persist-service"}}})
|
|
|
|
var wg sync.WaitGroup
|
|
for worker := 0; worker < 4; worker++ {
|
|
wg.Add(1)
|
|
go func(worker int) {
|
|
defer wg.Done()
|
|
for i := 0; i < 50; i++ {
|
|
if err := OnUpdate(func(c *Config) error {
|
|
c.Services[0].Metadata = map[string]any{"generation": worker*50 + i}
|
|
return nil
|
|
}); err != nil {
|
|
t.Errorf("persist update: %v", err)
|
|
return
|
|
}
|
|
}
|
|
}(worker)
|
|
}
|
|
wg.Wait()
|
|
|
|
var persisted Config
|
|
if err := persisted.ReadFile(path); err != nil {
|
|
t.Fatalf("read persisted config: %v", err)
|
|
}
|
|
if len(persisted.Services) != 1 || persisted.Services[0] == nil || persisted.Services[0].Name != "persist-service" {
|
|
t.Fatalf("unexpected persisted services: %#v", persisted.Services)
|
|
}
|
|
}
|