- Add TESTING_GUIDE.md with step-by-step testing instructions - Add test-complete-setup.js for automated setup verification - Cover all aspects: infrastructure, XML import, file upload, matching, playback, export - Include troubleshooting section and expected results - Provide verification checklist and success criteria The testing guide covers 7 phases of testing from basic setup to advanced features, ensuring complete validation of the S3 music storage and matching system.
239 lines
7.5 KiB
JavaScript
Executable File
239 lines
7.5 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
||
|
||
/**
|
||
* Complete S3 Music Storage Test Script
|
||
* Tests all aspects of the S3 music storage system
|
||
*/
|
||
|
||
import { S3Client, ListBucketsCommand, HeadBucketCommand } from '@aws-sdk/client-s3';
|
||
import { AudioMetadataService } from './packages/backend/src/services/audioMetadataService.js';
|
||
|
||
const S3_ENDPOINT = process.env.S3_ENDPOINT || 'http://localhost:9000';
|
||
const S3_ACCESS_KEY_ID = process.env.S3_ACCESS_KEY_ID || 'minioadmin';
|
||
const S3_SECRET_ACCESS_KEY = process.env.S3_SECRET_ACCESS_KEY || 'minioadmin';
|
||
const S3_BUCKET_NAME = process.env.S3_BUCKET_NAME || 'music-files';
|
||
|
||
console.log('🧪 Testing Complete S3 Music Storage Setup\n');
|
||
|
||
// Test 1: S3 Connection
|
||
async function testS3Connection() {
|
||
console.log('1️⃣ Testing S3 Connection...');
|
||
|
||
try {
|
||
const s3Client = new S3Client({
|
||
endpoint: S3_ENDPOINT,
|
||
region: 'us-east-1',
|
||
credentials: {
|
||
accessKeyId: S3_ACCESS_KEY_ID,
|
||
secretAccessKey: S3_SECRET_ACCESS_KEY,
|
||
},
|
||
forcePathStyle: true,
|
||
});
|
||
|
||
// Test connection
|
||
await s3Client.send(new ListBucketsCommand({}));
|
||
console.log(' ✅ S3 connection successful');
|
||
|
||
// Test bucket access
|
||
await s3Client.send(new HeadBucketCommand({ Bucket: S3_BUCKET_NAME }));
|
||
console.log(' ✅ Bucket access verified');
|
||
|
||
return true;
|
||
} catch (error) {
|
||
console.log(' ❌ S3 connection failed:', error.message);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// Test 2: Audio Metadata Service
|
||
async function testAudioMetadataService() {
|
||
console.log('\n2️⃣ Testing Audio Metadata Service...');
|
||
|
||
try {
|
||
const audioService = new AudioMetadataService();
|
||
|
||
// Test supported formats
|
||
const supportedFormats = ['mp3', 'wav', 'flac', 'm4a', 'aac'];
|
||
for (const format of supportedFormats) {
|
||
const isSupported = audioService.isAudioFile(`test.${format}`);
|
||
console.log(` ${isSupported ? '✅' : '❌'} ${format.toUpperCase()} format: ${isSupported ? 'Supported' : 'Not supported'}`);
|
||
}
|
||
|
||
console.log(' ✅ Audio metadata service initialized');
|
||
return true;
|
||
} catch (error) {
|
||
console.log(' ❌ Audio metadata service failed:', error.message);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// Test 3: Environment Variables
|
||
function testEnvironmentVariables() {
|
||
console.log('\n3️⃣ Testing Environment Variables...');
|
||
|
||
const requiredVars = [
|
||
'S3_ENDPOINT',
|
||
'S3_ACCESS_KEY_ID',
|
||
'S3_SECRET_ACCESS_KEY',
|
||
'S3_BUCKET_NAME'
|
||
];
|
||
|
||
let allPresent = true;
|
||
|
||
for (const varName of requiredVars) {
|
||
const value = process.env[varName];
|
||
if (value) {
|
||
console.log(` ✅ ${varName}: ${varName.includes('SECRET') ? '***' : value}`);
|
||
} else {
|
||
console.log(` ❌ ${varName}: Not set`);
|
||
allPresent = false;
|
||
}
|
||
}
|
||
|
||
return allPresent;
|
||
}
|
||
|
||
// Test 4: Port Availability
|
||
async function testPortAvailability() {
|
||
console.log('\n4️⃣ Testing Port Availability...');
|
||
|
||
const ports = [
|
||
{ port: 3000, service: 'Backend API' },
|
||
{ port: 5173, service: 'Frontend Dev Server' },
|
||
{ port: 9000, service: 'MinIO' },
|
||
{ port: 27017, service: 'MongoDB' }
|
||
];
|
||
|
||
const net = await import('net');
|
||
|
||
for (const { port, service } of ports) {
|
||
try {
|
||
const socket = new net.Socket();
|
||
const isAvailable = await new Promise((resolve) => {
|
||
socket.setTimeout(1000);
|
||
socket.on('connect', () => {
|
||
socket.destroy();
|
||
resolve(false); // Port is in use
|
||
});
|
||
socket.on('timeout', () => {
|
||
socket.destroy();
|
||
resolve(true); // Port is available
|
||
});
|
||
socket.on('error', () => {
|
||
resolve(true); // Port is available
|
||
});
|
||
socket.connect(port, 'localhost');
|
||
});
|
||
|
||
console.log(` ${isAvailable ? '❌' : '✅'} Port ${port} (${service}): ${isAvailable ? 'Available' : 'In Use'}`);
|
||
} catch (error) {
|
||
console.log(` ❌ Port ${port} (${service}): Error checking`);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Test 5: API Endpoints
|
||
async function testAPIEndpoints() {
|
||
console.log('\n5️⃣ Testing API Endpoints...');
|
||
|
||
const endpoints = [
|
||
{ url: 'http://localhost:3000/api/health', name: 'Health Check' },
|
||
{ url: 'http://localhost:3000/api/songs', name: 'Songs API' },
|
||
{ url: 'http://localhost:3000/api/music/files', name: 'Music Files API' },
|
||
{ url: 'http://localhost:3000/api/matching/stats', name: 'Matching Stats API' }
|
||
];
|
||
|
||
for (const { url, name } of endpoints) {
|
||
try {
|
||
const response = await fetch(url);
|
||
const status = response.status;
|
||
console.log(` ${status === 200 ? '✅' : '❌'} ${name}: ${status}`);
|
||
} catch (error) {
|
||
console.log(` ❌ ${name}: Connection failed`);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Test 6: Docker Services
|
||
async function testDockerServices() {
|
||
console.log('\n6️⃣ Testing Docker Services...');
|
||
|
||
try {
|
||
const { exec } = await import('child_process');
|
||
const { promisify } = await import('util');
|
||
const execAsync = promisify(exec);
|
||
|
||
const { stdout } = await execAsync('docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"');
|
||
const lines = stdout.trim().split('\n').slice(1); // Skip header
|
||
|
||
const expectedServices = ['minio', 'mongodb'];
|
||
|
||
for (const service of expectedServices) {
|
||
const isRunning = lines.some(line => line.includes(service));
|
||
console.log(` ${isRunning ? '✅' : '❌'} ${service}: ${isRunning ? 'Running' : 'Not running'}`);
|
||
}
|
||
|
||
return true;
|
||
} catch (error) {
|
||
console.log(' ❌ Docker check failed:', error.message);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// Main test runner
|
||
async function runAllTests() {
|
||
console.log('🚀 Starting Complete S3 Music Storage Tests\n');
|
||
|
||
const tests = [
|
||
{ name: 'Environment Variables', fn: testEnvironmentVariables },
|
||
{ name: 'Docker Services', fn: testDockerServices },
|
||
{ name: 'S3 Connection', fn: testS3Connection },
|
||
{ name: 'Audio Metadata Service', fn: testAudioMetadataService },
|
||
{ name: 'Port Availability', fn: testPortAvailability },
|
||
{ name: 'API Endpoints', fn: testAPIEndpoints }
|
||
];
|
||
|
||
const results = [];
|
||
|
||
for (const test of tests) {
|
||
try {
|
||
const result = await test.fn();
|
||
results.push({ name: test.name, passed: result });
|
||
} catch (error) {
|
||
console.log(` ❌ ${test.name} failed with error:`, error.message);
|
||
results.push({ name: test.name, passed: false });
|
||
}
|
||
}
|
||
|
||
// Summary
|
||
console.log('\n📊 Test Summary:');
|
||
console.log('================');
|
||
|
||
const passed = results.filter(r => r.passed).length;
|
||
const total = results.length;
|
||
|
||
for (const result of results) {
|
||
console.log(`${result.passed ? '✅' : '❌'} ${result.name}`);
|
||
}
|
||
|
||
console.log(`\n🎯 Overall Result: ${passed}/${total} tests passed`);
|
||
|
||
if (passed === total) {
|
||
console.log('\n🎉 All tests passed! Your S3 music storage system is ready for testing.');
|
||
console.log('\n📋 Next steps:');
|
||
console.log(' 1. Start backend: cd packages/backend && npm run dev');
|
||
console.log(' 2. Start frontend: cd packages/frontend && npm run dev');
|
||
console.log(' 3. Open browser: http://localhost:5173');
|
||
console.log(' 4. Follow the testing guide: TESTING_GUIDE.md');
|
||
} else {
|
||
console.log('\n⚠️ Some tests failed. Please check the issues above before proceeding.');
|
||
console.log('\n🔧 Troubleshooting:');
|
||
console.log(' 1. Ensure Docker is running');
|
||
console.log(' 2. Start services: docker-compose -f docker-compose.dev.yml up -d');
|
||
console.log(' 3. Check environment variables');
|
||
console.log(' 4. Install dependencies: npm install in both packages');
|
||
}
|
||
}
|
||
|
||
// Run tests
|
||
runAllTests().catch(console.error);
|