Files
michaelschiemer/tests/Performance/Benchmarks/RoutingBenchmark.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- 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.
2025-10-25 19:18:37 +02:00

212 lines
6.2 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Performance\Benchmarks;
use App\Framework\Performance\Contracts\PerformanceCollectorInterface;
use App\Framework\Performance\PerformanceCategory;
use App\Framework\Router\HttpRouter;
use App\Framework\Http\HttpRequest;
use App\Framework\Http\Method;
use App\Framework\Http\ServerEnvironment;
use App\Framework\Http\ParsedUri;
use Tests\Performance\PerformanceTestCase;
use Tests\Performance\PerformanceBenchmarkResult;
/**
* Performance benchmarks for routing system
*
* Tests routing performance including:
* - Route matching speed
* - Parameter extraction
* - Middleware resolution
* - Static vs dynamic routes
*/
final readonly class RoutingBenchmark extends PerformanceTestCase
{
public function __construct(
PerformanceCollectorInterface $collector,
private HttpRouter $router
) {
parent::__construct($collector);
}
/**
* Benchmark static route matching (no parameters)
*/
public function benchmarkStaticRouteMatching(): PerformanceBenchmarkResult
{
$request = $this->createRequest('/api/health', Method::GET);
$result = $this->benchmark(
operation: fn() => $this->router->match($request),
iterations: 10000,
name: 'Static Route Matching'
);
// Assert performance threshold: static routes should be very fast
$this->assertPerformanceThreshold($result, maxAvgTimeMs: 0.1);
// Record metrics
$this->recordBenchmark($result, PerformanceCategory::ROUTING);
return $result;
}
/**
* Benchmark dynamic route matching (with parameters)
*/
public function benchmarkDynamicRouteMatching(): PerformanceBenchmarkResult
{
$request = $this->createRequest('/api/users/123', Method::GET);
$result = $this->benchmark(
operation: fn() => $this->router->match($request),
iterations: 10000,
name: 'Dynamic Route Matching'
);
// Assert performance threshold: dynamic routes can be slightly slower
$this->assertPerformanceThreshold($result, maxAvgTimeMs: 0.5);
$this->recordBenchmark($result, PerformanceCategory::ROUTING);
return $result;
}
/**
* Benchmark complex route matching (multiple parameters)
*/
public function benchmarkComplexRouteMatching(): PerformanceBenchmarkResult
{
$request = $this->createRequest('/api/v1/users/123/posts/456/comments', Method::GET);
$result = $this->benchmark(
operation: fn() => $this->router->match($request),
iterations: 10000,
name: 'Complex Route Matching'
);
// Assert performance threshold: complex routes with multiple params
$this->assertPerformanceThreshold($result, maxAvgTimeMs: 1.0);
$this->recordBenchmark($result, PerformanceCategory::ROUTING);
return $result;
}
/**
* Benchmark route matching with query parameters
*/
public function benchmarkRouteWithQueryParams(): PerformanceBenchmarkResult
{
$request = $this->createRequest(
'/api/search?q=test&limit=10&offset=0&sort=name',
Method::GET
);
$result = $this->benchmark(
operation: fn() => $this->router->match($request),
iterations: 10000,
name: 'Route Matching with Query Params'
);
$this->assertPerformanceThreshold($result, maxAvgTimeMs: 0.2);
$this->recordBenchmark($result, PerformanceCategory::ROUTING);
return $result;
}
/**
* Benchmark route not found scenario
*/
public function benchmarkRouteNotFound(): PerformanceBenchmarkResult
{
$request = $this->createRequest('/non-existent-route', Method::GET);
$result = $this->benchmark(
operation: function() use ($request) {
try {
$this->router->match($request);
} catch (\Exception $e) {
// Expected - route not found
}
},
iterations: 10000,
name: 'Route Not Found'
);
// Route not found should still be fast (fail fast principle)
$this->assertPerformanceThreshold($result, maxAvgTimeMs: 0.1);
$this->recordBenchmark($result, PerformanceCategory::ROUTING);
return $result;
}
/**
* Benchmark POST route matching
*/
public function benchmarkPostRouteMatching(): PerformanceBenchmarkResult
{
$request = $this->createRequest('/api/users', Method::POST);
$result = $this->benchmark(
operation: fn() => $this->router->match($request),
iterations: 10000,
name: 'POST Route Matching'
);
$this->assertPerformanceThreshold($result, maxAvgTimeMs: 0.2);
$this->recordBenchmark($result, PerformanceCategory::ROUTING);
return $result;
}
/**
* Run all routing benchmarks and return summary
*/
public function runAllBenchmarks(): array
{
return [
'static_route' => $this->benchmarkStaticRouteMatching(),
'dynamic_route' => $this->benchmarkDynamicRouteMatching(),
'complex_route' => $this->benchmarkComplexRouteMatching(),
'query_params' => $this->benchmarkRouteWithQueryParams(),
'route_not_found' => $this->benchmarkRouteNotFound(),
'post_route' => $this->benchmarkPostRouteMatching(),
];
}
/**
* Helper: Create HTTP request for testing
*/
private function createRequest(string $uri, Method $method): HttpRequest
{
$parsedUri = ParsedUri::fromString('https://localhost' . $uri);
$server = new ServerEnvironment([
'REQUEST_METHOD' => $method->value,
'REQUEST_URI' => $uri,
'SERVER_NAME' => 'localhost',
'SERVER_PORT' => '443',
'HTTPS' => 'on'
]);
return new HttpRequest(
method: $method,
uri: $parsedUri,
server: $server,
headers: [],
body: '',
parsedBody: null,
queryParameters: $parsedUri->query ?? [],
cookies: [],
files: []
);
}
}