Download internal/upstream/cache_key_test.go from a3216/gcli2api: direct link, hf CLI and curl.
- Browser
- Download file 5.54 kB
-
https://huggingface.co/spaces/a3216/gcli2api/resolve/main/internal/upstream/cache_key_test.go
- Command line
-
hf download hf://spaces/a3216/gcli2api/internal/upstream/cache_key_test.go
-
curl -L -o cache_key_test.go https://huggingface.co/spaces/a3216/gcli2api/resolve/main/internal/upstream/cache_key_test.go
5.54 kB
| package upstream | |
| import ( | |
| "encoding/json" | |
| "strings" | |
| "testing" | |
| ) | |
| // extractCacheKey 从改写后的 body 里取出 prompt_cache_key 字段值。 | |
| func extractCacheKey(t *testing.T, body []byte) string { | |
| t.Helper() | |
| var obj map[string]any | |
| if err := json.Unmarshal(body, &obj); err != nil { | |
| t.Fatalf("unmarshal body: %v", err) | |
| } | |
| v, _ := obj["prompt_cache_key"].(string) | |
| return v | |
| } | |
| // TestInjectPromptCacheKey_PreservesExisting 覆盖任务用例 1: | |
| // 入站 body 已带 prompt_cache_key → 原值保留,不被网关覆盖。 | |
| func TestInjectPromptCacheKey_PreservesExisting(t *testing.T) { | |
| // Arrange | |
| uid := "user-abc-123" | |
| conv := "conv-xyz" | |
| in := `{"model":"glm-5.2","messages":[],"prompt_cache_key":"client-set-key"}` | |
| // Act | |
| out := InjectPromptCacheKey([]byte(in), uid, conv) | |
| // Assert | |
| if got := extractCacheKey(t, out); got != "client-set-key" { | |
| t.Fatalf("existing prompt_cache_key overwritten: got=%q want client-set-key", got) | |
| } | |
| } | |
| // TestInjectPromptCacheKey_UsesConversationID 覆盖任务用例 2: | |
| // body 无 prompt_cache_key 但有 conversation_id → 用它做会话哈希源。 | |
| // 格式 wb2a-<uid8>-<conversationHash>:conversation_id 不逐字出现,而是驱动哈希段 | |
| // (同 id 同 key、不同 id 不同 key)。同时仍带 uid8 隔离前缀。 | |
| func TestInjectPromptCacheKey_UsesConversationID(t *testing.T) { | |
| uid := "user-abc-123" | |
| in := `{"model":"glm-5.2","messages":[],"conversation_id":"conv-42"}` | |
| out := InjectPromptCacheKey([]byte(in), uid, "") | |
| got := extractCacheKey(t, out) | |
| if !strings.HasPrefix(got, "wb2a-") { | |
| t.Fatalf("expected wb2a- prefix, got=%q", got) | |
| } | |
| if !strings.Contains(got, "user-abc") { | |
| t.Fatalf("expected uid8 isolation prefix, got=%q", got) | |
| } | |
| // 同 conversation_id 两次出站 → 同 key(稳定)。 | |
| out2 := InjectPromptCacheKey([]byte(in), uid, "") | |
| if got2 := extractCacheKey(t, out2); got2 != got { | |
| t.Fatalf("non-deterministic key for same conversation_id: %q vs %q", got, got2) | |
| } | |
| // 不同 conversation_id → 不同 key(哈希段区分)。 | |
| inB := `{"model":"glm-5.2","messages":[],"conversation_id":"conv-99"}` | |
| gotB := extractCacheKey(t, InjectPromptCacheKey([]byte(inB), uid, "")) | |
| if gotB == got { | |
| t.Fatalf("different conversation_id produced same key: %q", got) | |
| } | |
| } | |
| // TestInjectPromptCacheKey_GeneratesStableKey 覆盖任务用例 3: | |
| // body 两者都无 → 网关生成稳定键,两次同输入同账号得到同 key。 | |
| func TestInjectPromptCacheKey_GeneratesStableKey(t *testing.T) { | |
| uid := "user-abc-123" | |
| conv := "conv-stable" | |
| in := `{"model":"glm-5.2","messages":[]}` | |
| a := InjectPromptCacheKey([]byte(in), uid, conv) | |
| b := InjectPromptCacheKey([]byte(in), uid, conv) | |
| ka, kb := extractCacheKey(t, a), extractCacheKey(t, b) | |
| if ka != kb { | |
| t.Fatalf("non-deterministic key for same input+uid: a=%q b=%q", ka, kb) | |
| } | |
| } | |
| // TestInjectPromptCacheKey_AccountIsolation 覆盖任务用例 4: | |
| // 不同账号 → key 不同(隔离验证)。 | |
| func TestInjectPromptCacheKey_AccountIsolation(t *testing.T) { | |
| conv := "conv-shared" | |
| in := `{"model":"glm-5.2","messages":[]}` | |
| ka := extractCacheKey(t, InjectPromptCacheKey([]byte(in), "user-aaa-111", conv)) | |
| kb := extractCacheKey(t, InjectPromptCacheKey([]byte(in), "user-bbb-222", conv)) | |
| if ka == kb { | |
| t.Fatalf("cross-account key collision: both=%q", ka) | |
| } | |
| if !strings.HasPrefix(ka, "wb2a-") || !strings.HasPrefix(kb, "wb2a-") { | |
| t.Fatalf("keys must carry wb2a- prefix: a=%q b=%q", ka, kb) | |
| } | |
| } | |
| // TestInjectPromptCacheKey_Format 覆盖任务用例 5: | |
| // cache key 格式校验(含 uid8 前缀)。 | |
| func TestInjectPromptCacheKey_Format(t *testing.T) { | |
| uid := "1234567890abcdef" | |
| in := `{"model":"glm-5.2","messages":[]}` | |
| out := InjectPromptCacheKey([]byte(in), uid, "conv-fmt") | |
| got := extractCacheKey(t, out) | |
| if !strings.HasPrefix(got, "wb2a-") { | |
| t.Fatalf("expected wb2a- prefix, got=%q", got) | |
| } | |
| if !strings.Contains(got, "12345678") { | |
| t.Fatalf("expected uid8 (12345678) in key, got=%q", got) | |
| } | |
| } | |
| // TestInjectPromptCacheKey_EmptyConversation 覆盖任务用例 3 边界: | |
| // 无 conversation_id 且无会话标识 → 生成键含 uid8 但 conversationHash 段为定值(不复用前缀)。 | |
| // 不应报错、不应空串(key 非空)。 | |
| func TestInjectPromptCacheKey_EmptyConversation(t *testing.T) { | |
| uid := "user-abc-123" | |
| in := `{"model":"glm-5.2","messages":[]}` | |
| out := InjectPromptCacheKey([]byte(in), uid, "") | |
| got := extractCacheKey(t, out) | |
| if got == "" { | |
| t.Fatalf("expected non-empty key when no conversation, got empty") | |
| } | |
| if !strings.HasPrefix(got, "wb2a-") { | |
| t.Fatalf("expected wb2a- prefix, got=%q", got) | |
| } | |
| if !strings.Contains(got, "user-abc") { | |
| t.Fatalf("expected uid8 in key, got=%q", got) | |
| } | |
| } | |
| // TestPrepareBodyOptNoCacheKeyInjection 覆盖任务用例 6: | |
| // PrepareBodyOpt(sanitize=false 的旧入口)行为不变——不注入 cache key。 | |
| // 向后兼容:仅传 body 不给 cacheKey 上下文时,不得引入新字段。 | |
| func TestPrepareBodyOptNoCacheKeyInjection(t *testing.T) { | |
| in := `{"model":"glm-5.2","messages":[]}` | |
| out := PrepareBodyOpt([]byte(in), false) | |
| var obj map[string]any | |
| if err := json.Unmarshal(out, &obj); err != nil { | |
| t.Fatalf("unmarshal: %v", err) | |
| } | |
| if _, present := obj["prompt_cache_key"]; present { | |
| t.Fatalf("PrepareBodyOpt must NOT inject prompt_cache_key, but got: %v", obj["prompt_cache_key"]) | |
| } | |
| } | |