443 lines
14 KiB
PHP
443 lines
14 KiB
PHP
<?php
|
|
/**
|
|
* Copyright seit 2024 Webshop System
|
|
*
|
|
* Performance-Tests für das Webshop-System
|
|
*
|
|
* @author Webshop System
|
|
* @license GPL v3
|
|
*/
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class PerformanceTest extends TestCase
|
|
{
|
|
protected $startTime;
|
|
protected $results = [];
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->startTime = microtime(true);
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
$this->printResults();
|
|
parent::tearDown();
|
|
}
|
|
|
|
/**
|
|
* Test Product Creation Performance
|
|
*/
|
|
public function testProductCreationPerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
for ($i = 1; $i <= 100; $i++) {
|
|
$product = new Product();
|
|
$product->name = 'Performance Test Product ' . $i;
|
|
$product->reference = 'PERF-' . $i;
|
|
$product->price = rand(10, 1000);
|
|
$product->active = true;
|
|
$product->add();
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Product Creation (100 products)'] = $executionTime;
|
|
$this->assertLessThan(5.0, $executionTime, 'Product creation should be faster than 5 seconds');
|
|
}
|
|
|
|
/**
|
|
* Test Product Retrieval Performance
|
|
*/
|
|
public function testProductRetrievalPerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
for ($i = 1; $i <= 1000; $i++) {
|
|
$product = new Product(rand(1, 100));
|
|
$name = $product->name;
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Product Retrieval (1000 products)'] = $executionTime;
|
|
$this->assertLessThan(2.0, $executionTime, 'Product retrieval should be faster than 2 seconds');
|
|
}
|
|
|
|
/**
|
|
* Test Product Search Performance
|
|
*/
|
|
public function testProductSearchPerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
for ($i = 1; $i <= 100; $i++) {
|
|
$products = Product::searchByName('Test');
|
|
$count = count($products);
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Product Search (100 searches)'] = $executionTime;
|
|
$this->assertLessThan(3.0, $executionTime, 'Product search should be faster than 3 seconds');
|
|
}
|
|
|
|
/**
|
|
* Test Category Performance
|
|
*/
|
|
public function testCategoryPerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
// Create categories
|
|
for ($i = 1; $i <= 50; $i++) {
|
|
$category = new Category();
|
|
$category->name = 'Performance Category ' . $i;
|
|
$category->active = true;
|
|
$category->add();
|
|
}
|
|
|
|
// Retrieve categories
|
|
for ($i = 1; $i <= 500; $i++) {
|
|
$category = new Category(rand(1, 50));
|
|
$name = $category->name;
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Category Operations (50 create, 500 retrieve)'] = $executionTime;
|
|
$this->assertLessThan(4.0, $executionTime, 'Category operations should be faster than 4 seconds');
|
|
}
|
|
|
|
/**
|
|
* Test Order Performance
|
|
*/
|
|
public function testOrderPerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
// Create customers first
|
|
for ($i = 1; $i <= 20; $i++) {
|
|
$customer = new Customer();
|
|
$customer->firstname = 'Test' . $i;
|
|
$customer->lastname = 'Customer' . $i;
|
|
$customer->email = 'test' . $i . '@example.com';
|
|
$customer->add();
|
|
}
|
|
|
|
// Create orders
|
|
for ($i = 1; $i <= 100; $i++) {
|
|
$order = new Order();
|
|
$order->id_customer = rand(1, 20);
|
|
$order->id_cart = rand(1, 100);
|
|
$order->total_paid = rand(10, 1000);
|
|
$order->add();
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Order Creation (100 orders)'] = $executionTime;
|
|
$this->assertLessThan(6.0, $executionTime, 'Order creation should be faster than 6 seconds');
|
|
}
|
|
|
|
/**
|
|
* Test Cart Performance
|
|
*/
|
|
public function testCartPerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
for ($i = 1; $i <= 200; $i++) {
|
|
$cart = new Cart();
|
|
$cart->id_customer = rand(1, 20);
|
|
$cart->add();
|
|
|
|
// Add products to cart
|
|
for ($j = 1; $j <= 5; $j++) {
|
|
$cart->updateQty(rand(1, 100), rand(1, 10));
|
|
}
|
|
|
|
$products = $cart->getProducts();
|
|
$total = $cart->getOrderTotal();
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Cart Operations (200 carts with 5 products each)'] = $executionTime;
|
|
$this->assertLessThan(8.0, $executionTime, 'Cart operations should be faster than 8 seconds');
|
|
}
|
|
|
|
/**
|
|
* Test Database Performance
|
|
*/
|
|
public function testDatabasePerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
// Complex queries
|
|
for ($i = 1; $i <= 100; $i++) {
|
|
$sql = 'SELECT p.*, c.name as category_name
|
|
FROM product p
|
|
LEFT JOIN category c ON p.id_category_default = c.id_category
|
|
WHERE p.active = 1
|
|
ORDER BY p.price ASC
|
|
LIMIT 50';
|
|
$result = Db::getInstance()->executeS($sql);
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Database Complex Queries (100 queries)'] = $executionTime;
|
|
$this->assertLessThan(3.0, $executionTime, 'Database queries should be faster than 3 seconds');
|
|
}
|
|
|
|
/**
|
|
* Test Cache Performance
|
|
*/
|
|
public function testCachePerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
// Cache operations
|
|
for ($i = 1; $i <= 1000; $i++) {
|
|
$key = 'test_cache_' . $i;
|
|
$value = 'test_value_' . $i;
|
|
|
|
Cache::store($key, $value, 3600);
|
|
$retrieved = Cache::retrieve($key);
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Cache Operations (1000 store/retrieve)'] = $executionTime;
|
|
$this->assertLessThan(1.0, $executionTime, 'Cache operations should be faster than 1 second');
|
|
}
|
|
|
|
/**
|
|
* Test Memory Usage
|
|
*/
|
|
public function testMemoryUsage()
|
|
{
|
|
$initialMemory = memory_get_usage();
|
|
|
|
// Create many objects
|
|
$products = [];
|
|
for ($i = 1; $i <= 1000; $i++) {
|
|
$product = new Product();
|
|
$product->name = 'Memory Test Product ' . $i;
|
|
$product->price = rand(10, 1000);
|
|
$products[] = $product;
|
|
}
|
|
|
|
$finalMemory = memory_get_usage();
|
|
$memoryUsed = $finalMemory - $initialMemory;
|
|
|
|
$this->results['Memory Usage (1000 Product objects)'] = $memoryUsed . ' bytes';
|
|
$this->assertLessThan(50 * 1024 * 1024, $memoryUsed, 'Memory usage should be less than 50MB');
|
|
}
|
|
|
|
/**
|
|
* Test Concurrent Operations
|
|
*/
|
|
public function testConcurrentOperations()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
// Simulate concurrent operations
|
|
$threads = [];
|
|
for ($i = 1; $i <= 10; $i++) {
|
|
$threads[] = function() use ($i) {
|
|
for ($j = 1; $j <= 10; $j++) {
|
|
$product = new Product();
|
|
$product->name = 'Concurrent Product ' . $i . '-' . $j;
|
|
$product->price = rand(10, 1000);
|
|
$product->add();
|
|
}
|
|
};
|
|
}
|
|
|
|
// Execute all threads
|
|
foreach ($threads as $thread) {
|
|
$thread();
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Concurrent Operations (10 threads, 10 products each)'] = $executionTime;
|
|
$this->assertLessThan(10.0, $executionTime, 'Concurrent operations should be faster than 10 seconds');
|
|
}
|
|
|
|
/**
|
|
* Test API Response Time
|
|
*/
|
|
public function testApiResponseTime()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
// Simulate API calls
|
|
for ($i = 1; $i <= 100; $i++) {
|
|
// Simulate GET /api/products
|
|
$products = Product::getProducts(1, 0, 0, 'id_product', 'ASC', false, true);
|
|
|
|
// Simulate GET /api/products/{id}
|
|
$product = new Product(rand(1, 100));
|
|
|
|
// Simulate POST /api/products
|
|
$newProduct = new Product();
|
|
$newProduct->name = 'API Test Product ' . $i;
|
|
$newProduct->price = rand(10, 1000);
|
|
$newProduct->add();
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['API Operations (100 requests)'] = $executionTime;
|
|
$this->assertLessThan(5.0, $executionTime, 'API operations should be faster than 5 seconds');
|
|
}
|
|
|
|
/**
|
|
* Test Webservice Performance
|
|
*/
|
|
public function testWebservicePerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
for ($i = 1; $i <= 50; $i++) {
|
|
$product = new Product(rand(1, 100));
|
|
$wsFields = $product->getWebserviceObjectList('', '', '', '');
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Webservice Operations (50 requests)'] = $executionTime;
|
|
$this->assertLessThan(3.0, $executionTime, 'Webservice operations should be faster than 3 seconds');
|
|
}
|
|
|
|
/**
|
|
* Test Configuration Performance
|
|
*/
|
|
public function testConfigurationPerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
for ($i = 1; $i <= 1000; $i++) {
|
|
$key = 'test_config_' . $i;
|
|
$value = 'test_value_' . $i;
|
|
|
|
Configuration::set($key, $value);
|
|
$retrieved = Configuration::get($key);
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Configuration Operations (1000 set/get)'] = $executionTime;
|
|
$this->assertLessThan(2.0, $executionTime, 'Configuration operations should be faster than 2 seconds');
|
|
}
|
|
|
|
/**
|
|
* Test Multi-Shop Performance
|
|
*/
|
|
public function testMultiShopPerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
// Test shop context switching
|
|
for ($i = 1; $i <= 100; $i++) {
|
|
Shop::setContext(Shop::CONTEXT_SHOP, rand(1, 5));
|
|
$currentShop = Shop::getContextShopID();
|
|
|
|
Shop::setContext(Shop::CONTEXT_GROUP, rand(1, 3));
|
|
$currentGroup = Shop::getContextShopGroupID();
|
|
|
|
Shop::setContext(Shop::CONTEXT_ALL);
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Multi-Shop Context Switching (100 switches)'] = $executionTime;
|
|
$this->assertLessThan(1.0, $executionTime, 'Multi-shop operations should be faster than 1 second');
|
|
}
|
|
|
|
/**
|
|
* Test Language Performance
|
|
*/
|
|
public function testLanguagePerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
for ($i = 1; $i <= 500; $i++) {
|
|
$languages = Language::getLanguages();
|
|
$activeLanguages = Language::getLanguages(true);
|
|
|
|
$languageId = Language::getIdByIso('de');
|
|
$languageIso = Language::getIsoById(1);
|
|
}
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Language Operations (500 operations)'] = $executionTime;
|
|
$this->assertLessThan(2.0, $executionTime, 'Language operations should be faster than 2 seconds');
|
|
}
|
|
|
|
/**
|
|
* Print performance results
|
|
*/
|
|
protected function printResults()
|
|
{
|
|
echo "\n\n" . str_repeat('=', 60) . "\n";
|
|
echo "PERFORMANCE TEST RESULTS\n";
|
|
echo str_repeat('=', 60) . "\n";
|
|
|
|
foreach ($this->results as $test => $time) {
|
|
if (is_numeric($time)) {
|
|
echo sprintf("%-50s %8.3f seconds\n", $test, $time);
|
|
} else {
|
|
echo sprintf("%-50s %s\n", $test, $time);
|
|
}
|
|
}
|
|
|
|
$totalTime = microtime(true) - $this->startTime;
|
|
echo str_repeat('-', 60) . "\n";
|
|
echo sprintf("%-50s %8.3f seconds\n", "TOTAL EXECUTION TIME", $totalTime);
|
|
echo str_repeat('=', 60) . "\n\n";
|
|
}
|
|
|
|
/**
|
|
* Test overall system performance
|
|
*/
|
|
public function testOverallSystemPerformance()
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
// Simulate typical e-commerce operations
|
|
$this->testProductCreationPerformance();
|
|
$this->testProductRetrievalPerformance();
|
|
$this->testOrderPerformance();
|
|
$this->testCartPerformance();
|
|
$this->testDatabasePerformance();
|
|
$this->testCachePerformance();
|
|
|
|
$endTime = microtime(true);
|
|
$executionTime = $endTime - $startTime;
|
|
|
|
$this->results['Overall System Performance'] = $executionTime;
|
|
$this->assertLessThan(30.0, $executionTime, 'Overall system performance should be acceptable');
|
|
}
|
|
}
|