#!/usr/bin/env node
/**
* 测试配置文件验证脚本
* 验证YAML配置文件的语法和结构正确性
*/
const fs = require('fs');
const path = require('path');
// 尝试加载YAML解析器
let yaml;
try {
yaml = require('js-yaml');
} catch (error) {
console.error('❌ js-yaml 未安装,请运行: npm install js-yaml');
process.exit(1);
}
// 配置文件路径
const CONFIGS = {
serverConfig: path.join(__dirname, '../tests/zendao-server-config.json'),
toolTests: path.join(__dirname, '../tests/zendao-tool-tests.yaml'),
evalTests: path.join(__dirname, '../tests/zendao-eval-tests.yaml'),
unifiedTests: path.join(__dirname, '../tests/zendao-unified-tests.yaml'),
};
// 颜色输出
const colors = {
reset: '\x1b[0m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
};
function colorLog(color, message) {
console.log(`${colors[color]}${message}${colors.reset}`);
}
function success(message) {
console.log(`${colors.green}✅ ${message}${colors.reset}`);
}
function error(message) {
console.log(`${colors.red}❌ ${message}${colors.reset}`);
}
function warning(message) {
console.log(`${colors.yellow}⚠️ ${message}${colors.reset}`);
}
function info(message) {
console.log(`${colors.blue}ℹ️ ${message}${colors.reset}`);
}
// 验证JSON文件
function validateJsonFile(filePath, schema = {}) {
try {
const content = fs.readFileSync(filePath, 'utf8');
const data = JSON.parse(content);
return { valid: true, data };
} catch (error) {
return {
valid: false,
error: error.message
};
}
}
// 验证YAML文件
function validateYamlFile(filePath, schema = {}) {
try {
const content = fs.readFileSync(filePath, 'utf8');
const data = yaml.load(content);
return { valid: true, data };
} catch (error) {
return {
valid: false,
error: error.message
};
}
}
// 验证服务器配置结构
function validateServerConfig(data) {
const errors = [];
if (!data.mcpServers) {
errors.push('缺少 mcpServers 字段');
return errors;
}
const servers = data.mcpServers;
if (typeof servers !== 'object' || Array.isArray(servers)) {
errors.push('mcpServers 必须是对象');
return errors;
}
for (const [name, config] of Object.entries(servers)) {
if (!config.command) {
errors.push(`服务器 ${name} 缺少 command 字段`);
}
if (!Array.isArray(config.args)) {
errors.push(`服务器 ${name} 的 args 必须是数组`);
}
}
return errors;
}
// 验证工具测试配置结构
function validateToolTests(data) {
const errors = [];
if (!data.tests) {
errors.push('缺少 tests 字段');
return errors;
}
if (!Array.isArray(data.tests)) {
errors.push('tests 必须是数组');
return errors;
}
data.tests.forEach((test, index) => {
if (!test.name) {
errors.push(`测试 ${index} 缺少 name 字段`);
}
if (!test.tool) {
errors.push(`测试 ${index} 缺少 tool 字段`);
}
if (!test.params) {
errors.push(`测试 ${index} 缺少 params 字段`);
}
if (!test.expect) {
errors.push(`测试 ${index} 缺少 expect 字段`);
}
});
// 检查是否有expected_tool_list
if (data.expected_tool_list && !Array.isArray(data.expected_tool_list)) {
errors.push('expected_tool_list 必须是数组');
}
return errors;
}
// 验证评估测试配置结构
function validateEvalTests(data) {
const errors = [];
if (!data.models) {
errors.push('缺少 models 字段');
} else if (!Array.isArray(data.models)) {
errors.push('models 必须是数组');
}
if (!data.tests) {
errors.push('缺少 tests 字段');
} else if (!Array.isArray(data.tests)) {
errors.push('tests 必须是数组');
}
data.tests.forEach((test, index) => {
if (!test.name) {
errors.push(`评估测试 ${index} 缺少 name 字段`);
}
if (!test.prompt) {
errors.push(`评估测试 ${index} 缺少 prompt 字段`);
}
});
return errors;
}
// 主验证函数
function validateAllConfigs() {
console.log('🔍 验证测试配置文件\n');
let allValid = true;
const results = [];
// 验证服务器配置
info('验证服务器配置...');
const serverResult = validateJsonFile(CONFIGS.serverConfig);
if (serverResult.valid) {
const serverErrors = validateServerConfig(serverResult.data);
if (serverErrors.length === 0) {
success('服务器配置格式正确');
} else {
allValid = false;
serverErrors.forEach(error => error(`服务器配置错误: ${error}`));
}
} else {
allValid = false;
error(`服务器配置JSON解析失败: ${serverResult.error}`);
}
// 验证工具测试配置
info('验证工具测试配置...');
const toolsResult = validateYamlFile(CONFIGS.toolTests);
if (toolsResult.valid) {
const toolsErrors = validateToolTests(toolsResult.data);
if (toolsErrors.length === 0) {
success('工具测试配置格式正确');
} else {
allValid = false;
toolsErrors.forEach(error => error(`工具测试配置错误: ${error}`));
}
} else {
allValid = false;
error(`工具测试配置YAML解析失败: ${toolsResult.error}`);
}
// 验证评估测试配置
info('验证评估测试配置...');
const evalsResult = validateYamlFile(CONFIGS.evalTests);
if (evalsResult.valid) {
const evalsErrors = validateEvalTests(evalsResult.data);
if (evalsErrors.length === 0) {
success('评估测试配置格式正确');
} else {
allValid = false;
evalsErrors.forEach(error => error(`评估测试配置错误: ${error}`));
}
} else {
allValid = false;
error(`评估测试配置YAML解析失败: ${evalsResult.error}`);
}
// 验证统一测试配置
info('验证统一测试配置...');
const unifiedResult = validateYamlFile(CONFIGS.unifiedTests);
if (unifiedResult.valid) {
const unifiedData = unifiedResult.data;
let hasTools = false;
let hasEvals = false;
const unifiedErrors = [];
if (unifiedData.tools) {
hasTools = true;
const toolsErrors = validateToolTests(unifiedData.tools);
unifiedErrors.push(...toolsErrors.map(err => `tools部分: ${err}`));
}
if (unifiedData.evals) {
hasEvals = true;
const evalsErrors = validateEvalTests(unifiedData.evals);
unifiedErrors.push(...evalsErrors.map(err => `evals部分: ${err}`));
}
if (!hasTools && !hasEvals) {
unifiedErrors.push('统一配置必须包含 tools 或 evals 字段');
}
if (unifiedErrors.length === 0) {
success('统一测试配置格式正确');
} else {
allValid = false;
unifiedErrors.forEach(error => error(`统一测试配置错误: ${error}`));
}
} else {
allValid = false;
error(`统一测试配置YAML解析失败: ${unifiedResult.error}`);
}
console.log('\n📊 验证结果总结');
console.log('==================');
if (allValid) {
success('🎉 所有配置文件验证通过!');
console.log('\n✅ 配置文件已准备好,可以运行MCP测试');
console.log('\n🚀 运行测试命令:');
console.log(' node scripts/run-mcp-tests.js tools # 工具测试');
console.log(' node scripts/run-mcp-tests.js evals # LLM评估测试');
console.log(' node scripts/run-mcp-tests.js unified # 统一测试');
console.log(' node scripts/run-mcp-tests.js all # 所有测试');
process.exit(0);
} else {
error('💥 配置文件验证失败!');
console.log('\n❌ 请修复上述错误后重新运行验证');
console.log('\n🔧 修复建议:');
console.log(' 1. 检查JSON/YAML语法是否正确');
console.log(' 2. 确保所有必需字段都存在');
console.log(' 3. 验证字段类型是否正确');
console.log(' 4. 参考mcp-server-tester文档调整配置');
process.exit(1);
}
}
// 检查是否所有文件都存在
function checkFilesExist() {
const missingFiles = [];
for (const [name, path] of Object.entries(CONFIGS)) {
if (!fs.existsSync(path)) {
missingFiles.push(`${name}: ${path}`);
}
}
if (missingFiles.length > 0) {
error('以下配置文件不存在:');
missingFiles.forEach(file => error(` - ${file}`));
return false;
}
return true;
}
// 主函数
function main() {
console.log('🧪 ZenTao MCP 测试配置验证器');
console.log('===============================\n');
if (!checkFilesExist()) {
process.exit(1);
}
validateAllConfigs();
}
// 运行主函数
if (require.main === module) {
main().catch(error => {
error(`验证过程中发生错误: ${error.message}`);
process.exit(1);
});
}