Skip to content

Commit d6068c1

Browse files
rdeutzSniperSister
andauthored
add loop detection (#29)
* add loop detection #25 * move stuff and add tests * Implement major version check (#28) * implement major version check * add test * move stuff and add tests * mock * cs fix --------- Co-authored-by: David Jardin <[email protected]>
1 parent 9731598 commit d6068c1

File tree

4 files changed

+35
-4
lines changed

4 files changed

+35
-4
lines changed

app/Jobs/UpdateSite.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
use App\Exceptions\UpdateException;
88
use App\Models\Site;
9-
use App\Models\Update;
109
use App\RemoteSite\Connection;
1110
use App\RemoteSite\Responses\PrepareUpdate;
1211
use Illuminate\Contracts\Queue\ShouldQueue;
@@ -31,6 +30,14 @@ public function __construct(protected readonly Site $site, protected string $tar
3130
*/
3231
public function handle(): void
3332
{
33+
$updateCount = $this->site->getUpdateCount($this->targetVersion);
34+
35+
if ($updateCount >= config('autoupdates.max_update_tries')) {
36+
Log::info("Update Loop detected for Site: " . $this->site->id . '; TargetVersion: ' . $this->targetVersion);
37+
38+
return;
39+
}
40+
3441
/** @var Connection $connection */
3542
$connection = $this->site->connection;
3643

app/Models/Site.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ public function getFrontendStatus(): int
6060
return $httpClient->get($this->url)->getStatusCode();
6161
}
6262

63+
public function getUpdateCount(string $targetVersion): int
64+
{
65+
return $this->updates()->where('new_version', $targetVersion)->count();
66+
}
67+
6368
/**
6469
* @return HasMany<Update, $this>
6570
*/

config/autoupdates.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
'healthcheck_interval' => env('HEALTH_CHECK_INTERVAL', 24),
55
'cleanup_site_delay' => env('CLEANUP_SITE_DELAY', 7),
66
'tuf_repo_cachetime' => env('TUF_REPO_CACHETIME', 5),
7+
'max_update_tries' => env('MAX_UPDATE_TRIES', 5),
78
];

tests/Unit/Jobs/UpdateSiteTest.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,24 @@ public function testJobQuitsIfNoUpdateIsAvailable()
5858
$this->assertTrue(true);
5959
}
6060

61+
public function testJobQuitsIfWeDetectALoopForAVersion()
62+
{
63+
$site = $this->getSiteMock([], null, 6);
64+
65+
Log::spy();
66+
67+
$object = new UpdateSite($site, "1.0.1");
68+
$object->handle();
69+
70+
Log::shouldHaveReceived('info')
71+
->once()
72+
->withArgs(function ($message) {
73+
return str_contains($message, 'Update Loop detected for Site');
74+
});
75+
76+
$this->assertTrue(true);
77+
}
78+
6179
public function testJobQuitsIfAvailableUpdateWouldBeAMajorUpdate()
6280
{
6381
$site = $this->getSiteMock(
@@ -80,7 +98,6 @@ public function testJobQuitsIfAvailableUpdateWouldBeAMajorUpdate()
8098

8199
$this->assertTrue(true);
82100
}
83-
84101
public function testJobQuitsIfAvailableUpdateDoesNotMatchTargetVersion()
85102
{
86103
$site = $this->getSiteMock(
@@ -167,7 +184,7 @@ public function testJobWritesSuccessLogForSuccessfulJobs()
167184
$object->handle();
168185
}
169186

170-
protected function getSiteMock(array $responses, array $expectedLogRow = null)
187+
protected function getSiteMock(array $responses, array $expectedLogRow = null, int $updateCount = 0)
171188
{
172189
$connectionMock = $this->getMockBuilder(Connection::class)
173190
->disableOriginalConstructor()
@@ -200,12 +217,13 @@ function ($method) use ($responses) {
200217
}
201218

202219
$siteMock = $this->getMockBuilder(Site::class)
203-
->onlyMethods(['getConnectionAttribute', 'getFrontendStatus', 'updates'])
220+
->onlyMethods(['getConnectionAttribute', 'getFrontendStatus', 'getUpdateCount', 'updates'])
204221
->getMock();
205222

206223
$siteMock->method('updates')->willReturn($updateMock);
207224
$siteMock->method('getConnectionAttribute')->willReturn($connectionMock);
208225
$siteMock->method('getFrontendStatus')->willReturn(200);
226+
$siteMock->method('getUpdateCount')->willReturn($updateCount);
209227
$siteMock->id = 1;
210228
$siteMock->url = "http://example.org";
211229
$siteMock->cms_version = "1.0.0";

0 commit comments

Comments
 (0)