// steamcache/steamcache_test.go package steamcache import ( "io" "os" "path/filepath" "strings" "testing" ) func TestCaching(t *testing.T) { td := t.TempDir() os.WriteFile(filepath.Join(td, "key2"), []byte("value2"), 0644) sc := New("localhost:8080", "1G", "1G", td, "", "lru", "lru", 200, 5) w, err := sc.vfs.Create("key", 5) if err != nil { t.Errorf("Create failed: %v", err) } w.Write([]byte("value")) w.Close() w, err = sc.vfs.Create("key1", 6) if err != nil { t.Errorf("Create failed: %v", err) } w.Write([]byte("value1")) w.Close() if sc.diskgc.Size() != 17 { t.Errorf("Size failed: got %d, want %d", sc.diskgc.Size(), 17) } if sc.vfs.Size() != 17 { t.Errorf("Size failed: got %d, want %d", sc.vfs.Size(), 17) } rc, err := sc.vfs.Open("key") if err != nil { t.Errorf("Open failed: %v", err) } d, _ := io.ReadAll(rc) rc.Close() if string(d) != "value" { t.Errorf("Get failed: got %s, want %s", d, "value") } rc, err = sc.vfs.Open("key1") if err != nil { t.Errorf("Open failed: %v", err) } d, _ = io.ReadAll(rc) rc.Close() if string(d) != "value1" { t.Errorf("Get failed: got %s, want %s", d, "value1") } rc, err = sc.vfs.Open("key2") if err != nil { t.Errorf("Open failed: %v", err) } d, _ = io.ReadAll(rc) rc.Close() if string(d) != "value2" { t.Errorf("Get failed: got %s, want %s", d, "value2") } if sc.diskgc.Size() != 17 { t.Errorf("Size failed: got %d, want %d", sc.diskgc.Size(), 17) } if sc.vfs.Size() != 17 { t.Errorf("Size failed: got %d, want %d", sc.vfs.Size(), 17) } sc.memory.Delete("key2") os.Remove(filepath.Join(td, "key2")) if _, err := sc.vfs.Open("key2"); err == nil { t.Errorf("Open failed: got nil, want error") } } func TestCacheMissAndHit(t *testing.T) { sc := New("localhost:8080", "0", "1G", t.TempDir(), "", "lru", "lru", 200, 5) key := "testkey" value := []byte("testvalue") // Simulate miss: but since no upstream, skip full ServeHTTP, test VFS w, err := sc.vfs.Create(key, int64(len(value))) if err != nil { t.Fatal(err) } w.Write(value) w.Close() rc, err := sc.vfs.Open(key) if err != nil { t.Fatal(err) } got, _ := io.ReadAll(rc) rc.Close() if string(got) != string(value) { t.Errorf("expected %s, got %s", value, got) } } func TestURLHashing(t *testing.T) { // Test the new SHA256-based cache key generation testCases := []struct { input string desc string shouldCache bool }{ { input: "/depot/1684171/chunk/abcdef1234567890", desc: "chunk file URL", shouldCache: true, }, { input: "/depot/1684171/manifest/944076726177422892/5/abcdef1234567890", desc: "manifest file URL", shouldCache: true, }, { input: "/depot/invalid/path", desc: "invalid depot URL format", shouldCache: true, // Still gets hashed, just not a proper Steam format }, { input: "/some/other/path", desc: "non-Steam URL", shouldCache: false, // Not cached }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { result := generateSteamCacheKey(tc.input) if tc.shouldCache { // Should return a cache key with "steam/" prefix if !strings.HasPrefix(result, "steam/") { t.Errorf("generateSteamCacheKey(%s) = %s, expected steam/ prefix", tc.input, result) } // Should be exactly 70 characters (6 for "steam/" + 64 for SHA256 hex) if len(result) != 70 { t.Errorf("generateSteamCacheKey(%s) length = %d, expected 70", tc.input, len(result)) } } else { // Should return empty string for non-Steam URLs if result != "" { t.Errorf("generateSteamCacheKey(%s) = %s, expected empty string", tc.input, result) } } }) } } // Removed hash calculation tests since we switched to lightweight validation func TestSteamKeySharding(t *testing.T) { sc := New("localhost:8080", "0", "1G", t.TempDir(), "", "lru", "lru", 200, 5) // Test with a Steam-style key that should trigger sharding steamKey := "steam/0016cfc5019b8baa6026aa1cce93e685d6e06c6e" testData := []byte("test steam cache data") // Create a file with the steam key w, err := sc.vfs.Create(steamKey, int64(len(testData))) if err != nil { t.Fatalf("Failed to create file with steam key: %v", err) } w.Write(testData) w.Close() // Verify we can read it back rc, err := sc.vfs.Open(steamKey) if err != nil { t.Fatalf("Failed to open file with steam key: %v", err) } got, _ := io.ReadAll(rc) rc.Close() if string(got) != string(testData) { t.Errorf("Data mismatch: expected %s, got %s", testData, got) } // Verify that the file was created (sharding is working if no error occurred) // The key difference is that with sharding, the file should be created successfully // and be readable, whereas without sharding it might not work correctly } // Removed old TestKeyGeneration - replaced with TestURLHashing that uses SHA256