77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
package common
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestJitterTTLRange(t *testing.T) {
|
|
base := 10 * time.Minute
|
|
minTTL := base - base/10
|
|
maxTTL := base + base/10
|
|
for range 1000 {
|
|
got := jitterTTL(base)
|
|
if got < minTTL || got > maxTTL {
|
|
t.Fatalf("jitterTTL(%v) = %v, want range [%v, %v]", base, got, minTTL, maxTTL)
|
|
}
|
|
}
|
|
if got := jitterTTL(0); got != 0 {
|
|
t.Fatalf("jitterTTL(0) = %v, want 0", got)
|
|
}
|
|
}
|
|
|
|
// TestUnmarshalCopyIndependent 副本必须与 target 完全独立:改写副本不得波及 target,
|
|
// 反之亦然(GetJSON L2 回填后调用方改写 target 不得产生缓存别名竞争)。
|
|
func TestUnmarshalCopyIndependent(t *testing.T) {
|
|
type seg struct {
|
|
Name string `json:"name"`
|
|
Mult float64 `json:"mult"`
|
|
}
|
|
type payload struct {
|
|
TimeMultiplier float64 `json:"time_multiplier"`
|
|
TimeRule string `json:"time_rule"`
|
|
Segs []seg `json:"segs"`
|
|
}
|
|
|
|
target := payload{}
|
|
jsonStr := `{"time_multiplier":1.5,"time_rule":"忙时","segs":[{"name":"a","mult":2}]}`
|
|
if err := json.Unmarshal([]byte(jsonStr), &target); err != nil {
|
|
t.Fatalf("unmarshal target: %v", err)
|
|
}
|
|
|
|
cpAny, err := unmarshalCopy(jsonStr, &target)
|
|
if err != nil {
|
|
t.Fatalf("unmarshalCopy: %v", err)
|
|
}
|
|
cp, ok := cpAny.(*payload)
|
|
if !ok {
|
|
t.Fatalf("unmarshalCopy 返回类型 %T, want *payload", cpAny)
|
|
}
|
|
|
|
// 初始值一致
|
|
if cp.TimeRule != target.TimeRule || cp.TimeMultiplier != target.TimeMultiplier || len(cp.Segs) != len(target.Segs) {
|
|
t.Fatalf("副本初始值与 target 不一致: %+v vs %+v", cp, &target)
|
|
}
|
|
|
|
// 改写副本不波及 target
|
|
cp.TimeMultiplier = 0.5
|
|
cp.TimeRule = "闲时"
|
|
if target.TimeMultiplier != 1.5 || target.TimeRule != "忙时" {
|
|
t.Fatalf("改写副本波及了 target: %+v", &target)
|
|
}
|
|
|
|
// 改写 target 不波及副本
|
|
target.TimeMultiplier = 9.9
|
|
if cp.TimeMultiplier != 0.5 {
|
|
t.Fatalf("改写 target 波及了副本: %+v", cp)
|
|
}
|
|
}
|
|
|
|
// TestUnmarshalCopyRejectsNonPointer 非 pointer target 必须报错而非 panic。
|
|
func TestUnmarshalCopyRejectsNonPointer(t *testing.T) {
|
|
if _, err := unmarshalCopy(`{}`, map[string]any{}); err == nil {
|
|
t.Fatal("non-pointer target 应返回错误")
|
|
}
|
|
}
|