package database import ( "context" "testing" ) func TestBlobChunkRepository(t *testing.T) { db, cleanup := setupTestDB(t) defer cleanup() ctx := context.Background() repo := NewBlobChunkRepository(db) // Test Create bc1 := &BlobChunk{ BlobHash: "blob1", ChunkHash: "chunk1", Offset: 0, Length: 1024, } err := repo.Create(ctx, nil, bc1) if err != nil { t.Fatalf("failed to create blob chunk: %v", err) } // Add more chunks to the same blob bc2 := &BlobChunk{ BlobHash: "blob1", ChunkHash: "chunk2", Offset: 1024, Length: 2048, } err = repo.Create(ctx, nil, bc2) if err != nil { t.Fatalf("failed to create second blob chunk: %v", err) } bc3 := &BlobChunk{ BlobHash: "blob1", ChunkHash: "chunk3", Offset: 3072, Length: 512, } err = repo.Create(ctx, nil, bc3) if err != nil { t.Fatalf("failed to create third blob chunk: %v", err) } // Test GetByBlobHash chunks, err := repo.GetByBlobHash(ctx, "blob1") if err != nil { t.Fatalf("failed to get blob chunks: %v", err) } if len(chunks) != 3 { t.Errorf("expected 3 chunks, got %d", len(chunks)) } // Verify order by offset expectedOffsets := []int64{0, 1024, 3072} for i, chunk := range chunks { if chunk.Offset != expectedOffsets[i] { t.Errorf("wrong chunk order: expected offset %d, got %d", expectedOffsets[i], chunk.Offset) } } // Test GetByChunkHash bc, err := repo.GetByChunkHash(ctx, "chunk2") if err != nil { t.Fatalf("failed to get blob chunk by chunk hash: %v", err) } if bc == nil { t.Fatal("expected blob chunk, got nil") } if bc.BlobHash != "blob1" { t.Errorf("wrong blob hash: expected blob1, got %s", bc.BlobHash) } if bc.Offset != 1024 { t.Errorf("wrong offset: expected 1024, got %d", bc.Offset) } // Test non-existent chunk bc, err = repo.GetByChunkHash(ctx, "nonexistent") if err != nil { t.Fatalf("unexpected error: %v", err) } if bc != nil { t.Error("expected nil for non-existent chunk") } } func TestBlobChunkRepositoryMultipleBlobs(t *testing.T) { db, cleanup := setupTestDB(t) defer cleanup() ctx := context.Background() repo := NewBlobChunkRepository(db) // Create chunks across multiple blobs // Some chunks are shared between blobs (deduplication scenario) blobChunks := []BlobChunk{ {BlobHash: "blob1", ChunkHash: "chunk1", Offset: 0, Length: 1024}, {BlobHash: "blob1", ChunkHash: "chunk2", Offset: 1024, Length: 1024}, {BlobHash: "blob2", ChunkHash: "chunk2", Offset: 0, Length: 1024}, // chunk2 is shared {BlobHash: "blob2", ChunkHash: "chunk3", Offset: 1024, Length: 1024}, } for _, bc := range blobChunks { err := repo.Create(ctx, nil, &bc) if err != nil { t.Fatalf("failed to create blob chunk: %v", err) } } // Verify blob1 chunks chunks, err := repo.GetByBlobHash(ctx, "blob1") if err != nil { t.Fatalf("failed to get blob1 chunks: %v", err) } if len(chunks) != 2 { t.Errorf("expected 2 chunks for blob1, got %d", len(chunks)) } // Verify blob2 chunks chunks, err = repo.GetByBlobHash(ctx, "blob2") if err != nil { t.Fatalf("failed to get blob2 chunks: %v", err) } if len(chunks) != 2 { t.Errorf("expected 2 chunks for blob2, got %d", len(chunks)) } // Verify shared chunk bc, err := repo.GetByChunkHash(ctx, "chunk2") if err != nil { t.Fatalf("failed to get shared chunk: %v", err) } if bc == nil { t.Fatal("expected shared chunk, got nil") } // GetByChunkHash returns first match, should be blob1 if bc.BlobHash != "blob1" { t.Errorf("expected blob1 for shared chunk, got %s", bc.BlobHash) } }