| package semanticcache |
|
|
| import ( |
| "testing" |
| "time" |
|
|
| "github.com/maximhq/bifrost/core/schemas" |
| ) |
|
|
| |
| func TestEmbeddingRequestsCaching(t *testing.T) { |
| setup := NewTestSetup(t) |
| defer setup.Cleanup() |
|
|
| ctx := CreateContextWithCacheKey("test-embedding-cache") |
|
|
| |
| embeddingRequest := CreateEmbeddingRequest([]string{ |
| "What is machine learning?", |
| "Explain artificial intelligence in simple terms.", |
| }) |
|
|
| t.Log("Making first embedding request (should go to OpenAI and be cached)...") |
|
|
| |
| start1 := time.Now() |
| response1, err1 := setup.Client.EmbeddingRequest(ctx, embeddingRequest) |
| duration1 := time.Since(start1) |
|
|
| if err1 != nil { |
| return |
| } |
|
|
| if response1 == nil || len(response1.Data) == 0 { |
| t.Fatal("First embedding response is invalid") |
| } |
|
|
| t.Logf("First embedding request completed in %v", duration1) |
| t.Logf("Response contains %d embeddings", len(response1.Data)) |
|
|
| |
| WaitForCache(setup.Plugin) |
|
|
| t.Log("Making second identical embedding request (should be served from cache)...") |
|
|
| |
| start2 := time.Now() |
| response2, err2 := setup.Client.EmbeddingRequest(ctx, embeddingRequest) |
| duration2 := time.Since(start2) |
|
|
| if err2 != nil { |
| t.Fatalf("Second embedding request failed: %v", err2) |
| } |
|
|
| if response2 == nil || len(response2.Data) == 0 { |
| t.Fatal("Second embedding response is invalid") |
| } |
|
|
| |
| AssertCacheHit(t, &schemas.BifrostResponse{EmbeddingResponse: response2}, "direct") |
|
|
| t.Logf("Second embedding request completed in %v", duration2) |
|
|
| |
| if duration2 >= duration1 { |
| t.Log("⚠️ Cache doesn't seem faster, but this could be due to test environment") |
| } |
|
|
| |
| if len(response1.Data) != len(response2.Data) { |
| t.Errorf("Response lengths differ: %d vs %d", len(response1.Data), len(response2.Data)) |
| } |
|
|
| t.Log("✅ Embedding requests properly cached using direct hash matching") |
| } |
|
|
| |
| func TestEmbeddingRequestsNoCacheWithoutCacheKey(t *testing.T) { |
| setup := NewTestSetup(t) |
| defer setup.Cleanup() |
|
|
| |
| ctx := CreateContextWithCacheKey("") |
|
|
| embeddingRequest := CreateEmbeddingRequest([]string{"Test embedding without cache key"}) |
|
|
| t.Log("Making embedding request without cache key...") |
|
|
| response, err := setup.Client.EmbeddingRequest(ctx, embeddingRequest) |
| if err != nil { |
| t.Fatalf("Embedding request failed: %v", err) |
| } |
|
|
| |
| AssertNoCacheHit(t, &schemas.BifrostResponse{EmbeddingResponse: response}) |
|
|
| t.Log("✅ Embedding requests without cache key are properly not cached") |
| } |
|
|
| |
| func TestEmbeddingRequestsDifferentTexts(t *testing.T) { |
| setup := NewTestSetup(t) |
| defer setup.Cleanup() |
|
|
| ctx := CreateContextWithCacheKey("test-embedding-different") |
|
|
| |
| request1 := CreateEmbeddingRequest([]string{"First set of texts"}) |
| request2 := CreateEmbeddingRequest([]string{"Second set of texts"}) |
|
|
| t.Log("Making first embedding request...") |
| response1, err1 := setup.Client.EmbeddingRequest(ctx, request1) |
| if err1 != nil { |
| return |
| } |
| AssertNoCacheHit(t, &schemas.BifrostResponse{EmbeddingResponse: response1}) |
|
|
| WaitForCache(setup.Plugin) |
|
|
| t.Log("Making second different embedding request...") |
| response2, err2 := setup.Client.EmbeddingRequest(ctx, request2) |
| if err2 != nil { |
| return |
| } |
| |
| AssertNoCacheHit(t, &schemas.BifrostResponse{EmbeddingResponse: response2}) |
|
|
| t.Log("✅ Different embedding texts produce different cache entries") |
| } |
|
|
| |
| func TestEmbeddingRequestsCacheExpiration(t *testing.T) { |
| setup := NewTestSetup(t) |
| defer setup.Cleanup() |
|
|
| |
| shortTTL := 5 * time.Second |
| ctx := CreateContextWithCacheKeyAndTTL("test-embedding-ttl", shortTTL) |
|
|
| embeddingRequest := CreateEmbeddingRequest([]string{"TTL test embedding"}) |
|
|
| t.Log("Making first embedding request with short TTL...") |
| response1, err1 := setup.Client.EmbeddingRequest(ctx, embeddingRequest) |
| if err1 != nil { |
| return |
| } |
| AssertNoCacheHit(t, &schemas.BifrostResponse{EmbeddingResponse: response1}) |
|
|
| WaitForCache(setup.Plugin) |
|
|
| t.Log("Making second request before TTL expiration...") |
| response2, err2 := setup.Client.EmbeddingRequest(ctx, embeddingRequest) |
| if err2 != nil { |
| if err2.Error != nil { |
| t.Fatalf("Second request failed: %v", err2.Error.Message) |
| } else { |
| t.Fatalf("Second request failed: %v", err2) |
| } |
| } |
| AssertCacheHit(t, &schemas.BifrostResponse{EmbeddingResponse: response2}, "direct") |
|
|
| t.Logf("Waiting for TTL expiration (%v)...", shortTTL) |
| time.Sleep(shortTTL + 1*time.Second) |
|
|
| t.Log("Making third request after TTL expiration...") |
| response3, err3 := setup.Client.EmbeddingRequest(ctx, embeddingRequest) |
| if err3 != nil { |
| return |
| } |
| |
| AssertNoCacheHit(t, &schemas.BifrostResponse{EmbeddingResponse: response3}) |
|
|
| t.Log("✅ Embedding requests properly handle TTL expiration") |
| } |
|
|