Skip to content

Commit d5bf873

Browse files
committed
Add unit tests for RunTaskJob.
1 parent 238ce43 commit d5bf873

File tree

4 files changed

+219
-99
lines changed

4 files changed

+219
-99
lines changed

app/Http/Controllers/Admin/NodesController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ public function viewServers($node)
248248
*
249249
* @throws \Pterodactyl\Exceptions\DisplayException
250250
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
251+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
251252
*/
252253
public function updateSettings(NodeFormRequest $request, Node $node)
253254
{

app/Jobs/Schedule/RunTaskJob.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ class RunTaskJob extends Job implements ShouldQueue
6161
*/
6262
public function __construct($task, $schedule)
6363
{
64-
Assert::integerish($task, 'First argument passed to constructor must be numeric, received %s.');
64+
Assert::integerish($task, 'First argument passed to constructor must be integer, received %s.');
65+
Assert::integerish($schedule, 'Second argument passed to constructor must be integer, received %s.');
6566

6667
$this->queue = app()->make('config')->get('pterodactyl.queues.standard');
6768
$this->task = $task;

app/Jobs/SendScheduledTask.php

Lines changed: 0 additions & 98 deletions
This file was deleted.
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
<?php
2+
/*
3+
* Pterodactyl - Panel
4+
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
5+
*
6+
* This software is licensed under the terms of the MIT license.
7+
* https://opensource.org/licenses/MIT
8+
*/
9+
10+
namespace Tests\Unit\Jobs\Schedule;
11+
12+
use Mockery as m;
13+
use Carbon\Carbon;
14+
use Tests\TestCase;
15+
use Pterodactyl\Models\Task;
16+
use Pterodactyl\Models\Server;
17+
use Pterodactyl\Models\Schedule;
18+
use Illuminate\Support\Facades\Bus;
19+
use Pterodactyl\Jobs\Schedule\RunTaskJob;
20+
use Illuminate\Contracts\Config\Repository;
21+
use Pterodactyl\Contracts\Repository\TaskRepositoryInterface;
22+
use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService;
23+
use Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface;
24+
use Pterodactyl\Contracts\Repository\Daemon\PowerRepositoryInterface;
25+
use Pterodactyl\Contracts\Repository\Daemon\CommandRepositoryInterface;
26+
27+
class RunTaskJobTest extends TestCase
28+
{
29+
/**
30+
* @var \Pterodactyl\Contracts\Repository\Daemon\CommandRepositoryInterface|\Mockery\Mock
31+
*/
32+
protected $commandRepository;
33+
34+
/**
35+
* @var \Illuminate\Contracts\Config\Repository|\Mockery\Mock
36+
*/
37+
protected $config;
38+
39+
/**
40+
* @var \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService|\Mockery\Mock
41+
*/
42+
protected $keyProviderService;
43+
44+
/**
45+
* @var \Pterodactyl\Contracts\Repository\Daemon\PowerRepositoryInterface|\Mockery\Mock
46+
*/
47+
protected $powerRepository;
48+
49+
/**
50+
* @var \Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface|\Mockery\Mock
51+
*/
52+
protected $scheduleRepository;
53+
54+
/**
55+
* @var \Pterodactyl\Contracts\Repository\TaskRepositoryInterface|\Mockery\Mock
56+
*/
57+
protected $taskRepository;
58+
59+
/**
60+
* Setup tests.
61+
*/
62+
public function setUp()
63+
{
64+
parent::setUp();
65+
Bus::fake();
66+
67+
$this->commandRepository = m::mock(CommandRepositoryInterface::class);
68+
$this->config = m::mock(Repository::class);
69+
$this->keyProviderService = m::mock(DaemonKeyProviderService::class);
70+
$this->powerRepository = m::mock(PowerRepositoryInterface::class);
71+
$this->scheduleRepository = m::mock(ScheduleRepositoryInterface::class);
72+
$this->taskRepository = m::mock(TaskRepositoryInterface::class);
73+
74+
$this->app->instance(Repository::class, $this->config);
75+
$this->app->instance(TaskRepositoryInterface::class, $this->taskRepository);
76+
$this->app->instance(ScheduleRepositoryInterface::class, $this->scheduleRepository);
77+
}
78+
79+
/**
80+
* Test power option passed to job.
81+
*/
82+
public function testPowerAction()
83+
{
84+
Carbon::setTestNow();
85+
86+
$schedule = factory(Schedule::class)->make();
87+
$task = factory(Task::class)->make(['action' => 'power', 'sequence_id' => 1]);
88+
$server = factory(Server::class)->make();
89+
$task->server = $server;
90+
91+
$this->taskRepository->shouldReceive('getTaskWithServer')->with($task->id)->once()->andReturn($task);
92+
$this->keyProviderService->shouldReceive('handle')->with($server->id, $server->owner_id)->once()->andReturn('123456');
93+
$this->powerRepository->shouldReceive('setNode')->with($server->node_id)->once()->andReturnSelf()
94+
->shouldReceive('setAccessServer')->with($server->uuid)->once()->andReturnSelf()
95+
->shouldReceive('setAccessToken')->with('123456')->once()->andReturnSelf()
96+
->shouldReceive('sendSignal')->with($task->payload)->once()->andReturnNull();
97+
98+
$this->taskRepository->shouldReceive('update')->with($task->id, ['is_queued' => false])->once()->andReturnNull();
99+
$this->taskRepository->shouldReceive('getNextTask')->with($schedule->id, $task->sequence_id)->once()->andReturnNull();
100+
101+
$this->scheduleRepository->shouldReceive('withoutFresh->update')->with($schedule->id, [
102+
'is_processing' => false,
103+
'last_run_at' => Carbon::now()->toDateTimeString(),
104+
])->once()->andReturnNull();
105+
106+
$this->getJobInstance($task->id, $schedule->id);
107+
108+
Bus::assertNotDispatched(RunTaskJob::class);
109+
}
110+
111+
/**
112+
* Test commmand action passed to job.
113+
*/
114+
public function testCommandAction()
115+
{
116+
Carbon::setTestNow();
117+
118+
$schedule = factory(Schedule::class)->make();
119+
$task = factory(Task::class)->make(['action' => 'command', 'sequence_id' => 1]);
120+
$server = factory(Server::class)->make();
121+
$task->server = $server;
122+
123+
$this->taskRepository->shouldReceive('getTaskWithServer')->with($task->id)->once()->andReturn($task);
124+
$this->keyProviderService->shouldReceive('handle')->with($server->id, $server->owner_id)->once()->andReturn('123456');
125+
$this->commandRepository->shouldReceive('setNode')->with($server->node_id)->once()->andReturnSelf()
126+
->shouldReceive('setAccessServer')->with($server->uuid)->once()->andReturnSelf()
127+
->shouldReceive('setAccessToken')->with('123456')->once()->andReturnSelf()
128+
->shouldReceive('send')->with($task->payload)->once()->andReturnNull();
129+
130+
$this->taskRepository->shouldReceive('update')->with($task->id, ['is_queued' => false])->once()->andReturnNull();
131+
$this->taskRepository->shouldReceive('getNextTask')->with($schedule->id, $task->sequence_id)->once()->andReturnNull();
132+
133+
$this->scheduleRepository->shouldReceive('withoutFresh->update')->with($schedule->id, [
134+
'is_processing' => false,
135+
'last_run_at' => Carbon::now()->toDateTimeString(),
136+
])->once()->andReturnNull();
137+
138+
$this->getJobInstance($task->id, $schedule->id);
139+
140+
Bus::assertNotDispatched(RunTaskJob::class);
141+
}
142+
143+
/**
144+
* Test that the next task in the list is queued if the current one is not the last.
145+
*/
146+
public function testNextTaskQueuedIfExists()
147+
{
148+
Carbon::setTestNow();
149+
150+
$schedule = factory(Schedule::class)->make();
151+
$task = factory(Task::class)->make(['action' => 'command', 'sequence_id' => 1]);
152+
$server = factory(Server::class)->make();
153+
$task->server = $server;
154+
155+
$this->taskRepository->shouldReceive('getTaskWithServer')->with($task->id)->once()->andReturn($task);
156+
$this->keyProviderService->shouldReceive('handle')->with($server->id, $server->owner_id)->once()->andReturn('123456');
157+
$this->commandRepository->shouldReceive('setNode')->with($server->node_id)->once()->andReturnSelf()
158+
->shouldReceive('setAccessServer')->with($server->uuid)->once()->andReturnSelf()
159+
->shouldReceive('setAccessToken')->with('123456')->once()->andReturnSelf()
160+
->shouldReceive('send')->with($task->payload)->once()->andReturnNull();
161+
162+
$this->taskRepository->shouldReceive('update')->with($task->id, ['is_queued' => false])->once()->andReturnNull();
163+
164+
$nextTask = factory(Task::class)->make();
165+
$this->taskRepository->shouldReceive('getNextTask')->with($schedule->id, $task->sequence_id)->once()->andReturn($nextTask);
166+
$this->taskRepository->shouldReceive('update')->with($nextTask->id, [
167+
'is_queued' => true,
168+
])->once()->andReturnNull();
169+
170+
$this->getJobInstance($task->id, $schedule->id);
171+
172+
Bus::assertDispatched(RunTaskJob::class, function ($job) use ($nextTask, $schedule) {
173+
$this->assertEquals($nextTask->id, $job->task, 'Assert correct task ID is passed to job.');
174+
$this->assertEquals($schedule->id, $job->schedule, 'Assert correct schedule ID is passed to job.');
175+
$this->assertEquals($nextTask->time_offset, $job->delay, 'Assert correct job delay time is set.');
176+
177+
return true;
178+
});
179+
}
180+
181+
/**
182+
* Test that an exception is thrown if an invalid task action is supplied.
183+
*
184+
* @expectedException \InvalidArgumentException
185+
* @expectedExceptionMessage Cannot run a task that points to a non-existant action.
186+
*/
187+
public function testInvalidActionPassedToJob()
188+
{
189+
$task = factory(Task::class)->make(['action' => 'invalid', 'sequence_id' => 1]);
190+
$task->server = [];
191+
192+
$this->taskRepository->shouldReceive('getTaskWithServer')->with($task->id)->once()->andReturn($task);
193+
194+
$this->getJobInstance($task->id, 1234);
195+
}
196+
197+
/**
198+
* Run the job using the mocks provided.
199+
*
200+
* @param int $task
201+
* @param int $schedule
202+
*
203+
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
204+
* @throws \Pterodactyl\Exceptions\Repository\Daemon\InvalidPowerSignalException
205+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
206+
*/
207+
private function getJobInstance($task, $schedule)
208+
{
209+
return (new RunTaskJob($task, $schedule))->handle(
210+
$this->commandRepository,
211+
$this->keyProviderService,
212+
$this->powerRepository,
213+
$this->taskRepository
214+
);
215+
}
216+
}

0 commit comments

Comments
 (0)