183 lines
7.1 KiB
PHP
183 lines
7.1 KiB
PHP
<?php
|
|
|
|
/**
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; under version 2
|
|
* of the License (non-upgradable).
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Copyright (c) 2019 (original work) Open Assessment Technologies SA ;
|
|
*/
|
|
|
|
namespace oat\taoDelivery\test\unit\model\Capacity;
|
|
|
|
use common_persistence_KeyValuePersistence;
|
|
use oat\generis\persistence\PersistenceManager;
|
|
use oat\generis\test\TestCase;
|
|
use oat\oatbox\event\EventManager;
|
|
use oat\oatbox\log\LoggerService;
|
|
use oat\oatbox\mutex\LockService;
|
|
use oat\tao\model\metrics\MetricsService;
|
|
use oat\taoDelivery\model\Capacity\InfrastructureCapacityService;
|
|
use oat\taoDelivery\model\Metrics\AwsLoadMetric;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Component\Lock\Factory;
|
|
use Symfony\Component\Lock\LockInterface;
|
|
|
|
class InfrastructureCapacityServiceTest extends TestCase
|
|
{
|
|
/**
|
|
* @dataProvider provideConfigAndMetricDataForCheckCapacity
|
|
*/
|
|
public function testGetCapacity_WhenConfigOptionsAndMetricDataIsProvided_ThenExpectedValuesAreReturned(
|
|
$infrastructureLimit,
|
|
$taoLimit,
|
|
$cachedCapacity,
|
|
$currentInfrastructureLoad,
|
|
$expectedCapacity
|
|
) {
|
|
$service = $this->createInfrastructureCapacityService($infrastructureLimit, $taoLimit, $cachedCapacity, $currentInfrastructureLoad);
|
|
|
|
$this->assertEquals($expectedCapacity, $service->getCapacity());
|
|
}
|
|
|
|
public function testConsume_WhenCachedServerCapacityIsInsufficient_ThenFalseIsReturned()
|
|
{
|
|
$service = $this->createInfrastructureCapacityService(50, 100, 0, 50);
|
|
$this->assertFalse($service->consume());
|
|
}
|
|
|
|
public function testConsume_WhenCachedServerCapacityIsSufficient_ThenTrueReturnedAndCapacityDecremented()
|
|
{
|
|
$service = $this->createInfrastructureCapacityService(50, 100, 1, 50, true);
|
|
$this->assertTrue($service->consume());
|
|
}
|
|
|
|
/**
|
|
* returns array with following structure:
|
|
* <code>
|
|
* array(
|
|
* array(
|
|
* (int) infrastructureLimit,
|
|
* (int) taoLimit,
|
|
* (int) cachedCapacity,
|
|
* (int) currentInfrastructureLoad,
|
|
* (int) expectedCapacity
|
|
* )
|
|
* )
|
|
* </code>
|
|
*
|
|
* @return array[]
|
|
*/
|
|
public function provideConfigAndMetricDataForCheckCapacity()
|
|
{
|
|
return [
|
|
// when there is no cached capacity, and server load is lower than configured threshold,
|
|
// then calculated capacity is proportional amount from configured TAO limit
|
|
[80, 3000, null, 40, 1500], // no cached capacity, server load limit 80%, current load 40%
|
|
[90, 3000, null, 30, 2000], // no cached capacity, server load limit 90%, current load 30%
|
|
// when there is no cached capacity, and server load is larger than configured threshold,
|
|
// then calculated capacity is negative and a zero capacity is returned
|
|
[80, 3000, null, 80, 0],
|
|
[80, 3000, null, 81, 0],
|
|
[80, 3000, null, 100, 0],
|
|
// when there is a cached calculated server capacity, then it is returned
|
|
[80, 3000, 5, 100, 5],
|
|
[80, 3000, 50, 100, 50],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param $infrastructureLimit
|
|
* @param $taoLimit
|
|
* @param $cachedCapacity
|
|
* @param $currentInfrastructureLoad
|
|
* @param bool $shouldDecrementCapacity
|
|
* @return InfrastructureCapacityService
|
|
*/
|
|
private function createInfrastructureCapacityService(
|
|
$infrastructureLimit,
|
|
$taoLimit,
|
|
$cachedCapacity,
|
|
$currentInfrastructureLoad,
|
|
$shouldDecrementCapacity = false
|
|
) {
|
|
$serviceLocatorMock = $this->getServiceLocatorMock([
|
|
LockService::SERVICE_ID => $this->createLockServiceMock(),
|
|
PersistenceManager::SERVICE_ID => $this->createPersistenceManagerMock($cachedCapacity, $shouldDecrementCapacity),
|
|
EventManager::SERVICE_ID => $this->createMock(EventManager::class),
|
|
LoggerService::SERVICE_ID => $this->createMock(LoggerInterface::class),
|
|
MetricsService::class => $this->createMetricsMock($currentInfrastructureLoad),
|
|
]);
|
|
$service = new InfrastructureCapacityService([
|
|
InfrastructureCapacityService::OPTION_INFRASTRUCTURE_LOAD_LIMIT => $infrastructureLimit,
|
|
InfrastructureCapacityService::OPTION_TAO_CAPACITY_LIMIT => $taoLimit,
|
|
InfrastructureCapacityService::OPTION_TTL => 60,
|
|
InfrastructureCapacityService::OPTION_PERSISTENCE => 'testPersistence',
|
|
]);
|
|
$service->setServiceLocator($serviceLocatorMock);
|
|
|
|
return $service;
|
|
}
|
|
|
|
/**
|
|
* @param $currentInfrastructureLoad
|
|
* @return \oat\generis\test\MockObject
|
|
*/
|
|
private function createMetricsMock($currentInfrastructureLoad)
|
|
{
|
|
$awsLoadMetricMock = $this->createMock(AwsLoadMetric::class);
|
|
$awsLoadMetricMock->method('collect')->willReturn($currentInfrastructureLoad);
|
|
$metricsServiceMock = $this->createMock(MetricsService::class);
|
|
$metricsServiceMock->method('getOneMetric')->willReturn($awsLoadMetricMock);
|
|
|
|
return $metricsServiceMock;
|
|
}
|
|
|
|
/**
|
|
* @param $cachedCapacity
|
|
* @return \oat\generis\test\MockObject
|
|
*/
|
|
private function createPersistenceManagerMock($cachedCapacity, $shouldDecrementCapacity)
|
|
{
|
|
$persistenceManagerMock = $this->createMock(PersistenceManager::class);
|
|
$persistenceMock = $this->createMock(common_persistence_KeyValuePersistence::class);
|
|
$persistenceMock->method('get')->willReturnCallback(function ($argument) use ($cachedCapacity) {
|
|
switch ($argument) {
|
|
case InfrastructureCapacityService::CAPACITY_TO_PROVIDE_CACHE_KEY:
|
|
case InfrastructureCapacityService::CAPACITY_TO_CONSUME_CACHE_KEY:
|
|
return $cachedCapacity;
|
|
}
|
|
});
|
|
if ($shouldDecrementCapacity) {
|
|
$persistenceMock->expects($this->once())->method('decr')->willReturn(true);
|
|
}
|
|
$persistenceManagerMock->method('getPersistenceById')->willReturn($persistenceMock);
|
|
|
|
return $persistenceManagerMock;
|
|
}
|
|
|
|
/**
|
|
* @return \oat\generis\test\MockObject
|
|
*/
|
|
private function createLockServiceMock()
|
|
{
|
|
$lockServiceMock = $this->createMock(LockService::class);
|
|
$lockFactoryMock = $this->createMock(Factory::class);
|
|
$lockServiceMock->method('getLockFactory')->willReturn($lockFactoryMock);
|
|
$lockMock = $this->createMock(LockInterface::class);
|
|
$lockFactoryMock->method('createLock')->willReturn($lockMock);
|
|
|
|
return $lockServiceMock;
|
|
}
|
|
}
|