- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
166 lines
6.1 KiB
PHP
166 lines
6.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Framework\Database\Indexing\IndexMigrationGenerator;
|
|
use App\Framework\Database\Indexing\ValueObjects\IndexRecommendation;
|
|
use App\Framework\Database\Indexing\ValueObjects\IndexType;
|
|
use App\Framework\Database\Indexing\ValueObjects\RecommendationPriority;
|
|
use App\Framework\Database\PdoConnection;
|
|
|
|
describe('IndexMigrationGenerator', function () {
|
|
beforeEach(function () {
|
|
$pdo = new PDO('sqlite::memory:');
|
|
$connection = new PdoConnection($pdo, 'sqlite');
|
|
|
|
$this->generator = new IndexMigrationGenerator($connection);
|
|
});
|
|
|
|
it('generates migration for adding indexes', function () {
|
|
$recommendations = [
|
|
new IndexRecommendation(
|
|
tableName: 'users',
|
|
columns: ['email'],
|
|
indexType: IndexType::BTREE,
|
|
reason: 'Frequent WHERE email lookups',
|
|
priority: RecommendationPriority::HIGH,
|
|
estimatedSpeedup: 5.0,
|
|
affectedQueries: 100
|
|
),
|
|
new IndexRecommendation(
|
|
tableName: 'users',
|
|
columns: ['status', 'created_at'],
|
|
indexType: IndexType::BTREE,
|
|
reason: 'WHERE status + ORDER BY created_at',
|
|
priority: RecommendationPriority::CRITICAL,
|
|
estimatedSpeedup: 10.0,
|
|
affectedQueries: 250
|
|
)
|
|
];
|
|
|
|
$migration = $this->generator->generateAddIndexMigration($recommendations, 'users');
|
|
|
|
expect($migration)->toBeString();
|
|
expect($migration)->toContain('extends Migration');
|
|
expect($migration)->toContain('public function up(Schema $schema)');
|
|
expect($migration)->toContain('public function down(Schema $schema)');
|
|
expect($migration)->toContain('users');
|
|
expect($migration)->toContain('$table->index');
|
|
});
|
|
|
|
it('generates migration for removing indexes', function () {
|
|
$unusedIndexes = [
|
|
[
|
|
'index_name' => 'idx_users_old_column',
|
|
'columns' => ['old_column']
|
|
],
|
|
[
|
|
'index_name' => 'idx_users_deprecated',
|
|
'columns' => ['deprecated_field']
|
|
]
|
|
];
|
|
|
|
$migration = $this->generator->generateRemoveIndexMigration($unusedIndexes, 'users');
|
|
|
|
expect($migration)->toBeString();
|
|
expect($migration)->toContain('extends Migration');
|
|
expect($migration)->toContain('$table->dropIndex');
|
|
expect($migration)->toContain('idx_users_old_column');
|
|
expect($migration)->toContain('idx_users_deprecated');
|
|
});
|
|
|
|
it('generates optimization migration (add + remove)', function () {
|
|
$toAdd = [
|
|
new IndexRecommendation(
|
|
tableName: 'orders',
|
|
columns: ['customer_id', 'status'],
|
|
indexType: IndexType::BTREE,
|
|
reason: 'WHERE customer_id + status filter',
|
|
priority: RecommendationPriority::HIGH,
|
|
estimatedSpeedup: 8.0,
|
|
affectedQueries: 150
|
|
)
|
|
];
|
|
|
|
$toRemove = [
|
|
[
|
|
'index_name' => 'idx_orders_unused',
|
|
'columns' => ['unused_column']
|
|
]
|
|
];
|
|
|
|
$migration = $this->generator->generateOptimizationMigration($toAdd, $toRemove, 'orders');
|
|
|
|
expect($migration)->toBeString();
|
|
expect($migration)->toContain('extends Migration');
|
|
expect($migration)->toContain('$table->dropIndex(\'idx_orders_unused\')');
|
|
expect($migration)->toContain('$table->index');
|
|
});
|
|
|
|
it('includes proper up/down migration methods', function () {
|
|
$recommendations = [
|
|
new IndexRecommendation(
|
|
tableName: 'products',
|
|
columns: ['category'],
|
|
indexType: IndexType::BTREE,
|
|
reason: 'Category filtering',
|
|
priority: RecommendationPriority::MEDIUM,
|
|
estimatedSpeedup: 3.0,
|
|
affectedQueries: 50
|
|
)
|
|
];
|
|
|
|
$migration = $this->generator->generateAddIndexMigration($recommendations, 'products');
|
|
|
|
// Check UP method
|
|
expect($migration)->toContain('public function up(Schema $schema)');
|
|
expect($migration)->toContain('$schema->table(\'products\'');
|
|
|
|
// Check DOWN method (should reverse the UP actions)
|
|
expect($migration)->toContain('public function down(Schema $schema)');
|
|
expect($migration)->toContain('$table->dropIndex');
|
|
});
|
|
|
|
it('validates migration content structure', function () {
|
|
$recommendations = [
|
|
new IndexRecommendation(
|
|
tableName: 'test_table',
|
|
columns: ['test_column'],
|
|
indexType: IndexType::BTREE,
|
|
reason: 'Test',
|
|
priority: RecommendationPriority::LOW,
|
|
estimatedSpeedup: 1.5,
|
|
affectedQueries: 10
|
|
)
|
|
];
|
|
|
|
$migration = $this->generator->generateAddIndexMigration($recommendations, 'test_table');
|
|
|
|
// Validate required components
|
|
expect($migration)->toContain('declare(strict_types=1)');
|
|
expect($migration)->toContain('use App\Framework\Database\Migration\Migration');
|
|
expect($migration)->toContain('use App\Framework\Database\Schema\Schema');
|
|
expect($migration)->toContain('final class');
|
|
});
|
|
|
|
it('handles composite indexes correctly', function () {
|
|
$recommendations = [
|
|
new IndexRecommendation(
|
|
tableName: 'posts',
|
|
columns: ['author_id', 'published_at', 'status'],
|
|
indexType: IndexType::BTREE,
|
|
reason: 'Complex WHERE + ORDER BY',
|
|
priority: RecommendationPriority::CRITICAL,
|
|
estimatedSpeedup: 15.0,
|
|
affectedQueries: 300
|
|
)
|
|
];
|
|
|
|
$migration = $this->generator->generateAddIndexMigration($recommendations, 'posts');
|
|
|
|
expect($migration)->toContain('author_id');
|
|
expect($migration)->toContain('published_at');
|
|
expect($migration)->toContain('status');
|
|
});
|
|
});
|