- 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.
176 lines
6.5 KiB
PHP
176 lines
6.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Framework\Deployment\Pipeline\Configuration\PipelineConfigurationException;
|
|
use App\Framework\Deployment\Pipeline\Configuration\YamlPipelineConfigLoader;
|
|
use App\Framework\Deployment\Pipeline\ValueObjects\DeploymentEnvironment;
|
|
use App\Framework\Deployment\Pipeline\ValueObjects\PipelineStage;
|
|
|
|
describe('Configuration Loading Integration Tests', function () {
|
|
beforeEach(function () {
|
|
$this->configLoader = new YamlPipelineConfigLoader();
|
|
});
|
|
|
|
it('loads development configuration successfully', function () {
|
|
$configFile = __DIR__ . '/../../../../config/deployment/pipeline-development.yaml';
|
|
|
|
$config = $this->configLoader->load($configFile);
|
|
|
|
expect($config->name)->toBe('Development Pipeline');
|
|
expect($config->environment)->toBe(DeploymentEnvironment::DEVELOPMENT);
|
|
expect($config->stopOnFailure)->toBeTrue();
|
|
expect($config->enableRollback)->toBeFalse();
|
|
});
|
|
|
|
it('loads staging configuration successfully', function () {
|
|
$configFile = __DIR__ . '/../../../../config/deployment/pipeline-staging.yaml';
|
|
|
|
$config = $this->configLoader->load($configFile);
|
|
|
|
expect($config->name)->toBe('Staging Pipeline');
|
|
expect($config->environment)->toBe(DeploymentEnvironment::STAGING);
|
|
expect($config->enableRollback)->toBeTrue();
|
|
});
|
|
|
|
it('loads production configuration successfully', function () {
|
|
$configFile = __DIR__ . '/../../../../config/deployment/pipeline-production.yaml';
|
|
|
|
$config = $this->configLoader->load($configFile);
|
|
|
|
expect($config->name)->toBe('Production Pipeline');
|
|
expect($config->environment)->toBe(DeploymentEnvironment::PRODUCTION);
|
|
expect($config->enableRollback)->toBeTrue();
|
|
});
|
|
|
|
it('parses stage configurations correctly', function () {
|
|
$configFile = __DIR__ . '/../../../../config/deployment/pipeline-development.yaml';
|
|
|
|
$config = $this->configLoader->load($configFile);
|
|
|
|
$buildStage = $config->findStage(PipelineStage::BUILD);
|
|
|
|
expect($buildStage)->not->toBeNull();
|
|
expect($buildStage->enabled)->toBeTrue();
|
|
expect($buildStage->timeoutSeconds)->toBe(600);
|
|
expect($buildStage->retries)->toBe(1);
|
|
});
|
|
|
|
it('handles disabled stages correctly', function () {
|
|
$configFile = __DIR__ . '/../../../../config/deployment/pipeline-development.yaml';
|
|
|
|
$config = $this->configLoader->load($configFile);
|
|
|
|
$securityCheckStage = $config->findStage(PipelineStage::SECURITY_CHECK);
|
|
|
|
expect($securityCheckStage)->not->toBeNull();
|
|
expect($securityCheckStage->enabled)->toBeFalse();
|
|
});
|
|
|
|
it('parses skip_environments correctly', function () {
|
|
$configFile = __DIR__ . '/../../../../config/deployment/pipeline-staging.yaml';
|
|
|
|
$config = $this->configLoader->load($configFile);
|
|
|
|
$backupStage = $config->findStage(PipelineStage::BACKUP);
|
|
|
|
expect($backupStage)->not->toBeNull();
|
|
expect($backupStage->skipEnvironments)->toContain(DeploymentEnvironment::DEVELOPMENT);
|
|
});
|
|
|
|
it('parses global parameters correctly', function () {
|
|
$configFile = __DIR__ . '/../../../../config/deployment/pipeline-staging.yaml';
|
|
|
|
$config = $this->configLoader->load($configFile);
|
|
|
|
expect($config->globalParameters)->toHaveKey('docker_compose_file');
|
|
expect($config->globalParameters['docker_compose_file'])->toBe('docker-compose.staging.yml');
|
|
expect($config->globalParameters['log_level'])->toBe('info');
|
|
});
|
|
|
|
it('parses stage parameters correctly', function () {
|
|
$configFile = __DIR__ . '/../../../../config/deployment/pipeline-staging.yaml';
|
|
|
|
$config = $this->configLoader->load($configFile);
|
|
|
|
$buildStage = $config->findStage(PipelineStage::BUILD);
|
|
|
|
expect($buildStage->parameters)->toHaveKey('composer_flags');
|
|
expect($buildStage->parameters['optimize'])->toBeTrue();
|
|
});
|
|
|
|
it('throws exception for missing configuration file', function () {
|
|
$configFile = __DIR__ . '/../../../../config/deployment/non-existent.yaml';
|
|
|
|
$this->configLoader->load($configFile);
|
|
})->throws(PipelineConfigurationException::class, 'Configuration file not found');
|
|
|
|
it('throws exception for invalid YAML', function () {
|
|
$invalidYaml = __DIR__ . '/../../../tmp/invalid-pipeline.yaml';
|
|
|
|
// Create invalid YAML file
|
|
file_put_contents($invalidYaml, "invalid: yaml: content:\n - bad: indentation");
|
|
|
|
try {
|
|
$this->configLoader->load($invalidYaml);
|
|
} finally {
|
|
// Cleanup
|
|
if (file_exists($invalidYaml)) {
|
|
unlink($invalidYaml);
|
|
}
|
|
}
|
|
})->throws(PipelineConfigurationException::class);
|
|
|
|
it('throws exception for missing required fields', function () {
|
|
$incompleteYaml = __DIR__ . '/../../../tmp/incomplete-pipeline.yaml';
|
|
|
|
// Create YAML missing required 'stages' field
|
|
file_put_contents($incompleteYaml, "name: Test\nenvironment: development\n");
|
|
|
|
try {
|
|
$this->configLoader->load($incompleteYaml);
|
|
} finally {
|
|
// Cleanup
|
|
if (file_exists($incompleteYaml)) {
|
|
unlink($incompleteYaml);
|
|
}
|
|
}
|
|
})->throws(PipelineConfigurationException::class, 'Missing required configuration keys');
|
|
|
|
it('throws exception for invalid environment', function () {
|
|
$invalidEnvYaml = __DIR__ . '/../../../tmp/invalid-env-pipeline.yaml';
|
|
|
|
file_put_contents($invalidEnvYaml, "name: Test\nenvironment: invalid_env\nstages: []\n");
|
|
|
|
try {
|
|
$this->configLoader->load($invalidEnvYaml);
|
|
} finally {
|
|
// Cleanup
|
|
if (file_exists($invalidEnvYaml)) {
|
|
unlink($invalidEnvYaml);
|
|
}
|
|
}
|
|
})->throws(PipelineConfigurationException::class, 'Invalid environment');
|
|
|
|
it('throws exception for invalid stage type', function () {
|
|
$invalidStageYaml = __DIR__ . '/../../../tmp/invalid-stage-pipeline.yaml';
|
|
|
|
file_put_contents($invalidStageYaml, <<<YAML
|
|
name: Test
|
|
environment: development
|
|
stages:
|
|
- stage: invalid_stage_type
|
|
enabled: true
|
|
YAML);
|
|
|
|
try {
|
|
$this->configLoader->load($invalidStageYaml);
|
|
} finally {
|
|
// Cleanup
|
|
if (file_exists($invalidStageYaml)) {
|
|
unlink($invalidStageYaml);
|
|
}
|
|
}
|
|
})->throws(PipelineConfigurationException::class, 'Invalid stage type');
|
|
});
|