ai_upgrade_assistant-0.2.0-alpha2/tests/src/Performance/UpgradePerformanceTest.php
tests/src/Performance/UpgradePerformanceTest.php
<?php
namespace Drupal\Tests\ai_upgrade_assistant\Performance;
use Drupal\Tests\BrowserTestBase;
use Drupal\Core\Test\AssertMailTrait;
use Symfony\Component\Process\Process;
/**
* Performance tests for AI Upgrade Assistant.
*
* @group ai_upgrade_assistant
* @group ai_upgrade_assistant_performance
*/
class UpgradePerformanceTest extends BrowserTestBase {
use AssertMailTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'ai_upgrade_assistant',
'node',
'system',
'user',
];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The state service.
*
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* Performance metrics.
*
* @var array
*/
protected $metrics = [];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->moduleHandler = $this->container->get('module_handler');
$this->database = $this->container->get('database');
$this->state = $this->container->get('state');
// Create test user with required permissions
$this->drupalCreateUser(['administer ai upgrade assistant']);
// Prepare test environment
$this->prepareTestEnvironment();
}
/**
* Prepares the test environment with sample modules and data.
*/
protected function prepareTestEnvironment() {
// Create sample modules for testing
$this->createSampleModules();
// Clear all caches to ensure clean state
drupal_flush_all_caches();
// Initialize performance metrics
$this->metrics = [
'memory' => [],
'time' => [],
'queries' => [],
'cache' => [
'hits' => 0,
'misses' => 0,
],
];
}
/**
* Tests upgrade analysis performance with varying load.
*/
public function testUpgradeAnalysisPerformance() {
$module_counts = [1, 5, 10, 25, 50];
foreach ($module_counts as $count) {
$this->runAnalysisTest($count);
}
// Assert performance metrics
$this->assertPerformanceMetrics();
}
/**
* Runs analysis performance test for a specific number of modules.
*
* @param int $module_count
* Number of modules to analyze.
*/
protected function runAnalysisTest($module_count) {
// Start monitoring
$start_memory = memory_get_usage();
$start_time = microtime(TRUE);
$start_queries = $this->getQueryCount();
// Run upgrade analysis
$this->drupalGet('admin/config/development/ai-upgrade-assistant/analyze');
$this->submitForm([
'modules[test_module_' . $module_count . ']' => TRUE,
], 'Analyze');
// Collect metrics
$this->metrics['memory'][$module_count] = memory_get_usage() - $start_memory;
$this->metrics['time'][$module_count] = microtime(TRUE) - $start_time;
$this->metrics['queries'][$module_count] = $this->getQueryCount() - $start_queries;
// Log metrics
$this->logPerformanceMetrics($module_count);
}
/**
* Tests cache performance under load.
*/
public function testCachePerformance() {
$iterations = [100, 500, 1000];
foreach ($iterations as $count) {
$this->runCacheTest($count);
}
// Assert cache metrics
$this->assertCacheMetrics();
}
/**
* Runs cache performance test.
*
* @param int $iterations
* Number of iterations to test.
*/
protected function runCacheTest($iterations) {
$start_time = microtime(TRUE);
for ($i = 0; $i < $iterations; $i++) {
$cid = 'ai_upgrade_test_' . rand(1, 100);
$cache = \Drupal::cache()->get($cid);
if ($cache) {
$this->metrics['cache']['hits']++;
}
else {
$this->metrics['cache']['misses']++;
\Drupal::cache()->set($cid, rand(1, 1000), time() + 3600);
}
}
$this->metrics['cache_time'][$iterations] = microtime(TRUE) - $start_time;
}
/**
* Tests concurrent request handling.
*/
public function testConcurrentRequests() {
$concurrent_requests = [5, 10, 20];
foreach ($concurrent_requests as $count) {
$this->runConcurrencyTest($count);
}
// Assert concurrency metrics
$this->assertConcurrencyMetrics();
}
/**
* Runs concurrency test.
*
* @param int $concurrent_count
* Number of concurrent requests.
*/
protected function runConcurrencyTest($concurrent_count) {
$processes = [];
$start_time = microtime(TRUE);
// Start concurrent processes
for ($i = 0; $i < $concurrent_count; $i++) {
$process = new Process([
'php',
'core/scripts/run-tests.php',
'--url',
$this->baseUrl,
'--class',
'Drupal\Tests\ai_upgrade_assistant\Functional\UpgradeAnalysisTest',
]);
$process->start();
$processes[] = $process;
}
// Wait for all processes to complete
foreach ($processes as $process) {
$process->wait();
}
$this->metrics['concurrent'][$concurrent_count] = microtime(TRUE) - $start_time;
}
/**
* Creates sample modules for testing.
*/
protected function createSampleModules() {
$module_template = $this->moduleHandler->getModule('ai_upgrade_assistant')->getPath() . '/tests/fixtures/test_module';
for ($i = 1; $i <= 50; $i++) {
$target = 'modules/custom/test_module_' . $i;
$this->copyDirectory($module_template, $target);
}
}
/**
* Gets the current database query count.
*
* @return int
* Number of queries executed.
*/
protected function getQueryCount() {
return (int) $this->database->query('SHOW SESSION STATUS LIKE "Questions"')->fetchField(1);
}
/**
* Logs performance metrics for analysis.
*
* @param int $test_size
* Size of the test (number of modules/iterations).
*/
protected function logPerformanceMetrics($test_size) {
$metrics = [
'memory' => $this->metrics['memory'][$test_size] ?? 0,
'time' => $this->metrics['time'][$test_size] ?? 0,
'queries' => $this->metrics['queries'][$test_size] ?? 0,
];
$this->state->set('ai_upgrade_assistant.performance_metrics.' . $test_size, $metrics);
}
/**
* Asserts that performance metrics meet requirements.
*/
protected function assertPerformanceMetrics() {
// Memory usage should scale sub-linearly
foreach ($this->metrics['memory'] as $count => $usage) {
$this->assertLessThan(
$count * 5000000, // 5MB per module
$usage,
"Memory usage for $count modules exceeds limit"
);
}
// Response time should be reasonable
foreach ($this->metrics['time'] as $count => $time) {
$this->assertLessThan(
$count * 2, // 2 seconds per module
$time,
"Response time for $count modules exceeds limit"
);
}
// Query count should scale efficiently
foreach ($this->metrics['queries'] as $count => $queries) {
$this->assertLessThan(
$count * 10, // 10 queries per module
$queries,
"Query count for $count modules exceeds limit"
);
}
}
/**
* Asserts that cache metrics meet requirements.
*/
protected function assertCacheMetrics() {
$total = $this->metrics['cache']['hits'] + $this->metrics['cache']['misses'];
$hit_ratio = ($this->metrics['cache']['hits'] / $total) * 100;
// Cache hit ratio should be above 80%
$this->assertGreaterThan(
80,
$hit_ratio,
"Cache hit ratio below 80%"
);
// Cache operations should be fast
foreach ($this->metrics['cache_time'] as $iterations => $time) {
$this->assertLessThan(
$iterations * 0.001, // 1ms per operation
$time,
"Cache operations too slow for $iterations iterations"
);
}
}
/**
* Asserts that concurrency metrics meet requirements.
*/
protected function assertConcurrencyMetrics() {
foreach ($this->metrics['concurrent'] as $count => $time) {
// Time should scale sub-linearly with concurrent requests
$this->assertLessThan(
$count * 5, // 5 seconds per concurrent request
$time,
"Concurrent processing time for $count requests exceeds limit"
);
}
}
}
