CaiWuXiTong/tests/Unit/Deployment/DeploymentSyncLockTest.php

58 lines
2.6 KiB
PHP

<?php
namespace Tests\Unit\Deployment;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Process;
class DeploymentSyncLockTest extends TestCase
{
public function test_container_replacement_waits_for_sync_and_fails_safely_on_lock_timeout(): void
{
foreach (['activate-release.sh', 'activate-incremental-release.sh'] as $script) {
$contents = file_get_contents(dirname(__DIR__, 3) . '/deploy/' . $script);
$start = strpos($contents, 'exec 8>/run/caiwu-upstream-sync.lock');
$end = strpos($contents, 'PREVIOUS_IMAGE=', $start ?: 0);
$this->assertNotFalse($start, $script);
$this->assertNotFalse($end, $script);
$this->assertLessThan(strpos($contents, 'docker compose -f compose.jiangling.yml up'), $end);
$guard = substr($contents, $start, $end - $start);
$directory = sys_get_temp_dir() . '/caiwu-deploy-lock-' . bin2hex(random_bytes(8));
mkdir($directory, 0700);
$holder = new Process(['sh', '-c', 'exec 8>"$1"; flock 8; touch "$2"; sleep 2', 'holder', $directory . '/sync.lock', $directory . '/held']);
try {
$holder->start();
$deadline = microtime(true) + 3;
while (! file_exists($directory . '/held') && microtime(true) < $deadline) {
usleep(10000);
}
$this->assertFileExists($directory . '/held');
$guard = str_replace('/run/caiwu-upstream-sync.lock', $directory . '/sync.lock', $guard);
$guard .= "touch '$directory/activated'\n";
$timeout = new Process(['sh', '-c', str_replace('-w 1800', '-w 0', $guard)]);
$timeout->run();
$this->assertSame(1, $timeout->getExitCode());
$this->assertStringContainsString('application container was not replaced', $timeout->getErrorOutput());
$this->assertFileDoesNotExist($directory . '/activated');
$release = new Process(['sh', '-c', $guard]);
$release->start();
usleep(100000);
$this->assertTrue($release->isRunning());
$this->assertFileDoesNotExist($directory . '/activated');
$release->wait();
$this->assertTrue($release->isSuccessful(), $release->getErrorOutput());
$this->assertFileExists($directory . '/activated');
} finally {
$holder->stop();
foreach (glob($directory . '/*') as $file) {
unlink($file);
}
rmdir($directory);
}
}
}
}