mirror of
https://github.com/truewhile/MeBox.git
synced 2026-11-12 19:34:24 +08:00
102 lines
3.7 KiB
Go
102 lines
3.7 KiB
Go
package cloud115
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestDownloadURLCache(t *testing.T) {
|
|
urlCacheMu.Lock()
|
|
urlCache = map[string]urlCacheEntry{}
|
|
urlCacheMu.Unlock()
|
|
|
|
if got := GetDownloadURLCache("pick1"); got != "" {
|
|
t.Fatalf("empty cache should return empty, got %q", got)
|
|
}
|
|
SetDownloadURLCache("pick1", "http://cdn/1")
|
|
if got := GetDownloadURLCache("pick1"); got != "http://cdn/1" {
|
|
t.Fatalf("cache miss, got %q", got)
|
|
}
|
|
// 过期条目按未命中处理
|
|
urlCacheMu.Lock()
|
|
urlCache["pick1"] = urlCacheEntry{url: "http://cdn/old", expiresAt: time.Now().Add(-time.Second)}
|
|
urlCacheMu.Unlock()
|
|
if got := GetDownloadURLCache("pick1"); got != "" {
|
|
t.Fatalf("expired entry should be a miss, got %q", got)
|
|
}
|
|
ClearDownloadURLCache("pick1")
|
|
if got := GetDownloadURLCache("pick1"); got != "" {
|
|
t.Fatalf("cleared entry should be a miss, got %q", got)
|
|
}
|
|
}
|
|
|
|
// 115 直链自带 `t=` 过期时间戳(实测为换取时刻 + 1800 秒)。缓存必须跟随它,
|
|
// 否则会出现「服务端认为还有效、CDN 已经 403」的窗口:直链被缓存到 45 分钟,
|
|
// 但第 30 分钟起客户端就必然拿到 403。
|
|
func TestDownloadURLCacheExpiryFollowsLinkTimestamp(t *testing.T) {
|
|
now := time.Now()
|
|
link := fmt.Sprintf("https://cdn/1/a.mkv?t=%d&u=1&k=abc", now.Add(30*time.Minute).Unix())
|
|
|
|
got := cacheExpiry(link, now)
|
|
want := now.Add(30*time.Minute - linkExpirySafety)
|
|
if diff := got.Sub(want); diff > time.Second || diff < -time.Second {
|
|
t.Fatalf("cacheExpiry = %v, want %v", got, want)
|
|
}
|
|
|
|
// 解析不出 t= 时退回兜底 TTL,保持旧行为。
|
|
fallback := cacheExpiry("https://cdn/1/a.mkv", now)
|
|
if diff := fallback.Sub(now.Add(downloadURLCacheMaxTTL)); diff > time.Second || diff < -time.Second {
|
|
t.Fatalf("fallback cacheExpiry = %v, want %v", fallback, now.Add(downloadURLCacheMaxTTL))
|
|
}
|
|
|
|
// 直链本身已经过期(或只剩不足提前量的寿命)时不进缓存。
|
|
if got := cacheExpiry(fmt.Sprintf("https://cdn/1/a.mkv?t=%d", now.Add(-time.Minute).Unix()), now); !got.IsZero() {
|
|
t.Fatalf("expired link must not be cached, got expiry %v", got)
|
|
}
|
|
if got := cacheExpiry(fmt.Sprintf("https://cdn/1/a.mkv?t=%d", now.Add(time.Minute).Unix()), now); !got.IsZero() {
|
|
t.Fatalf("link expiring inside the safety margin must not be cached, got %v", got)
|
|
}
|
|
}
|
|
|
|
// 客户端上报「直链被 CDN 拒绝」时按 pickcode 清缓存,但要挡住刚写入的条目,
|
|
// 避免重试风暴把 115 换链接口打出突发。
|
|
func TestClearDownloadURLCacheIfOlderThan(t *testing.T) {
|
|
urlCacheMu.Lock()
|
|
urlCache = map[string]urlCacheEntry{}
|
|
urlCacheMu.Unlock()
|
|
t.Cleanup(func() {
|
|
urlCacheMu.Lock()
|
|
urlCache = map[string]urlCacheEntry{}
|
|
urlCacheMu.Unlock()
|
|
})
|
|
|
|
future := time.Now().Add(30 * time.Minute)
|
|
link := fmt.Sprintf("https://cdn/1/a.mkv?t=%d", future.Unix())
|
|
SetDownloadURLCache("pick-fresh", link, "ua-a")
|
|
if ClearDownloadURLCacheIfOlderThan("pick-fresh", time.Minute) {
|
|
t.Fatal("fresh entry must survive the min-age guard")
|
|
}
|
|
if got := GetDownloadURLCache("pick-fresh", "ua-a"); got != link {
|
|
t.Fatalf("fresh entry lost, got %q", got)
|
|
}
|
|
|
|
SetDownloadURLCache("pick-old", link, "ua-a")
|
|
urlCacheMu.Lock()
|
|
entry := urlCache[urlCacheKey("pick-old", "ua-a")]
|
|
entry.createdAt = time.Now().Add(-10 * time.Minute)
|
|
urlCache[urlCacheKey("pick-old", "ua-a")] = entry
|
|
urlCacheMu.Unlock()
|
|
|
|
if !ClearDownloadURLCacheIfOlderThan("pick-old", time.Minute) {
|
|
t.Fatal("stale entry should be cleared")
|
|
}
|
|
if got := GetDownloadURLCache("pick-old", "ua-a"); got != "" {
|
|
t.Fatalf("stale entry should be gone, got %q", got)
|
|
}
|
|
// 无关 pickcode 不受影响。
|
|
if got := GetDownloadURLCache("pick-fresh", "ua-a"); got != link {
|
|
t.Fatalf("unrelated pickcode lost, got %q", got)
|
|
}
|
|
}
|