Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/tests/Integration/Services/Allocations/FindAssignableAllocationServiceTest.php
7460 views
1
<?php
2
3
namespace Pterodactyl\Tests\Integration\Services\Allocations;
4
5
use Pterodactyl\Models\Allocation;
6
use Pterodactyl\Tests\Integration\IntegrationTestCase;
7
use Pterodactyl\Services\Allocations\FindAssignableAllocationService;
8
use Pterodactyl\Exceptions\Service\Allocation\AutoAllocationNotEnabledException;
9
use Pterodactyl\Exceptions\Service\Allocation\NoAutoAllocationSpaceAvailableException;
10
11
class FindAssignableAllocationServiceTest extends IntegrationTestCase
12
{
13
/**
14
* Setup tests.
15
*/
16
public function setUp(): void
17
{
18
parent::setUp();
19
20
config()->set('pterodactyl.client_features.allocations.enabled', true);
21
config()->set('pterodactyl.client_features.allocations.range_start', 0);
22
config()->set('pterodactyl.client_features.allocations.range_end', 0);
23
}
24
25
/**
26
* Test that an unassigned allocation is preferred rather than creating an entirely new
27
* allocation for the server.
28
*/
29
public function testExistingAllocationIsPreferred()
30
{
31
$server = $this->createServerModel();
32
33
$created = Allocation::factory()->create([
34
'node_id' => $server->node_id,
35
'ip' => $server->allocation->ip,
36
]);
37
38
$response = $this->getService()->handle($server);
39
40
$this->assertSame($created->id, $response->id);
41
$this->assertSame($server->allocation->ip, $response->ip);
42
$this->assertSame($server->node_id, $response->node_id);
43
$this->assertSame($server->id, $response->server_id);
44
$this->assertNotSame($server->allocation_id, $response->id);
45
}
46
47
/**
48
* Test that a new allocation is created if there is not a free one available.
49
*/
50
public function testNewAllocationIsCreatedIfOneIsNotFound()
51
{
52
$server = $this->createServerModel();
53
config()->set('pterodactyl.client_features.allocations.range_start', 5000);
54
config()->set('pterodactyl.client_features.allocations.range_end', 5005);
55
56
$response = $this->getService()->handle($server);
57
$this->assertSame($server->id, $response->server_id);
58
$this->assertSame($server->allocation->ip, $response->ip);
59
$this->assertSame($server->node_id, $response->node_id);
60
$this->assertNotSame($server->allocation_id, $response->id);
61
$this->assertTrue($response->port >= 5000 && $response->port <= 5005);
62
}
63
64
/**
65
* Test that a currently assigned port is never assigned to a server.
66
*/
67
public function testOnlyPortNotInUseIsCreated()
68
{
69
$server = $this->createServerModel();
70
$server2 = $this->createServerModel(['node_id' => $server->node_id]);
71
72
config()->set('pterodactyl.client_features.allocations.range_start', 5000);
73
config()->set('pterodactyl.client_features.allocations.range_end', 5001);
74
75
Allocation::factory()->create([
76
'server_id' => $server2->id,
77
'node_id' => $server->node_id,
78
'ip' => $server->allocation->ip,
79
'port' => 5000,
80
]);
81
82
$response = $this->getService()->handle($server);
83
$this->assertSame(5001, $response->port);
84
}
85
86
public function testExceptionIsThrownIfNoMoreAllocationsCanBeCreatedInRange()
87
{
88
$server = $this->createServerModel();
89
$server2 = $this->createServerModel(['node_id' => $server->node_id]);
90
config()->set('pterodactyl.client_features.allocations.range_start', 5000);
91
config()->set('pterodactyl.client_features.allocations.range_end', 5005);
92
93
for ($i = 5000; $i <= 5005; ++$i) {
94
Allocation::factory()->create([
95
'ip' => $server->allocation->ip,
96
'port' => $i,
97
'node_id' => $server->node_id,
98
'server_id' => $server2->id,
99
]);
100
}
101
102
$this->expectException(NoAutoAllocationSpaceAvailableException::class);
103
$this->expectExceptionMessage('Cannot assign additional allocation: no more space available on node.');
104
105
$this->getService()->handle($server);
106
}
107
108
/**
109
* Test that we only auto-allocate from the current server's IP address space, and not a random
110
* IP address available on that node.
111
*/
112
public function testExceptionIsThrownIfOnlyFreePortIsOnADifferentIp()
113
{
114
$server = $this->createServerModel();
115
116
Allocation::factory()->times(5)->create(['node_id' => $server->node_id]);
117
118
$this->expectException(NoAutoAllocationSpaceAvailableException::class);
119
$this->expectExceptionMessage('Cannot assign additional allocation: no more space available on node.');
120
121
$this->getService()->handle($server);
122
}
123
124
public function testExceptionIsThrownIfStartOrEndRangeIsNotDefined()
125
{
126
$server = $this->createServerModel();
127
128
$this->expectException(NoAutoAllocationSpaceAvailableException::class);
129
$this->expectExceptionMessage('Cannot assign additional allocation: no more space available on node.');
130
131
$this->getService()->handle($server);
132
}
133
134
public function testExceptionIsThrownIfStartOrEndRangeIsNotNumeric()
135
{
136
$server = $this->createServerModel();
137
config()->set('pterodactyl.client_features.allocations.range_start', 'hodor');
138
config()->set('pterodactyl.client_features.allocations.range_end', 10);
139
140
try {
141
$this->getService()->handle($server);
142
$this->fail('This assertion should not be reached.');
143
} catch (\Exception $exception) {
144
$this->assertInstanceOf(\InvalidArgumentException::class, $exception);
145
$this->assertSame('Expected an integerish value. Got: string', $exception->getMessage());
146
}
147
148
config()->set('pterodactyl.client_features.allocations.range_start', 10);
149
config()->set('pterodactyl.client_features.allocations.range_end', 'hodor');
150
151
try {
152
$this->getService()->handle($server);
153
$this->fail('This assertion should not be reached.');
154
} catch (\Exception $exception) {
155
$this->assertInstanceOf(\InvalidArgumentException::class, $exception);
156
$this->assertSame('Expected an integerish value. Got: string', $exception->getMessage());
157
}
158
}
159
160
public function testExceptionIsThrownIfFeatureIsNotEnabled()
161
{
162
config()->set('pterodactyl.client_features.allocations.enabled', false);
163
$server = $this->createServerModel();
164
165
$this->expectException(AutoAllocationNotEnabledException::class);
166
167
$this->getService()->handle($server);
168
}
169
170
private function getService(): FindAssignableAllocationService
171
{
172
return $this->app->make(FindAssignableAllocationService::class);
173
}
174
}
175
176