fenghuo/test-minio-config.js

262 lines
7.6 KiB
JavaScript
Raw Normal View History

2025-05-29 11:12:16 +08:00
#!/usr/bin/env node
/**
* MinIO配置测试脚本
* 基于用户提供的具体配置进行测试
*/
const { S3 } = require('@aws-sdk/client-s3');
const fs = require('fs');
const path = require('path');
async function testMinIOConfig() {
console.log('🔍 开始测试MinIO配置...\n');
// 用户提供的配置
const config = {
endpoint: 'http://localhost:9000',
region: 'us-east-1',
credentials: {
accessKeyId: '7Nt7OyHkwIoo3zvSKdnc',
secretAccessKey: 'EZ0cyrjJAsabTLNSqWcU47LURMppBW2kka3LuXzb',
},
forcePathStyle: true,
};
const bucketName = 'test123';
const uploadDir = '/opt/projects/nice/uploads';
console.log('📋 配置信息:');
console.log(` Endpoint: ${config.endpoint}`);
console.log(` Region: ${config.region}`);
console.log(` Bucket: ${bucketName}`);
console.log(` Upload Dir: ${uploadDir}`);
console.log(` Access Key: ${config.credentials.accessKeyId}`);
console.log(` Force Path Style: ${config.forcePathStyle}`);
console.log();
try {
const s3Client = new S3(config);
// 1. 测试基本连接和认证
console.log('📡 测试连接和认证...');
try {
const buckets = await s3Client.listBuckets();
console.log('✅ 连接和认证成功!');
console.log(`📂 现有存储桶: ${buckets.Buckets?.map((b) => b.Name).join(', ') || '无'}`);
} catch (error) {
console.log('❌ 连接失败:', error.message);
if (error.message.includes('ECONNREFUSED')) {
console.log('💡 提示: MinIO服务可能未运行请检查localhost:9000是否可访问');
} else if (error.message.includes('Invalid')) {
console.log('💡 提示: 检查访问密钥和密钥是否正确');
}
return false;
}
// 2. 检查目标存储桶
console.log(`\n🪣 检查存储桶 "${bucketName}"...`);
let bucketExists = false;
try {
await s3Client.headBucket({ Bucket: bucketName });
console.log(`✅ 存储桶 "${bucketName}" 存在并可访问`);
bucketExists = true;
} catch (error) {
if (error.name === 'NotFound') {
console.log(`❌ 存储桶 "${bucketName}" 不存在`);
console.log('🔧 尝试创建存储桶...');
try {
await s3Client.createBucket({ Bucket: bucketName });
console.log(`✅ 存储桶 "${bucketName}" 创建成功`);
bucketExists = true;
} catch (createError) {
console.log(`❌ 创建存储桶失败: ${createError.message}`);
return false;
}
} else {
console.log(`❌ 检查存储桶时出错: ${error.message}`);
return false;
}
}
if (!bucketExists) {
return false;
}
// 3. 检查上传目录
console.log(`\n📁 检查上传目录 "${uploadDir}"...`);
try {
if (!fs.existsSync(uploadDir)) {
console.log('📁 上传目录不存在,正在创建...');
fs.mkdirSync(uploadDir, { recursive: true });
console.log('✅ 上传目录创建成功');
} else {
console.log('✅ 上传目录存在');
}
} catch (error) {
console.log(`❌ 检查/创建上传目录失败: ${error.message}`);
}
// 4. 测试文件上传
console.log('\n📤 测试文件上传...');
const testFileName = `test-upload-${Date.now()}.txt`;
const testContent = `这是一个测试文件
创建时间: ${new Date().toISOString()}
用户: nice1234
MinIO测试成功`;
try {
await s3Client.putObject({
Bucket: bucketName,
Key: testFileName,
Body: testContent,
ContentType: 'text/plain',
Metadata: {
'test-type': 'config-validation',
'created-by': 'test-script',
},
});
console.log(`✅ 文件上传成功: ${testFileName}`);
} catch (error) {
console.log(`❌ 文件上传失败: ${error.message}`);
console.log('错误详情:', error);
return false;
}
// 5. 测试文件下载验证
console.log('\n📥 测试文件下载验证...');
try {
const result = await s3Client.getObject({
Bucket: bucketName,
Key: testFileName,
});
// 读取流内容
const chunks = [];
for await (const chunk of result.Body) {
chunks.push(chunk);
}
const downloadedContent = Buffer.concat(chunks).toString();
if (downloadedContent === testContent) {
console.log('✅ 文件下载验证成功,内容一致');
} else {
console.log('❌ 文件内容不一致');
return false;
}
} catch (error) {
console.log(`❌ 文件下载失败: ${error.message}`);
return false;
}
// 6. 测试分片上传
console.log('\n🔄 测试分片上传功能...');
const multipartKey = `multipart-test-${Date.now()}.dat`;
try {
const multipartUpload = await s3Client.createMultipartUpload({
Bucket: bucketName,
Key: multipartKey,
Metadata: {
'test-type': 'multipart-upload',
},
});
console.log(`✅ 分片上传初始化成功: ${multipartUpload.UploadId}`);
// 清理测试
await s3Client.abortMultipartUpload({
Bucket: bucketName,
Key: multipartKey,
UploadId: multipartUpload.UploadId,
});
console.log('✅ 分片上传测试完成并清理');
} catch (error) {
console.log(`❌ 分片上传测试失败: ${error.message}`);
return false;
}
// 7. 列出存储桶中的文件
console.log('\n📂 列出存储桶中的文件...');
try {
const listResult = await s3Client.listObjectsV2({
Bucket: bucketName,
MaxKeys: 10,
});
console.log(`✅ 存储桶中共有 ${listResult.KeyCount || 0} 个文件`);
if (listResult.Contents && listResult.Contents.length > 0) {
console.log('最近的文件:');
listResult.Contents.slice(-5).forEach((obj, index) => {
const size = obj.Size < 1024 ? `${obj.Size}B` : `${Math.round(obj.Size / 1024)}KB`;
console.log(` ${index + 1}. ${obj.Key} (${size})`);
});
}
} catch (error) {
console.log(`❌ 列出文件失败: ${error.message}`);
}
// 8. 清理测试文件
console.log('\n🧹 清理测试文件...');
try {
await s3Client.deleteObject({
Bucket: bucketName,
Key: testFileName,
});
console.log('✅ 测试文件清理完成');
} catch (error) {
console.log(`⚠️ 清理测试文件失败: ${error.message}`);
}
console.log('\n🎉 所有测试通过您的MinIO配置完全正确');
console.log('\n📝 配置摘要:');
console.log('- ✅ 连接正常');
console.log('- ✅ 认证有效');
console.log('- ✅ 存储桶可用');
console.log('- ✅ 文件上传/下载正常');
console.log('- ✅ 分片上传支持');
console.log('\n💡 您可以在应用中使用这些配置:');
console.log('STORAGE_TYPE=s3');
console.log(`UPLOAD_DIR=${uploadDir}`);
console.log(`S3_ENDPOINT=${config.endpoint}`);
console.log(`S3_REGION=${config.region}`);
console.log(`S3_BUCKET=${bucketName}`);
console.log(`S3_ACCESS_KEY_ID=${config.credentials.accessKeyId}`);
console.log('S3_SECRET_ACCESS_KEY=***');
console.log('S3_FORCE_PATH_STYLE=true');
return true;
} catch (error) {
console.log(`❌ 测试过程中发生未预期错误: ${error.message}`);
console.log('错误堆栈:', error.stack);
return false;
}
}
// 主函数
async function main() {
console.log('🚀 MinIO S3存储配置测试\n');
// 检查依赖
try {
require('@aws-sdk/client-s3');
} catch (error) {
console.log('❌ 缺少必要依赖 @aws-sdk/client-s3');
console.log('请运行: npm install @aws-sdk/client-s3');
process.exit(1);
}
const success = await testMinIOConfig();
if (success) {
console.log('\n✅ 测试完成MinIO配置正确可以正常使用');
process.exit(0);
} else {
console.log('\n❌ 测试失败:请检查上述错误并修复配置');
process.exit(1);
}
}
main().catch((error) => {
console.error('❌ 脚本执行失败:', error);
process.exit(1);
});