'test-fraud-detector', 'type' => 'supervised', 'version' => '1.0.0', 'configuration' => [ 'threshold' => 0.7, 'algorithm' => 'random_forest', ], 'performance_metrics' => [ 'accuracy' => 0.92, 'precision' => 0.89, ], ] ); $registerResponse = $modelsController->registerModel($registerRequest); $registerData = $registerResponse->data; echo " → POST /api/ml/models\n"; echo " Status: {$registerResponse->status->value}\n"; echo " Model: {$registerData['model_name']}\n"; echo " Version: {$registerData['version']}\n"; echo " Message: {$registerData['message']}\n\n"; // ======================================================================== // Test 2: List Models (GET /api/ml/models) // ======================================================================== echo "3. Testing list models endpoint...\n"; // Register additional models for testing $additionalModels = [ ['name' => 'spam-classifier', 'type' => 'supervised', 'version' => '2.0.0'], ['name' => 'anomaly-detector', 'type' => 'unsupervised', 'version' => '1.5.0'], ]; foreach ($additionalModels as $modelData) { $metadata = new ModelMetadata( modelName: $modelData['name'], modelType: $modelData['type'] === 'supervised' ? ModelType::SUPERVISED : ModelType::UNSUPERVISED, version: Version::fromString($modelData['version']), configuration: ['threshold' => 0.75], createdAt: Timestamp::now() ); $registry->register($metadata); } $listRequest = createRequest( method: 'GET', path: '/api/ml/models' ); $listResponse = $modelsController->listModels($listRequest); $listData = $listResponse->data; echo " → GET /api/ml/models\n"; echo " Status: {$listResponse->status->value}\n"; echo " Total Models: {$listData['total_models']}\n"; foreach ($listData['models'] as $model) { echo " - {$model['model_name']} ({$model['type']}) - {$model['versions'][0]['version']}\n"; } echo "\n"; // ======================================================================== // Test 3: Get Model Metrics (GET /api/ml/models/{modelName}/metrics) // ======================================================================== echo "4. Testing model metrics endpoint...\n"; // Simulate predictions for test-fraud-detector $timestamp = Timestamp::now(); for ($i = 0; $i < 100; $i++) { $storage->storePrediction([ 'model_name' => 'test-fraud-detector', 'version' => '1.0.0', 'prediction' => $i < 92, 'actual' => $i < 92, 'confidence' => 0.85, 'features' => [], 'timestamp' => $timestamp->toDateTime(), 'is_correct' => true, ]); } $metricsRequest = createRequest( method: 'GET', path: '/api/ml/models/test-fraud-detector/metrics', queryParams: ['version' => '1.0.0', 'timeWindow' => '1'] ); $metricsResponse = $modelsController->getMetrics('test-fraud-detector', $metricsRequest); $metricsData = $metricsResponse->data; echo " → GET /api/ml/models/test-fraud-detector/metrics\n"; echo " Status: {$metricsResponse->status->value}\n"; echo " Accuracy: " . sprintf("%.2f%%", $metricsData['metrics']['accuracy'] * 100) . "\n"; echo " Total Predictions: {$metricsData['metrics']['total_predictions']}\n\n"; // ======================================================================== // Test 4: A/B Test Creation (POST /api/ml/ab-test) // ======================================================================== echo "5. Testing A/B test creation endpoint...\n"; // Register version 2.0.0 for A/B testing $v2Metadata = new ModelMetadata( modelName: 'test-fraud-detector', modelType: ModelType::SUPERVISED, version: Version::fromString('2.0.0'), configuration: ['threshold' => 0.75], createdAt: Timestamp::now(), performanceMetrics: ['accuracy' => 0.95] ); $registry->register($v2Metadata); $abTestRequest = createRequest( method: 'POST', path: '/api/ml/ab-test', data: [ 'model_name' => 'test-fraud-detector', 'version_a' => '1.0.0', 'version_b' => '2.0.0', 'traffic_split_a' => 0.5, 'primary_metric' => 'accuracy', ] ); $abTestResponse = $abTestingController->startTest($abTestRequest); $abTestData = $abTestResponse->data; echo " → POST /api/ml/ab-test\n"; echo " Status: {$abTestResponse->status->value}\n"; echo " Test ID: {$abTestData['test_id']}\n"; echo " Version A Traffic: " . ($abTestData['traffic_split']['version_a'] * 100) . "%\n"; echo " Version B Traffic: " . ($abTestData['traffic_split']['version_b'] * 100) . "%\n\n"; // ======================================================================== // Test 5: Rollout Plan Generation (POST /api/ml/ab-test/rollout-plan) // ======================================================================== echo "6. Testing rollout plan generation endpoint...\n"; $rolloutRequest = createRequest( method: 'POST', path: '/api/ml/ab-test/rollout-plan', data: [ 'model_name' => 'test-fraud-detector', 'current_version' => '1.0.0', 'new_version' => '2.0.0', 'steps' => 4, ] ); $rolloutResponse = $abTestingController->generateRolloutPlan($rolloutRequest); $rolloutData = $rolloutResponse->data; echo " → POST /api/ml/ab-test/rollout-plan\n"; echo " Status: {$rolloutResponse->status->value}\n"; echo " Total Stages: {$rolloutData['total_stages']}\n"; foreach ($rolloutData['rollout_stages'] as $stage) { echo " Stage {$stage['stage']}: Current {$stage['current_version_traffic']}% / New {$stage['new_version_traffic']}%\n"; } echo "\n"; // ======================================================================== // Test 6: Threshold Optimization (POST /api/ml/optimize/threshold) // ======================================================================== echo "7. Testing threshold optimization endpoint...\n"; // Add more diverse predictions for optimization for ($i = 0; $i < 100; $i++) { $confidence = 0.5 + ($i / 100) * 0.4; // 0.5 to 0.9 $prediction = $confidence >= 0.7; $actual = $i < 85; $storage->storePrediction([ 'model_name' => 'test-fraud-detector', 'version' => '1.0.0', 'prediction' => $prediction, 'actual' => $actual, 'confidence' => $confidence, 'features' => [], 'timestamp' => $timestamp->toDateTime(), 'is_correct' => $prediction === $actual, ]); } $optimizeRequest = createRequest( method: 'POST', path: '/api/ml/optimize/threshold', data: [ 'model_name' => 'test-fraud-detector', 'version' => '1.0.0', 'metric_to_optimize' => 'f1_score', 'threshold_range' => [0.5, 0.9], 'step' => 0.1, ] ); $optimizeResponse = $autoTuningController->optimizeThreshold($optimizeRequest); $optimizeData = $optimizeResponse->data; echo " → POST /api/ml/optimize/threshold\n"; echo " Status: {$optimizeResponse->status->value}\n"; echo " Current Threshold: {$optimizeData['current_threshold']}\n"; echo " Optimal Threshold: {$optimizeData['optimal_threshold']}\n"; echo " Improvement: " . sprintf("%.1f%%", $optimizeData['improvement_percent']) . "\n"; echo " Tested Thresholds: {$optimizeData['tested_thresholds']}\n\n"; // ======================================================================== // Test 7: Dashboard Data (GET /api/ml/dashboard) // ======================================================================== echo "8. Testing dashboard data endpoint...\n"; $dashboardRequest = createRequest( method: 'GET', path: '/api/ml/dashboard', queryParams: ['timeWindow' => '24'] ); $dashboardResponse = $dashboardController->getDashboardData($dashboardRequest); $dashboardData = $dashboardResponse->data; echo " → GET /api/ml/dashboard\n"; echo " Status: {$dashboardResponse->status->value}\n"; echo " Total Models: {$dashboardData['summary']['total_models']}\n"; echo " Healthy: {$dashboardData['summary']['healthy_models']}\n"; echo " Degraded: {$dashboardData['summary']['degraded_models']}\n"; echo " Average Accuracy: " . sprintf("%.2f%%", $dashboardData['summary']['average_accuracy'] * 100) . "\n"; echo " Overall Status: {$dashboardData['summary']['overall_status']}\n"; echo " Active Alerts: " . count($dashboardData['alerts']) . "\n\n"; // ======================================================================== // Test 8: Health Indicators (GET /api/ml/dashboard/health) // ======================================================================== echo "9. Testing health indicators endpoint...\n"; $healthResponse = $dashboardController->getHealthIndicators(); $healthData = $healthResponse->data; echo " → GET /api/ml/dashboard/health\n"; echo " Status: {$healthResponse->status->value}\n"; echo " Overall Status: {$healthData['overall_status']}\n"; echo " Health Percentage: {$healthData['health_percentage']}%\n"; echo " Healthy Models: {$healthData['healthy_models']}\n"; echo " Degraded Models: {$healthData['degraded_models']}\n"; echo " Critical Models: {$healthData['critical_models']}\n\n"; // ======================================================================== // Test 9: Registry Summary (GET /api/ml/dashboard/registry-summary) // ======================================================================== echo "10. Testing registry summary endpoint...\n"; $summaryResponse = $dashboardController->getRegistrySummary(); $summaryData = $summaryResponse->data; echo " → GET /api/ml/dashboard/registry-summary\n"; echo " Status: {$summaryResponse->status->value}\n"; echo " Total Models: {$summaryData['total_models']}\n"; echo " Total Versions: {$summaryData['total_versions']}\n"; echo " By Type:\n"; foreach ($summaryData['by_type'] as $type => $count) { echo " - {$type}: {$count}\n"; } echo "\n"; // ======================================================================== // Test Summary // ======================================================================== echo "=== Test Summary ===\n"; echo "✓ Model Registration: Working\n"; echo "✓ List Models: Working\n"; echo "✓ Get Model Metrics: Working\n"; echo "✓ A/B Test Creation: Working\n"; echo "✓ Rollout Plan Generation: Working\n"; echo "✓ Threshold Optimization: Working\n"; echo "✓ Dashboard Data: Working\n"; echo "✓ Health Indicators: Working\n"; echo "✓ Registry Summary: Working\n\n"; echo "API Endpoints Tested: 9\n"; echo "All endpoints returning 200/201 status codes\n\n"; echo "=== ML API Endpoints Test PASSED ===\n"; } catch (\Throwable $e) { echo "\n!!! TEST FAILED !!!\n"; echo "Error: " . $e->getMessage() . "\n"; echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n"; echo "\nStack trace:\n" . $e->getTraceAsString() . "\n"; exit(1); }