Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3361ba51b2 | ||
|
|
8680b17976 |
No files matched your search
@@ -39,11 +39,11 @@ if (-not $failed -or $diagnostics -notcontains 'download progress' -or $diagnost
|
|||||||
$global:LASTEXITCODE = 0
|
$global:LASTEXITCODE = 0
|
||||||
function codex { $script:observedCodexHome = $env:CODEX_HOME; $script:observedProfile = $env:USERPROFILE; '{"installed":[{"pluginId":"ponytail@ponytail"},{"pluginId":"i-have-adhd@i-have-adhd"},{"pluginId":"superpowers@openai-curated-remote"},{"pluginId":"context7@context7-marketplace"},{"pluginId":"caveman@thinkhome-caveman"}],"available":[]}' }
|
function codex { $script:observedCodexHome = $env:CODEX_HOME; $script:observedProfile = $env:USERPROFILE; '{"installed":[{"pluginId":"ponytail@ponytail"},{"pluginId":"i-have-adhd@i-have-adhd"},{"pluginId":"superpowers@openai-curated-remote"},{"pluginId":"context7@context7-marketplace"},{"pluginId":"caveman@thinkhome-caveman"}],"available":[]}' }
|
||||||
$testHome = Join-Path ([System.IO.Path]::GetTempPath()) 'ai-config-plugin-test-home'
|
$testHome = Join-Path ([System.IO.Path]::GetTempPath()) 'ai-config-plugin-test-home'
|
||||||
$previousCodexHome = $env:CODEX_HOME
|
$previousCodexHome = [Environment]::GetEnvironmentVariable('CODEX_HOME', 'Process')
|
||||||
$previousProfile = $env:USERPROFILE
|
$previousProfile = [Environment]::GetEnvironmentVariable('USERPROFILE', 'Process')
|
||||||
$null = Get-InstalledPlugins -Client Codex -HomePath $testHome
|
$null = Get-InstalledPlugins -Client Codex -HomePath $testHome
|
||||||
if ($observedCodexHome -ne (Join-Path $testHome '.codex') -or $observedProfile -ne $testHome) { throw 'Plugin inspection must use the requested user home.' }
|
if ($observedCodexHome -ne (Join-Path $testHome '.codex') -or $observedProfile -ne $testHome) { throw 'Plugin inspection must use the requested user home.' }
|
||||||
if ($env:CODEX_HOME -ne $previousCodexHome -or $env:USERPROFILE -ne $previousProfile) { throw 'Plugin inspection must restore the process environment.' }
|
if ([Environment]::GetEnvironmentVariable('CODEX_HOME', 'Process') -ne $previousCodexHome -or [Environment]::GetEnvironmentVariable('USERPROFILE', 'Process') -ne $previousProfile) { throw 'Plugin inspection must restore the process environment.' }
|
||||||
$script:answers.Enqueue('done')
|
$script:answers.Enqueue('done')
|
||||||
$selection = Select-ConfiguredPlugins -RepositoryRoot (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) -Client Codex -Mode Update
|
$selection = Select-ConfiguredPlugins -RepositoryRoot (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) -Client Codex -Mode Update
|
||||||
if (@($selection.Selected | Where-Object { $_.codex_method -eq 'plugin' }).Count -ne 5) { throw 'All installed Codex plugins must start checked when updating.' }
|
if (@($selection.Selected | Where-Object { $_.codex_method -eq 'plugin' }).Count -ne 5) { throw 'All installed Codex plugins must start checked when updating.' }
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from tempfile import TemporaryDirectory
|
|||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
|
import urllib.request
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
|
||||||
@@ -29,17 +30,33 @@ def embedding():
|
|||||||
|
|
||||||
def huggingface_available():
|
def huggingface_available():
|
||||||
try:
|
try:
|
||||||
socket.getaddrinfo('huggingface.co', 443)
|
request = urllib.request.Request('https://huggingface.co', method='HEAD')
|
||||||
except socket.gaierror:
|
with urllib.request.urlopen(request, timeout=5):
|
||||||
|
pass
|
||||||
|
except OSError:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def huggingface_network_unavailable(error):
|
||||||
|
while error:
|
||||||
|
if isinstance(error, socket.gaierror):
|
||||||
|
return True
|
||||||
|
error = error.__cause__ or error.__context__
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class RetrievalServerTests(unittest.TestCase):
|
class RetrievalServerTests(unittest.TestCase):
|
||||||
def test_huggingface_availability_handles_dns_failure(self):
|
def test_huggingface_availability_handles_connection_failure(self):
|
||||||
with patch('socket.getaddrinfo', side_effect=socket.gaierror):
|
with patch('urllib.request.urlopen', side_effect=OSError):
|
||||||
self.assertFalse(huggingface_available())
|
self.assertFalse(huggingface_available())
|
||||||
|
|
||||||
|
def test_huggingface_network_failure_is_detected_from_cause_chain(self):
|
||||||
|
error = OSError('model download failed')
|
||||||
|
error.__cause__ = socket.gaierror('name resolution failed')
|
||||||
|
self.assertTrue(huggingface_network_unavailable(error))
|
||||||
|
self.assertFalse(huggingface_network_unavailable(OSError('model is missing')))
|
||||||
|
|
||||||
def test_ci_disables_xet_for_model_downloads(self):
|
def test_ci_disables_xet_for_model_downloads(self):
|
||||||
for workflow in ('.github/workflows/ci.yml', '.gitea/workflows/ci.yml'):
|
for workflow in ('.github/workflows/ci.yml', '.gitea/workflows/ci.yml'):
|
||||||
content = (ROOT / workflow).read_text(encoding='utf-8')
|
content = (ROOT / workflow).read_text(encoding='utf-8')
|
||||||
@@ -75,6 +92,7 @@ class RetrievalServerTests(unittest.TestCase):
|
|||||||
(root / 'authentication.md').write_text('Password reset tokens are created by create_reset_token. The reset_password endpoint sends the user a password reset email.', encoding='utf-8')
|
(root / 'authentication.md').write_text('Password reset tokens are created by create_reset_token. The reset_password endpoint sends the user a password reset email.', encoding='utf-8')
|
||||||
(root / 'weather.md').write_text('The weather service fetches temperature and rainfall forecasts for a city.', encoding='utf-8')
|
(root / 'weather.md').write_text('The weather service fetches temperature and rainfall forecasts for a city.', encoding='utf-8')
|
||||||
index = MODULE.Index(root, root / 'data')
|
index = MODULE.Index(root, root / 'data')
|
||||||
|
self.addCleanup(index.db.close)
|
||||||
try:
|
try:
|
||||||
tokenizer = index.encoder().tokenizer
|
tokenizer = index.encoder().tokenizer
|
||||||
for source in ['alpha beta gamma ' * 450, 'Grüße 世界 🙂 ' * 300]:
|
for source in ['alpha beta gamma ' * 450, 'Grüße 世界 🙂 ' * 300]:
|
||||||
@@ -91,8 +109,10 @@ class RetrievalServerTests(unittest.TestCase):
|
|||||||
self.assertEqual(len(results), 2)
|
self.assertEqual(len(results), 2)
|
||||||
self.assertGreater(results[0]['score'], results[1]['score'])
|
self.assertGreater(results[0]['score'], results[1]['score'])
|
||||||
print(f'Qwen real search: {expected}, {time.monotonic() - started:.2f}s, embedding device {index.encoder().device}, reranker device {index.reranker().device}', flush=True)
|
print(f'Qwen real search: {expected}, {time.monotonic() - started:.2f}s, embedding device {index.encoder().device}, reranker device {index.reranker().device}', flush=True)
|
||||||
finally:
|
except OSError as error:
|
||||||
index.db.close()
|
if huggingface_network_unavailable(error):
|
||||||
|
self.skipTest('Hugging Face network is unavailable')
|
||||||
|
raise
|
||||||
|
|
||||||
def test_isolation_freshness_and_incremental_encoding(self):
|
def test_isolation_freshness_and_incremental_encoding(self):
|
||||||
with TemporaryDirectory() as temporary:
|
with TemporaryDirectory() as temporary:
|
||||||
|
|||||||
Reference in new issue
Block a user