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
180 lines
6.1 KiB
Python
180 lines
6.1 KiB
Python
"""
|
|
Tests targeting specific uncovered lines in xbench_deepsearch.py.
|
|
|
|
Covers:
|
|
- Decrypt failure in load_data (exception in base64 decode/XOR)
|
|
- Encrypted prompt in _load_from_url
|
|
- Decrypt failure in _load_from_url
|
|
- _load_from_url returns every row (sampling happens in load())
|
|
"""
|
|
|
|
import base64
|
|
from unittest.mock import MagicMock, Mock, patch
|
|
|
|
MODULE = "local_deep_research.benchmarks.datasets.xbench_deepsearch"
|
|
|
|
|
|
def _make_dataset():
|
|
from local_deep_research.benchmarks.datasets.xbench_deepsearch import (
|
|
XBenchDeepSearchDataset,
|
|
)
|
|
|
|
return XBenchDeepSearchDataset()
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Lines 133-138: Decrypt failure in load_data
|
|
# ---------------------------------------------------------------------------
|
|
class TestLoadDataDecryptFailure:
|
|
def test_decrypt_failure_logs_warning_and_keeps_original(self):
|
|
"""When XOR decrypt produces invalid UTF-8, exception is caught
|
|
and original (encrypted) value is used."""
|
|
ds = _make_dataset()
|
|
|
|
# Create a prompt that looks like base64 but when decrypted gives invalid UTF-8
|
|
# Use bytes that are valid base64 but XOR to non-UTF-8 sequences
|
|
bad_bytes = bytes([0xFF, 0xFE, 0xFD, 0xFC]) # Invalid UTF-8
|
|
key = "k"
|
|
key_bytes = key.encode("utf-8")
|
|
# XOR to create "encrypted" form
|
|
encrypted = bytes(
|
|
[
|
|
bad_bytes[i] ^ key_bytes[i % len(key_bytes)]
|
|
for i in range(len(bad_bytes))
|
|
]
|
|
)
|
|
encoded_prompt = base64.b64encode(encrypted).decode("utf-8")
|
|
|
|
mock_item = {
|
|
"id": "fail_1",
|
|
"prompt": encoded_prompt,
|
|
"answer": "plain answer",
|
|
"canary": key,
|
|
"reference_steps": "",
|
|
}
|
|
mock_dataset = [mock_item]
|
|
mock_load_dataset = Mock(return_value=mock_dataset)
|
|
|
|
with patch.dict(
|
|
"sys.modules", {"datasets": Mock(load_dataset=mock_load_dataset)}
|
|
):
|
|
with patch(f"{MODULE}.logger") as mock_logger:
|
|
result = ds.load_data()
|
|
|
|
assert len(result) == 1
|
|
# The warning should have been called
|
|
mock_logger.warning.assert_called()
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Encrypted prompt in _load_from_url
|
|
# ---------------------------------------------------------------------------
|
|
class TestLoadFromUrlEncrypted:
|
|
def test_url_decrypts_base64_prompt(self):
|
|
"""_load_from_url decrypts base64-encoded prompts via XOR."""
|
|
ds = _make_dataset()
|
|
|
|
plaintext = b"Real question from URL"
|
|
key = "urlkey"
|
|
key_bytes = key.encode("utf-8")
|
|
xored = bytes(
|
|
[
|
|
plaintext[i] ^ key_bytes[i % len(key_bytes)]
|
|
for i in range(len(plaintext))
|
|
]
|
|
)
|
|
encoded_prompt = base64.b64encode(xored).decode("utf-8")
|
|
|
|
mock_df = MagicMock()
|
|
row = MagicMock()
|
|
row.get = lambda k, default="": {
|
|
"id": "url_enc_1",
|
|
"prompt": encoded_prompt,
|
|
"answer": "plain answer",
|
|
"canary": key,
|
|
"reference_steps": "",
|
|
}.get(k, default)
|
|
mock_df.iterrows.return_value = [(0, row)]
|
|
|
|
mock_pd = Mock()
|
|
mock_pd.read_parquet.return_value = mock_df
|
|
with patch.dict("sys.modules", {"pandas": mock_pd}):
|
|
with patch(f"{MODULE}.logger"):
|
|
result = ds._load_from_url()
|
|
|
|
assert len(result) == 1
|
|
assert result[0]["problem"] == "Real question from URL"
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Decrypt failure in _load_from_url
|
|
# ---------------------------------------------------------------------------
|
|
class TestLoadFromUrlDecryptFailure:
|
|
def test_url_decrypt_failure_keeps_original(self):
|
|
"""When decrypt fails in _load_from_url, original value is used."""
|
|
ds = _make_dataset()
|
|
|
|
bad_bytes = bytes([0xFF, 0xFE, 0xFD])
|
|
key = "x"
|
|
key_bytes = key.encode("utf-8")
|
|
encrypted = bytes(
|
|
[
|
|
bad_bytes[i] ^ key_bytes[i % len(key_bytes)]
|
|
for i in range(len(bad_bytes))
|
|
]
|
|
)
|
|
encoded_prompt = base64.b64encode(encrypted).decode("utf-8")
|
|
|
|
mock_df = MagicMock()
|
|
row = MagicMock()
|
|
row.get = lambda k, default="": {
|
|
"id": "url_fail_1",
|
|
"prompt": encoded_prompt,
|
|
"answer": "plain",
|
|
"canary": key,
|
|
"reference_steps": "",
|
|
}.get(k, default)
|
|
mock_df.iterrows.return_value = [(0, row)]
|
|
|
|
mock_pd = Mock()
|
|
mock_pd.read_parquet.return_value = mock_df
|
|
with patch.dict("sys.modules", {"pandas": mock_pd}):
|
|
with patch(f"{MODULE}.logger") as mock_logger:
|
|
result = ds._load_from_url()
|
|
|
|
assert len(result) == 1
|
|
mock_logger.warning.assert_called()
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# _load_from_url returns every row (sampling happens in load())
|
|
# ---------------------------------------------------------------------------
|
|
class TestLoadFromUrlLoadsAll:
|
|
def test_url_loads_all_rows(self):
|
|
"""_load_from_url returns the full dataset without sampling."""
|
|
ds = _make_dataset()
|
|
|
|
mock_df = MagicMock()
|
|
rows = []
|
|
for i in range(10):
|
|
row = MagicMock()
|
|
row.get = lambda k, default="", idx=i: {
|
|
"id": f"url_q{idx}",
|
|
"prompt": f"Question {idx}",
|
|
"answer": f"Answer {idx}",
|
|
"canary": "",
|
|
"reference_steps": "",
|
|
}.get(k, default)
|
|
rows.append((i, row))
|
|
mock_df.iterrows.return_value = rows
|
|
|
|
mock_pd = Mock()
|
|
mock_pd.read_parquet.return_value = mock_df
|
|
with patch.dict("sys.modules", {"pandas": mock_pd}):
|
|
with patch(f"{MODULE}.logger"):
|
|
result = ds._load_from_url()
|
|
|
|
assert len(result) == 10
|
|
assert [q["id"] for q in result] == [f"url_q{i}" for i in range(10)]
|
|
assert result[0]["problem"] == "Question 0"
|