Files
SkillCompiler/data/skills-bench/tasks/parallel-tfidf-search/verifier/test_outputs.py
T
2026-09-04 14:58:42 +08:00

181 lines
6.1 KiBLFS
Python

#!/usr/bin/env python3
"""
Tests for Parallel TF-IDF Implementation
Tests correctness and performance of the parallel implementation.
"""
import random
import sys
import time
import pytest
sys.path.insert(0, "/root/workspace")
from document_generator import generate_corpus
from sequential import (
batch_search_sequential,
build_tfidf_index_sequential,
)
class TestParallelImplementation:
"""Test that parallel implementation exists and has correct interface."""
def test_parallel_solution_exists(self):
"""Test that parallel_solution.py exists and can be imported."""
try:
from parallel_solution import (
batch_search_parallel, # noqa: F401
build_tfidf_index_parallel, # noqa: F401
)
except ImportError as e:
pytest.fail(f"Could not import parallel_solution: {e}")
class TestCorrectnessSmall:
"""Test correctness with small dataset."""
@pytest.fixture(scope="class")
def small_corpus(self):
"""Generate small test corpus."""
return generate_corpus(1000, seed=42)
@pytest.fixture(scope="class")
def sequential_index(self, small_corpus):
"""Build sequential index for comparison."""
return build_tfidf_index_sequential(small_corpus)
def test_idf_values_match(self, small_corpus, sequential_index):
"""Test that IDF values match."""
from parallel_solution import build_tfidf_index_parallel
para_result = build_tfidf_index_parallel(small_corpus, num_workers=4)
for term in sequential_index.index.vocabulary:
seq_idf = sequential_index.index.idf.get(term, 0)
para_idf = para_result.index.idf.get(term, 0)
assert abs(seq_idf - para_idf) < 1e-6, f"IDF mismatch for term '{term}': {seq_idf} vs {para_idf}"
def test_search_results_match(self, small_corpus, sequential_index):
"""Test that search results match."""
from parallel_solution import batch_search_parallel, build_tfidf_index_parallel
para_result = build_tfidf_index_parallel(small_corpus, num_workers=4)
queries = ["machine learning algorithm", "database optimization", "clinical trial treatment"]
seq_results = batch_search_sequential(queries, sequential_index.index, top_k=10, documents=small_corpus)
para_results, _ = batch_search_parallel(queries, para_result.index, top_k=10, num_workers=4, documents=small_corpus)
for i, (seq_res, para_res) in enumerate(zip(seq_results, para_results)):
assert len(seq_res) == len(para_res), f"Different result count for query {i}"
for j, (s, p) in enumerate(zip(seq_res, para_res)):
assert s.doc_id == p.doc_id, f"Doc ID mismatch for query {i}, result {j}"
assert abs(s.score - p.score) < 1e-6, f"Score mismatch for query {i}, result {j}"
class TestPerformanceIndexing:
"""Test index building performance."""
@pytest.fixture(scope="class")
def perf_corpus(self):
"""Generate corpus for performance testing."""
return generate_corpus(5000, seed=789)
def test_index_speedup(self, perf_corpus):
"""Test that parallel indexing achieves speedup."""
from parallel_solution import build_tfidf_index_parallel
# Sequential baseline
start = time.perf_counter()
build_tfidf_index_sequential(perf_corpus)
seq_time = time.perf_counter() - start
# Parallel with 4 workers
start = time.perf_counter()
build_tfidf_index_parallel(perf_corpus, num_workers=4)
para_time = time.perf_counter() - start
speedup = seq_time / para_time
print("\nIndex Building Performance:")
print(f" Sequential: {seq_time:.2f}s")
print(f" Parallel (4 workers): {para_time:.2f}s")
print(f" Speedup: {speedup:.2f}x")
# Require at least 1.5x speedup
assert speedup >= 1.5, f"Insufficient speedup: {speedup:.2f}x (required: 1.5x)"
class TestPerformanceSearch:
"""Test batch search performance."""
@pytest.fixture(scope="class")
def search_setup(self):
"""Set up corpus and index for search testing."""
corpus = generate_corpus(5000, seed=101)
from parallel_solution import build_tfidf_index_parallel
index_result = build_tfidf_index_parallel(corpus, num_workers=4)
# Generate variable-length queries
random.seed(202)
base_terms = [
"machine",
"learning",
"algorithm",
"neural",
"network",
"database",
"optimization",
"performance",
"clinical",
"trial",
"market",
"analysis",
"investment",
"research",
"methodology",
]
queries = []
for _ in range(1000):
length = random.randint(1, 20)
query = " ".join(random.choices(base_terms, k=length))
queries.append(query)
return corpus, index_result.index, queries
def test_search_speedup(self, search_setup):
"""Test that parallel search achieves speedup."""
from parallel_solution import batch_search_parallel
corpus, index, queries = search_setup
# Sequential baseline
start = time.perf_counter()
batch_search_sequential(queries, index, top_k=10, documents=corpus)
seq_time = time.perf_counter() - start
# Parallel with 4 workers
start = time.perf_counter()
batch_search_parallel(queries, index, top_k=10, num_workers=4, documents=corpus)
para_time = time.perf_counter() - start
speedup = seq_time / para_time
print("\nBatch Search Performance (1000 queries):")
print(f" Sequential: {seq_time:.2f}s")
print(f" Parallel (4 workers): {para_time:.2f}s")
print(f" Speedup: {speedup:.2f}x")
# Require at least 2x speedup for batch search
assert speedup >= 2.0, f"Insufficient speedup: {speedup:.2f}x (required: 2.0x)"
if __name__ == "__main__":
pytest.main([__file__, "-v"])