|
|
|
|
@ -0,0 +1,185 @@
|
|
|
|
|
/**
|
|
|
|
|
* CNC 采集服务 Playwright 端到端测试
|
|
|
|
|
*
|
|
|
|
|
* 前置条件:
|
|
|
|
|
* 1. MariaDB 运行中(cnc_business + cnc_log 库已初始化)
|
|
|
|
|
* 2. CncSimulator 运行在 http://localhost:9001/
|
|
|
|
|
* 3. CncCollector 运行中,管理API在 http://localhost:5800/
|
|
|
|
|
*
|
|
|
|
|
* 安装: npm init -y && npm install @playwright/test
|
|
|
|
|
* 运行: npx playwright test e2e-collector.spec.ts --reporter=list
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { test, expect, request } from '@playwright/test';
|
|
|
|
|
|
|
|
|
|
const API_BASE = 'http://localhost:5800';
|
|
|
|
|
const API_KEY = 'collector_api_key_2026';
|
|
|
|
|
const HEADERS = { 'X-API-Key': API_KEY, 'Content-Type': 'application/json' };
|
|
|
|
|
|
|
|
|
|
// ============================================================
|
|
|
|
|
// 测试套件1: 采集服务管理API控制测试
|
|
|
|
|
// ============================================================
|
|
|
|
|
test.describe('采集服务管理API控制测试', () => {
|
|
|
|
|
|
|
|
|
|
test('GET /api/collector/status - 获取服务状态', async () => {
|
|
|
|
|
const ctx = await request.newContext();
|
|
|
|
|
const resp = await ctx.get(`${API_BASE}/api/collector/status`, { headers: HEADERS });
|
|
|
|
|
|
|
|
|
|
expect(resp.status()).toBe(200);
|
|
|
|
|
const body = await resp.json();
|
|
|
|
|
|
|
|
|
|
expect(body.code).toBe(0);
|
|
|
|
|
expect(body.data).toBeDefined();
|
|
|
|
|
expect(body.data).toHaveProperty('isRunning');
|
|
|
|
|
expect(body.data).toHaveProperty('startTime');
|
|
|
|
|
expect(body.data).toHaveProperty('uptimeSeconds');
|
|
|
|
|
expect(body.data).toHaveProperty('workerCount');
|
|
|
|
|
expect(body.data).toHaveProperty('workers');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('GET /api/collector/status - 无API Key返回401', async () => {
|
|
|
|
|
const ctx = await request.newContext();
|
|
|
|
|
const resp = await ctx.get(`${API_BASE}/api/collector/status`);
|
|
|
|
|
|
|
|
|
|
expect(resp.status()).toBe(401);
|
|
|
|
|
const body = await resp.json();
|
|
|
|
|
expect(body.code).toBe(40101);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('GET /api/collector/status - 错误API Key返回401', async () => {
|
|
|
|
|
const ctx = await request.newContext();
|
|
|
|
|
const resp = await ctx.get(`${API_BASE}/api/collector/status`, {
|
|
|
|
|
headers: { 'X-API-Key': 'wrong_key' }
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(resp.status()).toBe(401);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('POST /api/collector/refresh - 刷新配置', async () => {
|
|
|
|
|
const ctx = await request.newContext();
|
|
|
|
|
const resp = await ctx.post(`${API_BASE}/api/collector/refresh`, { headers: HEADERS });
|
|
|
|
|
|
|
|
|
|
expect(resp.status()).toBe(200);
|
|
|
|
|
const body = await resp.json();
|
|
|
|
|
expect(body.code).toBe(0);
|
|
|
|
|
expect(body.data.message).toContain('刷新');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('POST /api/collector/stop - 停止采集服务', async () => {
|
|
|
|
|
const ctx = await request.newContext();
|
|
|
|
|
const resp = await ctx.post(`${API_BASE}/api/collector/stop`, { headers: HEADERS });
|
|
|
|
|
|
|
|
|
|
expect(resp.status()).toBe(200);
|
|
|
|
|
const body = await resp.json();
|
|
|
|
|
expect(body.code).toBe(0);
|
|
|
|
|
|
|
|
|
|
// 验证状态变为停止
|
|
|
|
|
const statusResp = await ctx.get(`${API_BASE}/api/collector/status`, { headers: HEADERS });
|
|
|
|
|
const statusBody = await statusResp.json();
|
|
|
|
|
expect(statusBody.data.isRunning).toBe(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('POST /api/collector/start - 启动采集服务', async () => {
|
|
|
|
|
const ctx = await request.newContext();
|
|
|
|
|
const resp = await ctx.post(`${API_BASE}/api/collector/start`, { headers: HEADERS });
|
|
|
|
|
|
|
|
|
|
expect(resp.status()).toBe(200);
|
|
|
|
|
const body = await resp.json();
|
|
|
|
|
expect(body.code).toBe(0);
|
|
|
|
|
|
|
|
|
|
// 等待启动
|
|
|
|
|
await new Promise(r => setTimeout(r, 2000));
|
|
|
|
|
|
|
|
|
|
// 验证状态变为运行
|
|
|
|
|
const statusResp = await ctx.get(`${API_BASE}/api/collector/status`, { headers: HEADERS });
|
|
|
|
|
const statusBody = await statusResp.json();
|
|
|
|
|
expect(statusBody.data.isRunning).toBe(true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('未知端点返回404', async () => {
|
|
|
|
|
const ctx = await request.newContext();
|
|
|
|
|
const resp = await ctx.get(`${API_BASE}/api/collector/nonexistent`, { headers: HEADERS });
|
|
|
|
|
|
|
|
|
|
expect(resp.status()).toBe(404);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// ============================================================
|
|
|
|
|
// 测试套件2: 采集数据流程验证
|
|
|
|
|
// ============================================================
|
|
|
|
|
test.describe('采集数据流程验证', () => {
|
|
|
|
|
|
|
|
|
|
test('采集服务启动后工作线程数 > 0', async () => {
|
|
|
|
|
const ctx = await request.newContext();
|
|
|
|
|
|
|
|
|
|
// 确保启动
|
|
|
|
|
await ctx.post(`${API_BASE}/api/collector/start`, { headers: HEADERS });
|
|
|
|
|
await new Promise(r => setTimeout(r, 3000));
|
|
|
|
|
|
|
|
|
|
const resp = await ctx.get(`${API_BASE}/api/collector/status`, { headers: HEADERS });
|
|
|
|
|
const body = await resp.json();
|
|
|
|
|
|
|
|
|
|
expect(body.data.isRunning).toBe(true);
|
|
|
|
|
expect(body.data.workerCount).toBeGreaterThanOrEqual(0);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('采集服务运行时间持续增长', async () => {
|
|
|
|
|
const ctx = await request.newContext();
|
|
|
|
|
|
|
|
|
|
await ctx.post(`${API_BASE}/api/collector/start`, { headers: HEADERS });
|
|
|
|
|
await new Promise(r => setTimeout(r, 2000));
|
|
|
|
|
|
|
|
|
|
const resp1 = await ctx.get(`${API_BASE}/api/collector/status`, { headers: HEADERS });
|
|
|
|
|
const body1 = await resp1.json();
|
|
|
|
|
const uptime1 = body1.data.uptimeSeconds;
|
|
|
|
|
|
|
|
|
|
await new Promise(r => setTimeout(r, 3000));
|
|
|
|
|
|
|
|
|
|
const resp2 = await ctx.get(`${API_BASE}/api/collector/status`, { headers: HEADERS });
|
|
|
|
|
const body2 = await resp2.json();
|
|
|
|
|
const uptime2 = body2.data.uptimeSeconds;
|
|
|
|
|
|
|
|
|
|
expect(uptime2).toBeGreaterThanOrEqual(uptime1);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('停止后再启动,状态正确切换', async () => {
|
|
|
|
|
const ctx = await request.newContext();
|
|
|
|
|
|
|
|
|
|
// 停止
|
|
|
|
|
await ctx.post(`${API_BASE}/api/collector/stop`, { headers: HEADERS });
|
|
|
|
|
await new Promise(r => setTimeout(r, 1000));
|
|
|
|
|
|
|
|
|
|
let statusResp = await ctx.get(`${API_BASE}/api/collector/status`, { headers: HEADERS });
|
|
|
|
|
let statusBody = await statusResp.json();
|
|
|
|
|
expect(statusBody.data.isRunning).toBe(false);
|
|
|
|
|
|
|
|
|
|
// 启动
|
|
|
|
|
await ctx.post(`${API_BASE}/api/collector/start`, { headers: HEADERS });
|
|
|
|
|
await new Promise(r => setTimeout(r, 2000));
|
|
|
|
|
|
|
|
|
|
statusResp = await ctx.get(`${API_BASE}/api/collector/status`, { headers: HEADERS });
|
|
|
|
|
statusBody = await statusResp.json();
|
|
|
|
|
expect(statusBody.data.isRunning).toBe(true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('工作线程状态包含预期字段', async () => {
|
|
|
|
|
const ctx = await request.newContext();
|
|
|
|
|
|
|
|
|
|
await ctx.post(`${API_BASE}/api/collector/start`, { headers: HEADERS });
|
|
|
|
|
await new Promise(r => setTimeout(r, 3000));
|
|
|
|
|
|
|
|
|
|
const resp = await ctx.get(`${API_BASE}/api/collector/status`, { headers: HEADERS });
|
|
|
|
|
const body = await resp.json();
|
|
|
|
|
|
|
|
|
|
if (body.data.workerCount > 0) {
|
|
|
|
|
const workers = body.data.workers;
|
|
|
|
|
expect(Array.isArray(workers)).toBe(true);
|
|
|
|
|
if (workers.length > 0) {
|
|
|
|
|
const w = workers[0];
|
|
|
|
|
expect(w).toHaveProperty('addressId');
|
|
|
|
|
expect(w).toHaveProperty('url');
|
|
|
|
|
expect(w).toHaveProperty('isRunning');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|