mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-08-26 21:02:28 +02:00
121 lines
2.8 KiB
Go
121 lines
2.8 KiB
Go
package gobackend
|
|
|
|
import (
|
|
"sync"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func resetCoverCache() {
|
|
coverMu.Lock()
|
|
coverCache = map[string]*coverCacheEntry{}
|
|
coverInflight = map[string]*coverInflightCall{}
|
|
coverCacheBytes = 0
|
|
coverMu.Unlock()
|
|
}
|
|
|
|
func TestFetchCoverCachedSingleflight(t *testing.T) {
|
|
orig := coverFetch
|
|
defer func() { coverFetch = orig }()
|
|
resetCoverCache()
|
|
|
|
var calls int32
|
|
entered := make(chan struct{})
|
|
release := make(chan struct{})
|
|
coverFetch = func(string) ([]byte, error) {
|
|
if atomic.AddInt32(&calls, 1) == 1 {
|
|
close(entered)
|
|
}
|
|
<-release
|
|
return []byte("coverbytes"), nil
|
|
}
|
|
|
|
const url = "https://cdn.example/cover_max.jpg"
|
|
var wg sync.WaitGroup
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
if _, err := fetchCoverCached(url); err != nil {
|
|
t.Errorf("leader fetch error: %v", err)
|
|
}
|
|
}()
|
|
|
|
<-entered // leader has registered inflight and is blocked in coverFetch
|
|
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
if _, err := fetchCoverCached(url); err != nil {
|
|
t.Errorf("follower fetch error: %v", err)
|
|
}
|
|
}()
|
|
|
|
close(release)
|
|
wg.Wait()
|
|
|
|
if got := atomic.LoadInt32(&calls); got != 1 {
|
|
t.Fatalf("expected 1 fetch for concurrent requests, got %d", got)
|
|
}
|
|
}
|
|
|
|
func TestFetchCoverCachedTTLExpiry(t *testing.T) {
|
|
orig := coverFetch
|
|
defer func() { coverFetch = orig }()
|
|
resetCoverCache()
|
|
|
|
var calls int32
|
|
coverFetch = func(string) ([]byte, error) {
|
|
atomic.AddInt32(&calls, 1)
|
|
return []byte("data"), nil
|
|
}
|
|
|
|
const url = "https://cdn.example/ttl.jpg"
|
|
if _, err := fetchCoverCached(url); err != nil {
|
|
t.Fatalf("first fetch error: %v", err)
|
|
}
|
|
// second call served from cache
|
|
if _, err := fetchCoverCached(url); err != nil {
|
|
t.Fatalf("second fetch error: %v", err)
|
|
}
|
|
if got := atomic.LoadInt32(&calls); got != 1 {
|
|
t.Fatalf("expected cache hit, got %d fetches", got)
|
|
}
|
|
|
|
// expire the entry and confirm a refetch
|
|
coverMu.Lock()
|
|
coverCache[url].expiresAt = time.Now().Add(-time.Minute)
|
|
coverMu.Unlock()
|
|
|
|
if _, err := fetchCoverCached(url); err != nil {
|
|
t.Fatalf("third fetch error: %v", err)
|
|
}
|
|
if got := atomic.LoadInt32(&calls); got != 2 {
|
|
t.Fatalf("expected refetch after TTL expiry, got %d fetches", got)
|
|
}
|
|
}
|
|
|
|
func TestDownloadCoverUsesProviderURLUnchanged(t *testing.T) {
|
|
orig := coverFetch
|
|
defer func() { coverFetch = orig }()
|
|
resetCoverCache()
|
|
|
|
const providerURL = "https://i.scdn.co/image/ab67616d00001e02example"
|
|
var requestedURL string
|
|
coverFetch = func(url string) ([]byte, error) {
|
|
requestedURL = url
|
|
return []byte("provider-cover"), nil
|
|
}
|
|
|
|
got, err := downloadCoverToMemory(providerURL)
|
|
if err != nil {
|
|
t.Fatalf("download provider cover: %v", err)
|
|
}
|
|
if requestedURL != providerURL {
|
|
t.Fatalf("requested URL = %q, want provider URL %q", requestedURL, providerURL)
|
|
}
|
|
if string(got) != "provider-cover" {
|
|
t.Fatalf("downloaded cover = %q", got)
|
|
}
|
|
}
|