115 lines
4.4 KiB
PHP
115 lines
4.4 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace Tests\Unit;
|
||
|
|
|
||
|
|
use App\Helpers\SshMultiplexingHelper;
|
||
|
|
use Tests\TestCase;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Tests for SSH multiplexing disable functionality.
|
||
|
|
*
|
||
|
|
* These tests verify the parameter signatures for the disableMultiplexing feature
|
||
|
|
* which prevents race conditions when multiple scheduled tasks run concurrently.
|
||
|
|
*
|
||
|
|
* @see https://github.com/coollabsio/coolify/issues/6736
|
||
|
|
*/
|
||
|
|
class SshMultiplexingDisableTest extends TestCase
|
||
|
|
{
|
||
|
|
public function test_generate_ssh_command_method_exists()
|
||
|
|
{
|
||
|
|
$this->assertTrue(
|
||
|
|
method_exists(SshMultiplexingHelper::class, 'generateSshCommand'),
|
||
|
|
'generateSshCommand method should exist'
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_generate_ssh_command_accepts_disable_multiplexing_parameter()
|
||
|
|
{
|
||
|
|
$reflection = new \ReflectionMethod(SshMultiplexingHelper::class, 'generateSshCommand');
|
||
|
|
$parameters = $reflection->getParameters();
|
||
|
|
|
||
|
|
// Should have at least 3 parameters: $server, $command, $disableMultiplexing
|
||
|
|
$this->assertGreaterThanOrEqual(3, count($parameters));
|
||
|
|
|
||
|
|
$disableMultiplexingParam = $parameters[2] ?? null;
|
||
|
|
$this->assertNotNull($disableMultiplexingParam);
|
||
|
|
$this->assertEquals('disableMultiplexing', $disableMultiplexingParam->getName());
|
||
|
|
$this->assertTrue($disableMultiplexingParam->isDefaultValueAvailable());
|
||
|
|
$this->assertFalse($disableMultiplexingParam->getDefaultValue());
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_disable_multiplexing_parameter_is_boolean_type()
|
||
|
|
{
|
||
|
|
$reflection = new \ReflectionMethod(SshMultiplexingHelper::class, 'generateSshCommand');
|
||
|
|
$parameters = $reflection->getParameters();
|
||
|
|
|
||
|
|
$disableMultiplexingParam = $parameters[2] ?? null;
|
||
|
|
$this->assertNotNull($disableMultiplexingParam);
|
||
|
|
|
||
|
|
$type = $disableMultiplexingParam->getType();
|
||
|
|
$this->assertNotNull($type);
|
||
|
|
$this->assertEquals('bool', $type->getName());
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_instant_remote_process_accepts_disable_multiplexing_parameter()
|
||
|
|
{
|
||
|
|
$this->assertTrue(
|
||
|
|
function_exists('instant_remote_process'),
|
||
|
|
'instant_remote_process function should exist'
|
||
|
|
);
|
||
|
|
|
||
|
|
$reflection = new \ReflectionFunction('instant_remote_process');
|
||
|
|
$parameters = $reflection->getParameters();
|
||
|
|
|
||
|
|
// Find the disableMultiplexing parameter
|
||
|
|
$disableMultiplexingParam = null;
|
||
|
|
foreach ($parameters as $param) {
|
||
|
|
if ($param->getName() === 'disableMultiplexing') {
|
||
|
|
$disableMultiplexingParam = $param;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->assertNotNull($disableMultiplexingParam, 'disableMultiplexing parameter should exist');
|
||
|
|
$this->assertTrue($disableMultiplexingParam->isDefaultValueAvailable());
|
||
|
|
$this->assertFalse($disableMultiplexingParam->getDefaultValue());
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_instant_remote_process_disable_multiplexing_is_boolean_type()
|
||
|
|
{
|
||
|
|
$reflection = new \ReflectionFunction('instant_remote_process');
|
||
|
|
$parameters = $reflection->getParameters();
|
||
|
|
|
||
|
|
// Find the disableMultiplexing parameter
|
||
|
|
$disableMultiplexingParam = null;
|
||
|
|
foreach ($parameters as $param) {
|
||
|
|
if ($param->getName() === 'disableMultiplexing') {
|
||
|
|
$disableMultiplexingParam = $param;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->assertNotNull($disableMultiplexingParam);
|
||
|
|
|
||
|
|
$type = $disableMultiplexingParam->getType();
|
||
|
|
$this->assertNotNull($type);
|
||
|
|
$this->assertEquals('bool', $type->getName());
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_multiplexing_is_skipped_when_disabled()
|
||
|
|
{
|
||
|
|
// This test verifies the logic flow by checking the code path
|
||
|
|
// When disableMultiplexing is true, the condition `! $disableMultiplexing && self::isMultiplexingEnabled()`
|
||
|
|
// should evaluate to false, skipping multiplexing entirely
|
||
|
|
|
||
|
|
// We verify the condition logic:
|
||
|
|
// disableMultiplexing = true -> ! true = false -> condition is false -> skip multiplexing
|
||
|
|
$disableMultiplexing = true;
|
||
|
|
$this->assertFalse(! $disableMultiplexing, 'When disableMultiplexing is true, negation should be false');
|
||
|
|
|
||
|
|
// disableMultiplexing = false -> ! false = true -> condition may proceed
|
||
|
|
$disableMultiplexing = false;
|
||
|
|
$this->assertTrue(! $disableMultiplexing, 'When disableMultiplexing is false, negation should be true');
|
||
|
|
}
|
||
|
|
}
|