Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/tests/Integration/Services/Databases/DeployServerDatabaseServiceTest.php
7460 views
1
<?php
2
3
namespace Pterodactyl\Tests\Integration\Services\Databases;
4
5
use Mockery\MockInterface;
6
use Pterodactyl\Models\Node;
7
use Pterodactyl\Models\Database;
8
use Pterodactyl\Models\DatabaseHost;
9
use Pterodactyl\Tests\Integration\IntegrationTestCase;
10
use Pterodactyl\Services\Databases\DatabaseManagementService;
11
use Pterodactyl\Services\Databases\DeployServerDatabaseService;
12
use Pterodactyl\Exceptions\Service\Database\NoSuitableDatabaseHostException;
13
14
class DeployServerDatabaseServiceTest extends IntegrationTestCase
15
{
16
private MockInterface $managementService;
17
18
/**
19
* Setup tests.
20
*/
21
public function setUp(): void
22
{
23
parent::setUp();
24
25
$this->managementService = \Mockery::mock(DatabaseManagementService::class);
26
$this->swap(DatabaseManagementService::class, $this->managementService);
27
}
28
29
/**
30
* Ensure we reset the config to the expected value.
31
*/
32
protected function tearDown(): void
33
{
34
config()->set('pterodactyl.client_features.databases.allow_random', true);
35
36
Database::query()->delete();
37
DatabaseHost::query()->delete();
38
39
parent::tearDown();
40
}
41
42
/**
43
* Test that an error is thrown if either the database name or the remote host are empty.
44
*/
45
#[\PHPUnit\Framework\Attributes\DataProvider('invalidDataProvider')]
46
public function testErrorIsThrownIfDatabaseNameIsEmpty(array $data)
47
{
48
$server = $this->createServerModel();
49
50
$this->expectException(\InvalidArgumentException::class);
51
$this->expectExceptionMessageMatches('/^Expected a non-empty value\. Got: /');
52
$this->getService()->handle($server, $data);
53
}
54
55
/**
56
* Test that an error is thrown if there are no database hosts on the same node as the
57
* server and the allow_random config value is false.
58
*/
59
public function testErrorIsThrownIfNoDatabaseHostsExistOnNode()
60
{
61
$server = $this->createServerModel();
62
63
$node = Node::factory()->create(['location_id' => $server->location->id]);
64
DatabaseHost::factory()->create(['node_id' => $node->id]);
65
66
config()->set('pterodactyl.client_features.databases.allow_random', false);
67
68
$this->expectException(NoSuitableDatabaseHostException::class);
69
70
$this->getService()->handle($server, [
71
'database' => 'something',
72
'remote' => '%',
73
]);
74
}
75
76
/**
77
* Test that an error is thrown if no database hosts exist at all on the system.
78
*/
79
public function testErrorIsThrownIfNoDatabaseHostsExistOnSystem()
80
{
81
$server = $this->createServerModel();
82
83
$this->expectException(NoSuitableDatabaseHostException::class);
84
85
$this->getService()->handle($server, [
86
'database' => 'something',
87
'remote' => '%',
88
]);
89
}
90
91
/**
92
* Test that a database host on the same node as the server is preferred.
93
*/
94
public function testDatabaseHostOnSameNodeIsPreferred()
95
{
96
$server = $this->createServerModel();
97
98
$node = Node::factory()->create(['location_id' => $server->location->id]);
99
DatabaseHost::factory()->create(['node_id' => $node->id]);
100
$host = DatabaseHost::factory()->create(['node_id' => $server->node_id]);
101
102
$this->managementService->expects('create')->with($server, [
103
'database_host_id' => $host->id,
104
'database' => "s{$server->id}_something",
105
'remote' => '%',
106
])->andReturns(new Database());
107
108
$response = $this->getService()->handle($server, [
109
'database' => 'something',
110
'remote' => '%',
111
]);
112
113
$this->assertInstanceOf(Database::class, $response);
114
}
115
116
/**
117
* Test that a database host not assigned to the same node as the server is used if
118
* there are no same-node hosts and the allow_random configuration value is set to
119
* true.
120
*/
121
public function testDatabaseHostIsSelectedIfNoSuitableHostExistsOnSameNode()
122
{
123
$server = $this->createServerModel();
124
125
$node = Node::factory()->create(['location_id' => $server->location->id]);
126
$host = DatabaseHost::factory()->create(['node_id' => $node->id]);
127
128
$this->managementService->expects('create')->with($server, [
129
'database_host_id' => $host->id,
130
'database' => "s{$server->id}_something",
131
'remote' => '%',
132
])->andReturns(new Database());
133
134
$response = $this->getService()->handle($server, [
135
'database' => 'something',
136
'remote' => '%',
137
]);
138
139
$this->assertInstanceOf(Database::class, $response);
140
}
141
142
public static function invalidDataProvider(): array
143
{
144
return [
145
[['remote' => '%']],
146
[['database' => null, 'remote' => '%']],
147
[['database' => '', 'remote' => '%']],
148
[['database' => '']],
149
[['database' => '', 'remote' => '']],
150
];
151
}
152
153
private function getService(): DeployServerDatabaseService
154
{
155
return $this->app->make(DeployServerDatabaseService::class);
156
}
157
}
158
159