Files
wehub-resource-sync 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
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

549 lines
16 KiB
Python

"""
Tests for benchmarks/efficiency/speed_profiler.py
Tests cover:
- SpeedProfiler initialization
- Session start/stop
- Timer management (start, stop, context manager)
- Timing retrieval and summary
- time_function decorator
"""
import time
from unittest.mock import patch
class TestSpeedProfilerInit:
"""Tests for SpeedProfiler initialization."""
def test_init_creates_empty_timings(self):
"""Test that initialization creates empty timings dict."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
assert profiler.timings == {}
def test_init_creates_empty_current_timers(self):
"""Test that initialization creates empty current_timers dict."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
assert profiler.current_timers == {}
def test_init_total_start_time_is_none(self):
"""Test that total_start_time is None on init."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
assert profiler.total_start_time is None
def test_init_total_end_time_is_none(self):
"""Test that total_end_time is None on init."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
assert profiler.total_end_time is None
class TestSpeedProfilerStartStop:
"""Tests for session start/stop."""
def test_start_sets_total_start_time(self):
"""Test that start() sets total_start_time."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
before = time.time()
profiler.start()
after = time.time()
assert profiler.total_start_time is not None
assert before <= profiler.total_start_time <= after
def test_start_clears_timings(self):
"""Test that start() clears any existing timings."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.timings = {"old_timer": {"total": 1.0}}
profiler.current_timers = {"running": time.time()}
profiler.start()
assert profiler.timings == {}
assert profiler.current_timers == {}
def test_stop_sets_total_end_time(self):
"""Test that stop() sets total_end_time."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start()
before = time.time()
profiler.stop()
after = time.time()
assert profiler.total_end_time is not None
assert before <= profiler.total_end_time <= after
def test_stop_stops_running_timers(self):
"""Test that stop() stops any running timers."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start()
profiler.start_timer("running_timer")
assert "running_timer" in profiler.current_timers
profiler.stop()
assert "running_timer" not in profiler.current_timers
assert "running_timer" in profiler.timings
def test_stop_records_total_duration(self):
"""Test that stop() allows calculating total duration."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start()
time.sleep(0.01) # Small delay
profiler.stop()
duration = profiler.total_end_time - profiler.total_start_time
assert duration >= 0.01
class TestSpeedProfilerTimers:
"""Tests for timer management."""
def test_start_timer_adds_to_current_timers(self):
"""Test that start_timer adds timer to current_timers."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
before = time.time()
profiler.start_timer("my_timer")
after = time.time()
assert "my_timer" in profiler.current_timers
assert before <= profiler.current_timers["my_timer"] <= after
def test_start_timer_restarts_existing_timer(self):
"""Test that starting an existing timer restarts it."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start_timer("my_timer")
old_time = profiler.current_timers["my_timer"]
time.sleep(0.01)
profiler.start_timer("my_timer")
new_time = profiler.current_timers["my_timer"]
assert new_time > old_time
def test_stop_timer_removes_from_current_timers(self):
"""Test that stop_timer removes from current_timers."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start_timer("my_timer")
profiler.stop_timer("my_timer")
assert "my_timer" not in profiler.current_timers
def test_stop_timer_adds_to_timings(self):
"""Test that stop_timer adds timing data."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start_timer("my_timer")
time.sleep(0.01)
profiler.stop_timer("my_timer")
assert "my_timer" in profiler.timings
assert profiler.timings["my_timer"]["count"] == 1
assert profiler.timings["my_timer"]["total"] >= 0.01
def test_stop_timer_accumulates_count(self):
"""Test that multiple timer runs accumulate count."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
for _ in range(3):
profiler.start_timer("my_timer")
profiler.stop_timer("my_timer")
assert profiler.timings["my_timer"]["count"] == 3
def test_stop_timer_tracks_min_max(self):
"""Test that timer tracks min and max values."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
# First run
profiler.start_timer("my_timer")
time.sleep(0.01)
profiler.stop_timer("my_timer")
# Second run
profiler.start_timer("my_timer")
time.sleep(0.02)
profiler.stop_timer("my_timer")
assert (
profiler.timings["my_timer"]["min"]
< profiler.timings["my_timer"]["max"]
)
def test_stop_timer_not_started_does_nothing(self):
"""Test that stopping a non-existent timer does nothing."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.stop_timer("nonexistent")
assert "nonexistent" not in profiler.timings
def test_timer_context_manager_starts_and_stops(self):
"""Test timer context manager starts and stops timer."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
with profiler.timer("context_timer"):
assert "context_timer" in profiler.current_timers
assert "context_timer" not in profiler.current_timers
assert "context_timer" in profiler.timings
def test_timer_context_manager_records_time(self):
"""Test timer context manager records elapsed time."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
with profiler.timer("context_timer"):
time.sleep(0.01)
assert profiler.timings["context_timer"]["total"] >= 0.01
class TestSpeedProfilerGetTimings:
"""Tests for timing retrieval."""
def test_get_timings_returns_copy(self):
"""Test that get_timings returns a copy of timings."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start_timer("test")
profiler.stop_timer("test")
result = profiler.get_timings()
result["modified"] = True
assert "modified" not in profiler.timings
def test_get_timings_calculates_averages(self):
"""Test that get_timings calculates averages."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
for _ in range(4):
profiler.start_timer("test")
profiler.stop_timer("test")
result = profiler.get_timings()
assert "avg" in result["test"]
expected_avg = result["test"]["total"] / result["test"]["count"]
assert abs(result["test"]["avg"] - expected_avg) < 0.0001
def test_get_timings_includes_total_duration(self):
"""Test that get_timings includes total session duration."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start()
time.sleep(0.01)
profiler.stop()
result = profiler.get_timings()
assert "total" in result
assert result["total"]["total"] >= 0.01
def test_get_timings_empty_when_no_timers(self):
"""Test that get_timings returns empty dict when no timers used."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
result = profiler.get_timings()
assert result == {}
class TestSpeedProfilerGetSummary:
"""Tests for summary generation."""
def test_get_summary_includes_total_duration(self):
"""Test that summary includes total_duration."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start()
time.sleep(0.01)
profiler.stop()
summary = profiler.get_summary()
assert "total_duration" in summary
assert summary["total_duration"] >= 0.01
def test_get_summary_calculates_percentages(self):
"""Test that summary calculates component percentages."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start()
with profiler.timer("component"):
time.sleep(0.01)
profiler.stop()
summary = profiler.get_summary()
assert "component_percent" in summary
assert 0 <= summary["component_percent"] <= 100
def test_get_summary_includes_per_operation_times(self):
"""Test that summary includes per-operation times."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
for _ in range(3):
profiler.start_timer("op")
profiler.stop_timer("op")
summary = profiler.get_summary()
assert "op_per_operation" in summary
def test_get_summary_handles_zero_duration(self):
"""Test that summary handles zero total duration gracefully."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start_timer("test")
profiler.stop_timer("test")
# Don't call start/stop, so total_duration comes from sum of timers
summary = profiler.get_summary()
# Should not raise division by zero
assert "total_duration" in summary
class TestSpeedProfilerPrintSummary:
"""Tests for print_summary."""
def test_print_summary_outputs_header(self, capsys):
"""Test that print_summary outputs header."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start()
profiler.stop()
profiler.print_summary()
captured = capsys.readouterr()
assert "SPEED PROFILE SUMMARY" in captured.out
def test_print_summary_shows_total_time(self, capsys):
"""Test that print_summary shows total execution time."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
profiler.start()
time.sleep(0.01)
profiler.stop()
profiler.print_summary()
captured = capsys.readouterr()
assert "Total execution time:" in captured.out
class TestTimeFunctionDecorator:
"""Tests for time_function decorator."""
def test_time_function_returns_result(self):
"""Test that decorated function returns correct result."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
time_function,
)
@time_function
def add(a, b):
return a + b
result = add(2, 3)
assert result == 5
def test_time_function_logs_execution_time(self):
"""Test that decorator logs execution time."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
time_function,
)
@time_function
def slow_function():
time.sleep(0.01)
return "done"
with patch(
"local_deep_research.benchmarks.efficiency.speed_profiler.logger"
) as mock_logger:
slow_function()
mock_logger.info.assert_called_once()
call_args = mock_logger.info.call_args[0][0]
assert "slow_function" in call_args
assert "seconds" in call_args
def test_time_function_preserves_args_kwargs(self):
"""Test that decorator preserves function arguments."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
time_function,
)
@time_function
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
result = greet("World", greeting="Hi")
assert result == "Hi, World!"
class TestSpeedProfilerTimingData:
"""Tests for timing data structure."""
def test_timing_data_includes_starts_list(self):
"""Test that timing data includes list of start times."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
for _ in range(3):
profiler.start_timer("test")
profiler.stop_timer("test")
assert "starts" in profiler.timings["test"]
assert len(profiler.timings["test"]["starts"]) == 3
def test_timing_data_includes_durations_list(self):
"""Test that timing data includes list of durations."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
for _ in range(3):
profiler.start_timer("test")
profiler.stop_timer("test")
assert "durations" in profiler.timings["test"]
assert len(profiler.timings["test"]["durations"]) == 3
def test_timing_data_total_equals_sum_of_durations(self):
"""Test that total equals sum of individual durations."""
from local_deep_research.benchmarks.efficiency.speed_profiler import (
SpeedProfiler,
)
profiler = SpeedProfiler()
for _ in range(3):
profiler.start_timer("test")
time.sleep(0.01)
profiler.stop_timer("test")
total = profiler.timings["test"]["total"]
sum_durations = sum(profiler.timings["test"]["durations"])
assert abs(total - sum_durations) < 0.0001