Download src/server/__tests__/proxy-network-settings.test.ts from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 7.55 kB
-
https://huggingface.co/chenbhao/codev/resolve/afbc7edaae4e6bb0102ba024b49ce8be89d2264c/src/server/__tests__/proxy-network-settings.test.ts
- Command line
-
hf download hf://chenbhao/codev@afbc7edaae4e6bb0102ba024b49ce8be89d2264c/src/server/__tests__/proxy-network-settings.test.ts
-
curl -L -o proxy-network-settings.test.ts https://huggingface.co/chenbhao/codev/resolve/afbc7edaae4e6bb0102ba024b49ce8be89d2264c/src/server/__tests__/proxy-network-settings.test.ts
7.55 kB
| import { afterEach, beforeEach, describe, expect, mock, test } from 'bun:test' | |
| import * as fs from 'fs/promises' | |
| import * as os from 'os' | |
| import * as path from 'path' | |
| import { handleProxyRequest } from '../proxy/handler.js' | |
| import { ProviderService } from '../services/providerService.js' | |
| import { resetSettingsCache } from '../../utils/settings/settingsCache.js' | |
| let tmpDir: string | |
| let originalConfigDir: string | undefined | |
| async function setup() { | |
| tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'proxy-network-test-')) | |
| originalConfigDir = process.env.CLAUDE_CONFIG_DIR | |
| process.env.CLAUDE_CONFIG_DIR = tmpDir | |
| resetSettingsCache() | |
| } | |
| async function teardown() { | |
| if (originalConfigDir !== undefined) { | |
| process.env.CLAUDE_CONFIG_DIR = originalConfigDir | |
| } else { | |
| delete process.env.CLAUDE_CONFIG_DIR | |
| } | |
| resetSettingsCache() | |
| await fs.rm(tmpDir, { recursive: true, force: true }) | |
| } | |
| describe('proxy network settings', () => { | |
| beforeEach(setup) | |
| afterEach(teardown) | |
| test('uses configured AI request timeout for non-stream upstream requests', async () => { | |
| await fs.writeFile( | |
| path.join(tmpDir, 'settings.json'), | |
| JSON.stringify({ | |
| network: { | |
| aiRequestTimeoutMs: 45_000, | |
| proxy: { mode: 'system', url: '' }, | |
| }, | |
| }), | |
| 'utf-8', | |
| ) | |
| const svc = new ProviderService() | |
| const provider = await svc.addProvider({ | |
| presetId: 'custom', | |
| name: 'OpenAI Proxy', | |
| baseUrl: 'https://api.example.com', | |
| apiKey: 'sk-test', | |
| apiFormat: 'openai_chat', | |
| models: { | |
| main: 'model-main', | |
| haiku: 'model-main', | |
| sonnet: 'model-main', | |
| opus: 'model-main', | |
| }, | |
| }) | |
| const originalFetch = globalThis.fetch | |
| const originalTimeout = AbortSignal.timeout | |
| const timeoutCalls: number[] = [] | |
| globalThis.fetch = mock(async (_url: string | URL | Request, _init?: RequestInit) => { | |
| return new Response(JSON.stringify({ | |
| id: 'chatcmpl-network-timeout', | |
| object: 'chat.completion', | |
| created: 0, | |
| model: 'model-main', | |
| choices: [{ | |
| index: 0, | |
| message: { role: 'assistant', content: 'ok' }, | |
| finish_reason: 'stop', | |
| }], | |
| usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 }, | |
| }), { | |
| status: 200, | |
| headers: { 'Content-Type': 'application/json' }, | |
| }) | |
| }) as typeof fetch | |
| AbortSignal.timeout = ((ms: number) => { | |
| timeoutCalls.push(ms) | |
| return originalTimeout(ms) | |
| }) as typeof AbortSignal.timeout | |
| try { | |
| const body = { | |
| model: 'model-main', | |
| max_tokens: 64, | |
| messages: [{ role: 'user', content: 'hello' }], | |
| } | |
| const req = new Request( | |
| `http://localhost:3456/proxy/providers/${provider.id}/v1/messages`, | |
| { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify(body), | |
| }, | |
| ) | |
| const res = await handleProxyRequest(req, new URL(req.url)) | |
| expect(res.status).toBe(200) | |
| expect(timeoutCalls).toEqual([45_000]) | |
| } finally { | |
| AbortSignal.timeout = originalTimeout | |
| globalThis.fetch = originalFetch | |
| } | |
| }) | |
| test('uses configured AI request timeout for non-stream Responses upstream requests', async () => { | |
| await fs.writeFile( | |
| path.join(tmpDir, 'settings.json'), | |
| JSON.stringify({ | |
| network: { | |
| aiRequestTimeoutMs: 45_000, | |
| proxy: { mode: 'system', url: '' }, | |
| }, | |
| }), | |
| 'utf-8', | |
| ) | |
| const svc = new ProviderService() | |
| const provider = await svc.addProvider({ | |
| presetId: 'custom', | |
| name: 'OpenAI Responses Proxy', | |
| baseUrl: 'https://api.example.com', | |
| apiKey: 'sk-test', | |
| apiFormat: 'openai_responses', | |
| models: { | |
| main: 'model-main', | |
| haiku: 'model-main', | |
| sonnet: 'model-main', | |
| opus: 'model-main', | |
| }, | |
| }) | |
| const originalFetch = globalThis.fetch | |
| const originalTimeout = AbortSignal.timeout | |
| const timeoutCalls: number[] = [] | |
| globalThis.fetch = mock(async (_url: string | URL | Request, _init?: RequestInit) => { | |
| return new Response(JSON.stringify({ | |
| id: 'resp-network-timeout', | |
| status: 'completed', | |
| model: 'model-main', | |
| output: [{ | |
| type: 'message', | |
| content: [{ type: 'output_text', text: 'ok' }], | |
| }], | |
| usage: { input_tokens: 1, output_tokens: 1 }, | |
| }), { | |
| status: 200, | |
| headers: { 'Content-Type': 'application/json' }, | |
| }) | |
| }) as typeof fetch | |
| AbortSignal.timeout = ((ms: number) => { | |
| timeoutCalls.push(ms) | |
| return originalTimeout(ms) | |
| }) as typeof AbortSignal.timeout | |
| try { | |
| const body = { | |
| model: 'model-main', | |
| max_tokens: 64, | |
| messages: [{ role: 'user', content: 'hello' }], | |
| } | |
| const req = new Request( | |
| `http://localhost:3456/proxy/providers/${provider.id}/v1/messages`, | |
| { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify(body), | |
| }, | |
| ) | |
| const res = await handleProxyRequest(req, new URL(req.url)) | |
| expect(res.status).toBe(200) | |
| expect(timeoutCalls).toEqual([45_000]) | |
| } finally { | |
| AbortSignal.timeout = originalTimeout | |
| globalThis.fetch = originalFetch | |
| } | |
| }) | |
| test('uses configured AI request timeout for streaming upstream requests', async () => { | |
| await fs.writeFile( | |
| path.join(tmpDir, 'settings.json'), | |
| JSON.stringify({ | |
| network: { | |
| aiRequestTimeoutMs: 180_000, | |
| proxy: { mode: 'system', url: '' }, | |
| }, | |
| }), | |
| 'utf-8', | |
| ) | |
| const svc = new ProviderService() | |
| const provider = await svc.addProvider({ | |
| presetId: 'custom', | |
| name: 'OpenAI Proxy', | |
| baseUrl: 'https://api.example.com', | |
| apiKey: 'sk-test', | |
| apiFormat: 'openai_chat', | |
| models: { | |
| main: 'model-main', | |
| haiku: 'model-main', | |
| sonnet: 'model-main', | |
| opus: 'model-main', | |
| }, | |
| }) | |
| const originalFetch = globalThis.fetch | |
| const originalTimeout = AbortSignal.timeout | |
| const timeoutCalls: number[] = [] | |
| globalThis.fetch = mock(async (_url: string | URL | Request, _init?: RequestInit) => { | |
| return new Response( | |
| new ReadableStream({ | |
| start(controller) { | |
| controller.enqueue(new TextEncoder().encode('data: [DONE]\n\n')) | |
| controller.close() | |
| }, | |
| }), | |
| { | |
| status: 200, | |
| headers: { 'Content-Type': 'text/event-stream' }, | |
| }, | |
| ) | |
| }) as typeof fetch | |
| AbortSignal.timeout = ((ms: number) => { | |
| timeoutCalls.push(ms) | |
| return originalTimeout(ms) | |
| }) as typeof AbortSignal.timeout | |
| try { | |
| const body = { | |
| model: 'model-main', | |
| max_tokens: 64, | |
| stream: true, | |
| messages: [{ role: 'user', content: 'hello' }], | |
| } | |
| const req = new Request( | |
| `http://localhost:3456/proxy/providers/${provider.id}/v1/messages`, | |
| { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify(body), | |
| }, | |
| ) | |
| const res = await handleProxyRequest(req, new URL(req.url)) | |
| expect(res.status).toBe(200) | |
| expect(timeoutCalls).toEqual([180_000]) | |
| } finally { | |
| AbortSignal.timeout = originalTimeout | |
| globalThis.fetch = originalFetch | |
| } | |
| }) | |
| }) | |