7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
304 lines
9.9 KiB
Python
304 lines
9.9 KiB
Python
"""
|
|
Tests for benchmarks/metrics/calculation.py
|
|
|
|
Tests cover:
|
|
- calculate_metrics function
|
|
- calculate_combined_score function
|
|
- calculate_resource_metrics function
|
|
"""
|
|
|
|
import json
|
|
|
|
|
|
class TestCalculateMetrics:
|
|
"""Tests for the calculate_metrics function."""
|
|
|
|
def test_calculates_basic_metrics(self, tmp_path):
|
|
"""Test calculation of basic metrics from results file."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_metrics,
|
|
)
|
|
|
|
# Create a test results file
|
|
results_file = tmp_path / "results.jsonl"
|
|
results = [
|
|
{"is_correct": True, "processing_time": 1.5, "confidence": "90"},
|
|
{"is_correct": True, "processing_time": 2.0, "confidence": "85"},
|
|
{"is_correct": False, "processing_time": 1.0, "confidence": "70"},
|
|
]
|
|
with open(results_file, "w") as f:
|
|
for r in results:
|
|
f.write(json.dumps(r) + "\n")
|
|
|
|
metrics = calculate_metrics(str(results_file))
|
|
|
|
assert metrics["total_examples"] == 3
|
|
assert metrics["graded_examples"] == 3
|
|
assert metrics["correct"] == 2
|
|
assert metrics["accuracy"] == 2 / 3
|
|
assert metrics["average_processing_time"] == 1.5
|
|
assert metrics["average_confidence"] == (90 + 85 + 70) / 3
|
|
|
|
def test_handles_empty_file(self, tmp_path):
|
|
"""Test handling of empty results file."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_metrics,
|
|
)
|
|
|
|
results_file = tmp_path / "empty.jsonl"
|
|
results_file.write_text("")
|
|
|
|
metrics = calculate_metrics(str(results_file))
|
|
|
|
assert "error" in metrics
|
|
assert metrics["error"] == "No results found"
|
|
|
|
def test_handles_missing_file(self, tmp_path):
|
|
"""Test handling of missing results file."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_metrics,
|
|
)
|
|
|
|
metrics = calculate_metrics(str(tmp_path / "nonexistent.jsonl"))
|
|
|
|
assert "error" in metrics
|
|
|
|
def test_calculates_error_rate(self, tmp_path):
|
|
"""Test calculation of error rate."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_metrics,
|
|
)
|
|
|
|
results_file = tmp_path / "results.jsonl"
|
|
results = [
|
|
{"is_correct": True},
|
|
{"error": "Some error occurred"},
|
|
{"is_correct": False},
|
|
]
|
|
with open(results_file, "w") as f:
|
|
for r in results:
|
|
f.write(json.dumps(r) + "\n")
|
|
|
|
metrics = calculate_metrics(str(results_file))
|
|
|
|
assert metrics["error_count"] == 1
|
|
assert metrics["error_rate"] == 1 / 3
|
|
|
|
def test_calculates_per_category_metrics(self, tmp_path):
|
|
"""Test calculation of per-category metrics."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_metrics,
|
|
)
|
|
|
|
results_file = tmp_path / "results.jsonl"
|
|
results = [
|
|
{"is_correct": True, "category": "science"},
|
|
{"is_correct": False, "category": "science"},
|
|
{"is_correct": True, "category": "history"},
|
|
{"is_correct": True, "category": "history"},
|
|
]
|
|
with open(results_file, "w") as f:
|
|
for r in results:
|
|
f.write(json.dumps(r) + "\n")
|
|
|
|
metrics = calculate_metrics(str(results_file))
|
|
|
|
assert "categories" in metrics
|
|
assert metrics["categories"]["science"]["total"] == 2
|
|
assert metrics["categories"]["science"]["correct"] == 1
|
|
assert metrics["categories"]["science"]["accuracy"] == 0.5
|
|
assert metrics["categories"]["history"]["total"] == 2
|
|
assert metrics["categories"]["history"]["correct"] == 2
|
|
assert metrics["categories"]["history"]["accuracy"] == 1.0
|
|
|
|
def test_handles_missing_confidence(self, tmp_path):
|
|
"""Test handling of results without confidence values."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_metrics,
|
|
)
|
|
|
|
results_file = tmp_path / "results.jsonl"
|
|
results = [
|
|
{"is_correct": True},
|
|
{"is_correct": False},
|
|
]
|
|
with open(results_file, "w") as f:
|
|
for r in results:
|
|
f.write(json.dumps(r) + "\n")
|
|
|
|
metrics = calculate_metrics(str(results_file))
|
|
|
|
assert metrics["average_confidence"] == 0
|
|
|
|
def test_handles_invalid_confidence(self, tmp_path):
|
|
"""Test handling of invalid confidence values."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_metrics,
|
|
)
|
|
|
|
results_file = tmp_path / "results.jsonl"
|
|
results = [
|
|
{"is_correct": True, "confidence": "invalid"},
|
|
{"is_correct": True, "confidence": "80"},
|
|
]
|
|
with open(results_file, "w") as f:
|
|
for r in results:
|
|
f.write(json.dumps(r) + "\n")
|
|
|
|
metrics = calculate_metrics(str(results_file))
|
|
|
|
# Should skip invalid and only use valid confidence
|
|
assert metrics["average_confidence"] == 80
|
|
|
|
|
|
class TestCalculateCombinedScore:
|
|
"""Tests for the calculate_combined_score function."""
|
|
|
|
def test_calculates_with_default_weights(self):
|
|
"""Test combined score with default weights."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_combined_score,
|
|
)
|
|
|
|
metrics = {
|
|
"quality": {"quality_score": 0.8},
|
|
"speed": {"speed_score": 0.6},
|
|
"resource": {"resource_score": 0.9},
|
|
}
|
|
|
|
score = calculate_combined_score(metrics)
|
|
|
|
# Default weights: quality=0.6, speed=0.3, resource=0.1
|
|
expected = 0.8 * 0.6 + 0.6 * 0.3 + 0.9 * 0.1
|
|
assert abs(score - expected) < 0.001
|
|
|
|
def test_calculates_with_custom_weights(self):
|
|
"""Test combined score with custom weights."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_combined_score,
|
|
)
|
|
|
|
metrics = {
|
|
"quality": {"quality_score": 1.0},
|
|
"speed": {"speed_score": 0.5},
|
|
"resource": {"resource_score": 0.0},
|
|
}
|
|
weights = {"quality": 0.5, "speed": 0.5, "resource": 0.0}
|
|
|
|
score = calculate_combined_score(metrics, weights)
|
|
|
|
expected = 1.0 * 0.5 + 0.5 * 0.5 + 0.0 * 0.0
|
|
assert abs(score - expected) < 0.001
|
|
|
|
def test_handles_missing_metrics(self):
|
|
"""Test handling of missing metric categories."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_combined_score,
|
|
)
|
|
|
|
metrics = {
|
|
"quality": {"quality_score": 0.8},
|
|
# Missing speed and resource
|
|
}
|
|
|
|
score = calculate_combined_score(metrics)
|
|
|
|
# Should only count quality component
|
|
assert score > 0
|
|
assert score <= 1.0
|
|
|
|
def test_handles_zero_weights(self):
|
|
"""Test handling of zero total weight."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_combined_score,
|
|
)
|
|
|
|
metrics = {
|
|
"quality": {"quality_score": 0.8},
|
|
}
|
|
weights = {"quality": 0, "speed": 0, "resource": 0}
|
|
|
|
score = calculate_combined_score(metrics, weights)
|
|
|
|
assert score == 0.0
|
|
|
|
def test_normalizes_weights(self):
|
|
"""Test that weights are normalized."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_combined_score,
|
|
)
|
|
|
|
metrics = {
|
|
"quality": {"quality_score": 1.0},
|
|
"speed": {"speed_score": 1.0},
|
|
"resource": {"resource_score": 1.0},
|
|
}
|
|
# Weights that don't sum to 1
|
|
weights = {"quality": 2, "speed": 1, "resource": 1}
|
|
|
|
score = calculate_combined_score(metrics, weights)
|
|
|
|
# All scores are 1.0, so normalized result should be 1.0
|
|
assert abs(score - 1.0) < 0.001
|
|
|
|
|
|
class TestCalculateResourceMetrics:
|
|
"""Tests for the calculate_resource_metrics function."""
|
|
|
|
def test_calculates_resource_score(self):
|
|
"""Test calculation of resource score."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_resource_metrics,
|
|
)
|
|
|
|
config = {
|
|
"iterations": 2,
|
|
"questions_per_iteration": 2,
|
|
"max_results": 50,
|
|
}
|
|
|
|
metrics = calculate_resource_metrics(config)
|
|
|
|
assert "resource_score" in metrics
|
|
assert "estimated_complexity" in metrics
|
|
assert 0 <= metrics["resource_score"] <= 1
|
|
|
|
def test_higher_complexity_lower_score(self):
|
|
"""Test that higher complexity results in lower resource score."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_resource_metrics,
|
|
)
|
|
|
|
low_complexity_config = {
|
|
"iterations": 1,
|
|
"questions_per_iteration": 1,
|
|
"max_results": 25,
|
|
}
|
|
high_complexity_config = {
|
|
"iterations": 5,
|
|
"questions_per_iteration": 5,
|
|
"max_results": 100,
|
|
}
|
|
|
|
low_metrics = calculate_resource_metrics(low_complexity_config)
|
|
high_metrics = calculate_resource_metrics(high_complexity_config)
|
|
|
|
assert low_metrics["resource_score"] > high_metrics["resource_score"]
|
|
assert (
|
|
low_metrics["estimated_complexity"]
|
|
< high_metrics["estimated_complexity"]
|
|
)
|
|
|
|
def test_uses_default_values(self):
|
|
"""Test that default values are used for missing config."""
|
|
from local_deep_research.benchmarks.metrics.calculation import (
|
|
calculate_resource_metrics,
|
|
)
|
|
|
|
empty_config = {}
|
|
|
|
metrics = calculate_resource_metrics(empty_config)
|
|
|
|
assert "resource_score" in metrics
|
|
assert metrics["resource_score"] > 0
|