Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/tests/Integration/Jobs/Schedule/RunTaskJobTest.php
10277 views
1
<?php
2
3
namespace Pterodactyl\Tests\Integration\Jobs\Schedule;
4
5
use Carbon\Carbon;
6
use Carbon\CarbonImmutable;
7
use GuzzleHttp\Psr7\Request;
8
use Pterodactyl\Models\Task;
9
use GuzzleHttp\Psr7\Response;
10
use Pterodactyl\Models\Server;
11
use Pterodactyl\Models\Schedule;
12
use Illuminate\Support\Facades\Bus;
13
use Pterodactyl\Jobs\Schedule\RunTaskJob;
14
use GuzzleHttp\Exception\BadResponseException;
15
use Pterodactyl\Tests\Integration\IntegrationTestCase;
16
use Pterodactyl\Repositories\Wings\DaemonPowerRepository;
17
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
18
19
class RunTaskJobTest extends IntegrationTestCase
20
{
21
/**
22
* An inactive job should not be run by the system.
23
*/
24
public function testInactiveJobIsNotRun()
25
{
26
$server = $this->createServerModel();
27
28
/** @var Schedule $schedule */
29
$schedule = Schedule::factory()->create([
30
'server_id' => $server->id,
31
'is_processing' => true,
32
'last_run_at' => null,
33
'is_active' => false,
34
]);
35
/** @var Task $task */
36
$task = Task::factory()->create(['schedule_id' => $schedule->id, 'is_queued' => true]);
37
38
$job = new RunTaskJob($task);
39
40
Bus::dispatchSync($job);
41
42
$task->refresh();
43
$schedule->refresh();
44
45
$this->assertFalse($task->is_queued);
46
$this->assertFalse($schedule->is_processing);
47
$this->assertFalse($schedule->is_active);
48
$this->assertTrue(CarbonImmutable::now()->isSameAs(\DateTimeInterface::ATOM, $schedule->last_run_at));
49
}
50
51
public function testJobWithInvalidActionThrowsException()
52
{
53
$server = $this->createServerModel();
54
55
/** @var Schedule $schedule */
56
$schedule = Schedule::factory()->create(['server_id' => $server->id]);
57
/** @var Task $task */
58
$task = Task::factory()->create(['schedule_id' => $schedule->id, 'action' => 'foobar']);
59
60
$job = new RunTaskJob($task);
61
62
$this->expectException(\InvalidArgumentException::class);
63
$this->expectExceptionMessage('Invalid task action provided: foobar');
64
Bus::dispatchSync($job);
65
}
66
67
#[\PHPUnit\Framework\Attributes\DataProvider('isManualRunDataProvider')]
68
public function testJobIsExecuted(bool $isManualRun)
69
{
70
$server = $this->createServerModel();
71
72
/** @var Schedule $schedule */
73
$schedule = Schedule::factory()->create([
74
'server_id' => $server->id,
75
'is_active' => !$isManualRun,
76
'is_processing' => true,
77
'last_run_at' => null,
78
]);
79
/** @var Task $task */
80
$task = Task::factory()->create([
81
'schedule_id' => $schedule->id,
82
'action' => Task::ACTION_POWER,
83
'payload' => 'start',
84
'is_queued' => true,
85
'continue_on_failure' => false,
86
]);
87
88
$mock = \Mockery::mock(DaemonPowerRepository::class);
89
$this->instance(DaemonPowerRepository::class, $mock);
90
91
$mock->expects('setServer')->with(\Mockery::on(function ($value) use ($server) {
92
return $value instanceof Server && $value->id === $server->id;
93
}))->andReturnSelf();
94
$mock->expects('send')->with('start')->andReturn(new Response());
95
96
Bus::dispatchSync(new RunTaskJob($task, $isManualRun));
97
98
$task->refresh();
99
$schedule->refresh();
100
101
$this->assertFalse($task->is_queued);
102
$this->assertFalse($schedule->is_processing);
103
$this->assertTrue(CarbonImmutable::now()->isSameAs(\DateTimeInterface::ATOM, $schedule->last_run_at));
104
}
105
106
#[\PHPUnit\Framework\Attributes\DataProvider('isManualRunDataProvider')]
107
public function testExceptionDuringRunIsHandledCorrectly(bool $continueOnFailure)
108
{
109
$server = $this->createServerModel();
110
111
/** @var Schedule $schedule */
112
$schedule = Schedule::factory()->create(['server_id' => $server->id]);
113
/** @var Task $task */
114
$task = Task::factory()->create([
115
'schedule_id' => $schedule->id,
116
'action' => Task::ACTION_POWER,
117
'payload' => 'start',
118
'continue_on_failure' => $continueOnFailure,
119
]);
120
121
$mock = \Mockery::mock(DaemonPowerRepository::class);
122
$this->instance(DaemonPowerRepository::class, $mock);
123
124
$mock->expects('setServer->send')->andThrow(
125
new DaemonConnectionException(new BadResponseException('Bad request', new Request('GET', '/test'), new Response()))
126
);
127
128
if (!$continueOnFailure) {
129
$this->expectException(DaemonConnectionException::class);
130
}
131
132
Bus::dispatchSync(new RunTaskJob($task));
133
134
if ($continueOnFailure) {
135
$task->refresh();
136
$schedule->refresh();
137
138
$this->assertFalse($task->is_queued);
139
$this->assertFalse($schedule->is_processing);
140
$this->assertTrue(CarbonImmutable::now()->isSameAs(\DateTimeInterface::ATOM, $schedule->last_run_at));
141
}
142
}
143
144
/**
145
* Test that a schedule is not executed if the server is suspended.
146
*
147
* @see https://github.com/pterodactyl/panel/issues/4008
148
*/
149
public function testTaskIsNotRunIfServerIsSuspended()
150
{
151
$server = $this->createServerModel([
152
'status' => Server::STATUS_SUSPENDED,
153
]);
154
155
$schedule = Schedule::factory()->for($server)->create([
156
'last_run_at' => Carbon::now()->subHour(),
157
]);
158
159
$task = Task::factory()->for($schedule)->create([
160
'action' => Task::ACTION_POWER,
161
'payload' => 'start',
162
]);
163
164
Bus::dispatchSync(new RunTaskJob($task));
165
166
$task->refresh();
167
$schedule->refresh();
168
169
$this->assertFalse($task->is_queued);
170
$this->assertFalse($schedule->is_processing);
171
$this->assertTrue(Carbon::now()->isSameAs(\DateTimeInterface::ATOM, $schedule->last_run_at));
172
}
173
174
public static function isManualRunDataProvider(): array
175
{
176
return [[true], [false]];
177
}
178
}
179
180