mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
feat(tests): move SDK integration tests to integration-tests to share globalSetup
This commit is contained in:
@@ -238,7 +238,7 @@ export default tseslint.config(
|
||||
prettierConfig,
|
||||
// extra settings for scripts that we run directly with node
|
||||
{
|
||||
files: ['./integration-tests/**/*.js'],
|
||||
files: ['./integration-tests/**/*.{js,ts,tsx}'],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* Copyright 2025 Qwen Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
@@ -30,6 +30,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const rootDir = join(__dirname, '..');
|
||||
const integrationTestsDir = join(rootDir, '.integration-tests');
|
||||
let runDir = ''; // Make runDir accessible in teardown
|
||||
let sdkE2eRunDir = ''; // SDK E2E test run directory
|
||||
|
||||
const memoryFilePath = join(
|
||||
os.homedir(),
|
||||
@@ -48,14 +49,36 @@ export async function setup() {
|
||||
// File doesn't exist, which is fine.
|
||||
}
|
||||
|
||||
// Setup for CLI integration tests
|
||||
runDir = join(integrationTestsDir, `${Date.now()}`);
|
||||
await mkdir(runDir, { recursive: true });
|
||||
|
||||
// Setup for SDK E2E tests (separate directory with prefix)
|
||||
sdkE2eRunDir = join(integrationTestsDir, `sdk-e2e-${Date.now()}`);
|
||||
await mkdir(sdkE2eRunDir, { recursive: true });
|
||||
|
||||
// Clean up old test runs, but keep the latest few for debugging
|
||||
try {
|
||||
const testRuns = await readdir(integrationTestsDir);
|
||||
if (testRuns.length > 5) {
|
||||
const oldRuns = testRuns.sort().slice(0, testRuns.length - 5);
|
||||
|
||||
// Clean up old CLI integration test runs (without sdk-e2e- prefix)
|
||||
const cliTestRuns = testRuns.filter((run) => !run.startsWith('sdk-e2e-'));
|
||||
if (cliTestRuns.length > 5) {
|
||||
const oldRuns = cliTestRuns.sort().slice(0, cliTestRuns.length - 5);
|
||||
await Promise.all(
|
||||
oldRuns.map((oldRun) =>
|
||||
rm(join(integrationTestsDir, oldRun), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Clean up old SDK E2E test runs (with sdk-e2e- prefix)
|
||||
const sdkTestRuns = testRuns.filter((run) => run.startsWith('sdk-e2e-'));
|
||||
if (sdkTestRuns.length > 5) {
|
||||
const oldRuns = sdkTestRuns.sort().slice(0, sdkTestRuns.length - 5);
|
||||
await Promise.all(
|
||||
oldRuns.map((oldRun) =>
|
||||
rm(join(integrationTestsDir, oldRun), {
|
||||
@@ -69,24 +92,37 @@ export async function setup() {
|
||||
console.error('Error cleaning up old test runs:', e);
|
||||
}
|
||||
|
||||
// Environment variables for CLI integration tests
|
||||
process.env['INTEGRATION_TEST_FILE_DIR'] = runDir;
|
||||
process.env['GEMINI_CLI_INTEGRATION_TEST'] = 'true';
|
||||
process.env['TELEMETRY_LOG_FILE'] = join(runDir, 'telemetry.log');
|
||||
|
||||
// Environment variables for SDK E2E tests
|
||||
process.env['E2E_TEST_FILE_DIR'] = sdkE2eRunDir;
|
||||
process.env['TEST_CLI_PATH'] = join(rootDir, 'dist/cli.js');
|
||||
|
||||
if (process.env['KEEP_OUTPUT']) {
|
||||
console.log(`Keeping output for test run in: ${runDir}`);
|
||||
console.log(`Keeping output for SDK E2E test run in: ${sdkE2eRunDir}`);
|
||||
}
|
||||
process.env['VERBOSE'] = process.env['VERBOSE'] ?? 'false';
|
||||
|
||||
console.log(`\nIntegration test output directory: ${runDir}`);
|
||||
console.log(`SDK E2E test output directory: ${sdkE2eRunDir}`);
|
||||
console.log(`CLI path: ${process.env['TEST_CLI_PATH']}`);
|
||||
}
|
||||
|
||||
export async function teardown() {
|
||||
// Cleanup the test run directory unless KEEP_OUTPUT is set
|
||||
// Cleanup the CLI test run directory unless KEEP_OUTPUT is set
|
||||
if (process.env['KEEP_OUTPUT'] !== 'true' && runDir) {
|
||||
await rm(runDir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
// Cleanup the SDK E2E test run directory unless KEEP_OUTPUT is set
|
||||
if (process.env['KEEP_OUTPUT'] !== 'true' && sdkE2eRunDir) {
|
||||
await rm(sdkE2eRunDir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
if (originalMemoryContent !== null) {
|
||||
await mkdir(dirname(memoryFilePath), { recursive: true });
|
||||
await writeFile(memoryFilePath, originalMemoryContent, 'utf-8');
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
isSDKAssistantMessage,
|
||||
type TextBlock,
|
||||
type ContentBlock,
|
||||
} from '../../src/index.js';
|
||||
} from '@qwen-code/sdk-typescript';
|
||||
import { SDKTestHelper, createSharedTestOptions } from './test-helper.js';
|
||||
|
||||
const SHARED_TEST_OPTIONS = createSharedTestOptions();
|
||||
@@ -12,12 +12,12 @@
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { query } from '../../src/index.js';
|
||||
import {
|
||||
query,
|
||||
isSDKAssistantMessage,
|
||||
isSDKSystemMessage,
|
||||
type SDKMessage,
|
||||
} from '../../src/types/protocol.js';
|
||||
} from '@qwen-code/sdk-typescript';
|
||||
import {
|
||||
SDKTestHelper,
|
||||
extractText,
|
||||
@@ -10,8 +10,8 @@
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { query } from '../../src/index.js';
|
||||
import {
|
||||
query,
|
||||
isSDKAssistantMessage,
|
||||
isSDKResultMessage,
|
||||
isSDKSystemMessage,
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
type SDKMessage,
|
||||
type ToolUseBlock,
|
||||
type SDKSystemMessage,
|
||||
} from '../../src/types/protocol.js';
|
||||
} from '@qwen-code/sdk-typescript';
|
||||
import {
|
||||
SDKTestHelper,
|
||||
createMCPServer,
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { query } from '../../src/index.js';
|
||||
import {
|
||||
query,
|
||||
isSDKUserMessage,
|
||||
isSDKAssistantMessage,
|
||||
isSDKSystemMessage,
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
type SDKMessage,
|
||||
type ControlMessage,
|
||||
type ToolUseBlock,
|
||||
} from '../../src/types/protocol.js';
|
||||
} from '@qwen-code/sdk-typescript';
|
||||
import { SDKTestHelper, createSharedTestOptions } from './test-helper.js';
|
||||
|
||||
const SHARED_TEST_OPTIONS = createSharedTestOptions();
|
||||
@@ -13,8 +13,8 @@ import {
|
||||
beforeEach,
|
||||
afterEach,
|
||||
} from 'vitest';
|
||||
import { query } from '../../src/index.js';
|
||||
import {
|
||||
query,
|
||||
isSDKAssistantMessage,
|
||||
isSDKResultMessage,
|
||||
isSDKUserMessage,
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
type SDKUserMessage,
|
||||
type ToolUseBlock,
|
||||
type ContentBlock,
|
||||
} from '../../src/types/protocol.js';
|
||||
} from '@qwen-code/sdk-typescript';
|
||||
import {
|
||||
SDKTestHelper,
|
||||
createSharedTestOptions,
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { query } from '../../src/index.js';
|
||||
import {
|
||||
query,
|
||||
isSDKAssistantMessage,
|
||||
isSDKSystemMessage,
|
||||
isSDKResultMessage,
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
type SDKMessage,
|
||||
type SDKSystemMessage,
|
||||
type SDKAssistantMessage,
|
||||
} from '../../src/types/protocol.js';
|
||||
} from '@qwen-code/sdk-typescript';
|
||||
import {
|
||||
SDKTestHelper,
|
||||
extractText,
|
||||
@@ -10,14 +10,14 @@
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { query } from '../../src/index.js';
|
||||
import {
|
||||
query,
|
||||
isSDKAssistantMessage,
|
||||
type SDKMessage,
|
||||
type SubagentConfig,
|
||||
type ContentBlock,
|
||||
type ToolUseBlock,
|
||||
} from '../../src/types/protocol.js';
|
||||
} from '@qwen-code/sdk-typescript';
|
||||
import {
|
||||
SDKTestHelper,
|
||||
extractText,
|
||||
@@ -4,12 +4,12 @@
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { query } from '../../src/index.js';
|
||||
import {
|
||||
query,
|
||||
isSDKAssistantMessage,
|
||||
isSDKSystemMessage,
|
||||
type SDKUserMessage,
|
||||
} from '../../src/types/protocol.js';
|
||||
} from '@qwen-code/sdk-typescript';
|
||||
import { SDKTestHelper, createSharedTestOptions } from './test-helper.js';
|
||||
|
||||
const SHARED_TEST_OPTIONS = createSharedTestOptions();
|
||||
@@ -265,7 +265,7 @@ describe('System Control (E2E)', () => {
|
||||
|
||||
// First model change
|
||||
await q.setModel('qwen3-turbo');
|
||||
resumeResolve1?.();
|
||||
resumeResolve1!();
|
||||
|
||||
// Wait for second response
|
||||
await Promise.race([
|
||||
@@ -277,7 +277,7 @@ describe('System Control (E2E)', () => {
|
||||
|
||||
// Second model change
|
||||
await q.setModel('qwen3-vl-plus');
|
||||
resumeResolve2?.();
|
||||
resumeResolve2!();
|
||||
|
||||
// Wait for third response
|
||||
await Promise.race([
|
||||
@@ -21,12 +21,12 @@ import type {
|
||||
ContentBlock,
|
||||
TextBlock,
|
||||
ToolUseBlock,
|
||||
} from '../../src/types/protocol.js';
|
||||
} from '@qwen-code/sdk-typescript';
|
||||
import {
|
||||
isSDKAssistantMessage,
|
||||
isSDKSystemMessage,
|
||||
isSDKResultMessage,
|
||||
} from '../../src/types/protocol.js';
|
||||
} from '@qwen-code/sdk-typescript';
|
||||
|
||||
// ============================================================================
|
||||
// Core Test Helper Class
|
||||
@@ -12,11 +12,11 @@
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { query } from '../../src/index.js';
|
||||
import {
|
||||
query,
|
||||
isSDKAssistantMessage,
|
||||
type SDKMessage,
|
||||
} from '../../src/types/protocol.js';
|
||||
} from '@qwen-code/sdk-typescript';
|
||||
import {
|
||||
SDKTestHelper,
|
||||
extractText,
|
||||
@@ -2,7 +2,13 @@
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"allowJs": true
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@qwen-code/sdk-typescript": [
|
||||
"../packages/sdk-typescript/dist/index.d.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": ["**/*.ts"],
|
||||
"references": [{ "path": "../packages/core" }]
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* Copyright 2025 Qwen Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const timeoutMinutes = Number(process.env.TB_TIMEOUT_MINUTES || '5');
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const timeoutMinutes = Number(process.env['TB_TIMEOUT_MINUTES'] || '5');
|
||||
const testTimeoutMs = timeoutMinutes * 60 * 1000;
|
||||
|
||||
export default defineConfig({
|
||||
@@ -25,4 +28,13 @@ export default defineConfig({
|
||||
},
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
// Use built SDK bundle for e2e tests
|
||||
'@qwen-code/sdk-typescript': resolve(
|
||||
__dirname,
|
||||
'../packages/sdk-typescript/dist/index.mjs',
|
||||
),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"scripts": {
|
||||
"build": "node scripts/build.js",
|
||||
"test": "vitest run",
|
||||
"test:ci": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
"test:coverage": "vitest run --coverage",
|
||||
"lint": "eslint src test",
|
||||
|
||||
@@ -18,6 +18,14 @@ export type {
|
||||
SDKResultMessage,
|
||||
SDKPartialAssistantMessage,
|
||||
SDKMessage,
|
||||
ControlMessage,
|
||||
CLIControlRequest,
|
||||
CLIControlResponse,
|
||||
ControlCancelRequest,
|
||||
SubagentConfig,
|
||||
SubagentLevel,
|
||||
ModelConfig,
|
||||
RunConfig,
|
||||
} from './types/protocol.js';
|
||||
|
||||
export {
|
||||
@@ -26,6 +34,9 @@ export {
|
||||
isSDKSystemMessage,
|
||||
isSDKResultMessage,
|
||||
isSDKPartialAssistantMessage,
|
||||
isControlRequest,
|
||||
isControlResponse,
|
||||
isControlCancel,
|
||||
} from './types/protocol.js';
|
||||
|
||||
export type {
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Qwen Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { mkdir, readdir, rm } from 'node:fs/promises';
|
||||
import { join, dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const rootDir = join(__dirname, '../..');
|
||||
const e2eTestsDir = join(rootDir, '.integration-tests');
|
||||
let runDir = '';
|
||||
|
||||
export async function setup() {
|
||||
runDir = join(e2eTestsDir, `sdk-e2e-${Date.now()}`);
|
||||
await mkdir(runDir, { recursive: true });
|
||||
|
||||
// Clean up old test runs, but keep the latest few for debugging
|
||||
try {
|
||||
const testRuns = await readdir(e2eTestsDir);
|
||||
const sdkTestRuns = testRuns.filter((run) => run.startsWith('sdk-e2e-'));
|
||||
if (sdkTestRuns.length > 5) {
|
||||
const oldRuns = sdkTestRuns.sort().slice(0, sdkTestRuns.length - 5);
|
||||
await Promise.all(
|
||||
oldRuns.map((oldRun) =>
|
||||
rm(join(e2eTestsDir, oldRun), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error cleaning up old test runs:', e);
|
||||
}
|
||||
|
||||
process.env['E2E_TEST_FILE_DIR'] = runDir;
|
||||
process.env['QWEN_CLI_E2E_TEST'] = 'true';
|
||||
process.env['TEST_CLI_PATH'] = join(rootDir, '../../dist/cli.js');
|
||||
|
||||
if (process.env['KEEP_OUTPUT']) {
|
||||
console.log(`Keeping output for test run in: ${runDir}`);
|
||||
}
|
||||
process.env['VERBOSE'] = process.env['VERBOSE'] ?? 'false';
|
||||
|
||||
console.log(`\nSDK E2E test output directory: ${runDir}`);
|
||||
console.log(`CLI path: ${process.env['TEST_CLI_PATH']}`);
|
||||
}
|
||||
|
||||
export async function teardown() {
|
||||
// Cleanup the test run directory unless KEEP_OUTPUT is set
|
||||
if (process.env['KEEP_OUTPUT'] !== 'true' && runDir) {
|
||||
await rm(runDir, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user