Path: blob/1.0-develop/tests/Integration/Services/Allocations/FindAssignableAllocationServiceTest.php
7460 views
<?php12namespace Pterodactyl\Tests\Integration\Services\Allocations;34use Pterodactyl\Models\Allocation;5use Pterodactyl\Tests\Integration\IntegrationTestCase;6use Pterodactyl\Services\Allocations\FindAssignableAllocationService;7use Pterodactyl\Exceptions\Service\Allocation\AutoAllocationNotEnabledException;8use Pterodactyl\Exceptions\Service\Allocation\NoAutoAllocationSpaceAvailableException;910class FindAssignableAllocationServiceTest extends IntegrationTestCase11{12/**13* Setup tests.14*/15public function setUp(): void16{17parent::setUp();1819config()->set('pterodactyl.client_features.allocations.enabled', true);20config()->set('pterodactyl.client_features.allocations.range_start', 0);21config()->set('pterodactyl.client_features.allocations.range_end', 0);22}2324/**25* Test that an unassigned allocation is preferred rather than creating an entirely new26* allocation for the server.27*/28public function testExistingAllocationIsPreferred()29{30$server = $this->createServerModel();3132$created = Allocation::factory()->create([33'node_id' => $server->node_id,34'ip' => $server->allocation->ip,35]);3637$response = $this->getService()->handle($server);3839$this->assertSame($created->id, $response->id);40$this->assertSame($server->allocation->ip, $response->ip);41$this->assertSame($server->node_id, $response->node_id);42$this->assertSame($server->id, $response->server_id);43$this->assertNotSame($server->allocation_id, $response->id);44}4546/**47* Test that a new allocation is created if there is not a free one available.48*/49public function testNewAllocationIsCreatedIfOneIsNotFound()50{51$server = $this->createServerModel();52config()->set('pterodactyl.client_features.allocations.range_start', 5000);53config()->set('pterodactyl.client_features.allocations.range_end', 5005);5455$response = $this->getService()->handle($server);56$this->assertSame($server->id, $response->server_id);57$this->assertSame($server->allocation->ip, $response->ip);58$this->assertSame($server->node_id, $response->node_id);59$this->assertNotSame($server->allocation_id, $response->id);60$this->assertTrue($response->port >= 5000 && $response->port <= 5005);61}6263/**64* Test that a currently assigned port is never assigned to a server.65*/66public function testOnlyPortNotInUseIsCreated()67{68$server = $this->createServerModel();69$server2 = $this->createServerModel(['node_id' => $server->node_id]);7071config()->set('pterodactyl.client_features.allocations.range_start', 5000);72config()->set('pterodactyl.client_features.allocations.range_end', 5001);7374Allocation::factory()->create([75'server_id' => $server2->id,76'node_id' => $server->node_id,77'ip' => $server->allocation->ip,78'port' => 5000,79]);8081$response = $this->getService()->handle($server);82$this->assertSame(5001, $response->port);83}8485public function testExceptionIsThrownIfNoMoreAllocationsCanBeCreatedInRange()86{87$server = $this->createServerModel();88$server2 = $this->createServerModel(['node_id' => $server->node_id]);89config()->set('pterodactyl.client_features.allocations.range_start', 5000);90config()->set('pterodactyl.client_features.allocations.range_end', 5005);9192for ($i = 5000; $i <= 5005; ++$i) {93Allocation::factory()->create([94'ip' => $server->allocation->ip,95'port' => $i,96'node_id' => $server->node_id,97'server_id' => $server2->id,98]);99}100101$this->expectException(NoAutoAllocationSpaceAvailableException::class);102$this->expectExceptionMessage('Cannot assign additional allocation: no more space available on node.');103104$this->getService()->handle($server);105}106107/**108* Test that we only auto-allocate from the current server's IP address space, and not a random109* IP address available on that node.110*/111public function testExceptionIsThrownIfOnlyFreePortIsOnADifferentIp()112{113$server = $this->createServerModel();114115Allocation::factory()->times(5)->create(['node_id' => $server->node_id]);116117$this->expectException(NoAutoAllocationSpaceAvailableException::class);118$this->expectExceptionMessage('Cannot assign additional allocation: no more space available on node.');119120$this->getService()->handle($server);121}122123public function testExceptionIsThrownIfStartOrEndRangeIsNotDefined()124{125$server = $this->createServerModel();126127$this->expectException(NoAutoAllocationSpaceAvailableException::class);128$this->expectExceptionMessage('Cannot assign additional allocation: no more space available on node.');129130$this->getService()->handle($server);131}132133public function testExceptionIsThrownIfStartOrEndRangeIsNotNumeric()134{135$server = $this->createServerModel();136config()->set('pterodactyl.client_features.allocations.range_start', 'hodor');137config()->set('pterodactyl.client_features.allocations.range_end', 10);138139try {140$this->getService()->handle($server);141$this->fail('This assertion should not be reached.');142} catch (\Exception $exception) {143$this->assertInstanceOf(\InvalidArgumentException::class, $exception);144$this->assertSame('Expected an integerish value. Got: string', $exception->getMessage());145}146147config()->set('pterodactyl.client_features.allocations.range_start', 10);148config()->set('pterodactyl.client_features.allocations.range_end', 'hodor');149150try {151$this->getService()->handle($server);152$this->fail('This assertion should not be reached.');153} catch (\Exception $exception) {154$this->assertInstanceOf(\InvalidArgumentException::class, $exception);155$this->assertSame('Expected an integerish value. Got: string', $exception->getMessage());156}157}158159public function testExceptionIsThrownIfFeatureIsNotEnabled()160{161config()->set('pterodactyl.client_features.allocations.enabled', false);162$server = $this->createServerModel();163164$this->expectException(AutoAllocationNotEnabledException::class);165166$this->getService()->handle($server);167}168169private function getService(): FindAssignableAllocationService170{171return $this->app->make(FindAssignableAllocationService::class);172}173}174175176