diff --git a/.ci/ubuntu/gha-setup.sh b/.ci/ubuntu/gha-setup.sh index 73cc741bb..ab66c49c9 100755 --- a/.ci/ubuntu/gha-setup.sh +++ b/.ci/ubuntu/gha-setup.sh @@ -54,6 +54,7 @@ function start_toxiproxy docker run --detach $docker_pull_args \ --name "$toxiproxy_docker_name" \ --hostname "$toxiproxy_docker_name" \ + --add-host=host.docker.internal:host-gateway \ --publish 8474:8474 \ --publish 5673:5673 \ --network "$docker_network_name" \ @@ -133,3 +134,7 @@ start_rabbitmq wait_rabbitmq get_rabbitmq_id + +export TOXIPROXY_HOST="${TOXIPROXY_HOST:-localhost}" +export TOXIPROXY_AMQP_TARGET="${TOXIPROXY_AMQP_TARGET:-host.docker.internal}" +export TOXIPROXY_AMQP_PORT="${TOXIPROXY_AMQP_PORT:-5673}" diff --git a/.ci/ubuntu/rabbitmq.conf b/.ci/ubuntu/rabbitmq.conf index 64ed2d30e..66050d70f 100644 --- a/.ci/ubuntu/rabbitmq.conf +++ b/.ci/ubuntu/rabbitmq.conf @@ -24,3 +24,7 @@ ssl_options.fail_if_no_peer_cert = false management.ssl.certfile = /etc/rabbitmq/certs/server_certificate.pem management.ssl.keyfile = /etc/rabbitmq/certs/server_key.pem management.ssl.cacertfile = /etc/rabbitmq/certs/ca_certificate.pem + +# RabbitMQ 4.x blocks transient non-exclusive queues by default; the test suite +# still declares queues with the AMQP defaults (non-durable, non-exclusive). +deprecated_features.permit.transient_nonexcl_queues = true diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index cc4d5f6c5..b548736c8 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -44,7 +44,7 @@ jobs: name: PHP ${{ matrix.php }} + phpseclib ${{ matrix.phpseclib }} env: TOXIPROXY_HOST: localhost - TOXIPROXY_AMQP_TARGET: php-amqplib-rabbitmq + TOXIPROXY_AMQP_TARGET: host.docker.internal TOXIPROXY_AMQP_PORT: 5673 steps: - name: Checkout diff --git a/tests/Functional/AbstractConnectionTest.php b/tests/Functional/AbstractConnectionTest.php index 218c49a30..9d6d573d1 100644 --- a/tests/Functional/AbstractConnectionTest.php +++ b/tests/Functional/AbstractConnectionTest.php @@ -113,7 +113,7 @@ protected function get_toxiproxy_amqp_port() $this->markTestSkipped('TOXIPROXY_AMQP_PORT is not set'); } - return $port; + return (int) $port; } protected function assertConnectionClosed(AbstractConnection $connection) diff --git a/tests/Functional/Connection/ConnectionAuthTest.php b/tests/Functional/Connection/ConnectionAuthTest.php index 15958afc7..5e8159c55 100644 --- a/tests/Functional/Connection/ConnectionAuthTest.php +++ b/tests/Functional/Connection/ConnectionAuthTest.php @@ -67,7 +67,7 @@ private function createUser($username, $password) $userEndpoint = $this->getManagementBase() . 'api/users/' . $username; $passwordHash = ''; if (!empty($password)) { - $salt = substr(md5(mt_rand()), 0, 4); + $salt = substr(md5((string) mt_rand()), 0, 4); $passwordHash = base64_encode($salt . hash('sha256', $salt . $password, true)); } $request = Request::put( diff --git a/tests/Functional/ToxiProxy.php b/tests/Functional/ToxiProxy.php index 83f338e52..318bb8d5d 100644 --- a/tests/Functional/ToxiProxy.php +++ b/tests/Functional/ToxiProxy.php @@ -49,6 +49,8 @@ public function __destruct() */ public function open($host, $port, $listen) { + $this->closeIfExists(); + $payload = [ 'name' => $this->name, 'upstream' => $host . ':' . $port, @@ -56,13 +58,13 @@ public function open($host, $port, $listen) ]; $url = $this->api . '/proxies'; $request = Request::post($url, json_encode($payload), 'json'); - $request->timeout(1); + $request->timeout(5); $request->expectsJson(); $response = $request->send(); if ($response->code !== 201) { throw new \RuntimeException('Cannot create Toxiproxy connection'); } - $this->listen = $listen; + $this->listen = (int) $listen; $this->isOpen = true; } @@ -85,7 +87,7 @@ public function mode($type, $attributes = [], $direction = 'upstream', $toxicity ]; $url = sprintf('%s/proxies/%s/toxics', $this->api, $this->name); $request = Request::post($url, json_encode($payload), 'json'); - $request->timeout(1); + $request->timeout(5); $request->expectsJson(); $response = $request->send(); @@ -94,6 +96,17 @@ public function mode($type, $attributes = [], $direction = 'upstream', $toxicity } } + private function closeIfExists() + { + $url = sprintf('%s/proxies/%s', $this->api, $this->name); + $request = Request::delete($url); + $request->timeout(5); + try { + $request->send(); + } catch (\Exception $exception) { + } + } + /** * Disable(block) proxy connection so no data can be transferred. * @throws \Httpful\Exception\ConnectionErrorException @@ -113,10 +126,22 @@ public function disable() */ public function close() { + if (!$this->isOpen) { + return; + } + $url = sprintf('%s/proxies/%s', $this->api, $this->name); - $response = Request::delete($url)->send(); - if ($response->code !== 204 && $response->code !== 404) { - throw new \RuntimeException('Cannot close Toxiproxy connection'); + $request = Request::delete($url); + $request->timeout(5); + try { + $response = $request->send(); + if ($response->code !== 204 && $response->code !== 404) { + throw new \RuntimeException('Cannot close Toxiproxy connection'); + } + } catch (\Exception $exception) { + // Best-effort cleanup; a stale proxy is removed before the next open(). + } finally { + $this->isOpen = false; } } diff --git a/tests/config.php b/tests/config.php index 1ba5c8c23..0086636e7 100644 --- a/tests/config.php +++ b/tests/config.php @@ -4,7 +4,7 @@ define('HOST', getenv('TEST_RABBITMQ_HOST') ? getenv('TEST_RABBITMQ_HOST') : 'localhost'); define('HOST6', getenv('TEST_RABBITMQ_HOST6') ? getenv('TEST_RABBITMQ_HOST6') : '[::1]'); -define('PORT', getenv('TEST_RABBITMQ_PORT') ? getenv('TEST_RABBITMQ_PORT') : 5672); +define('PORT', (int)(getenv('TEST_RABBITMQ_PORT') ?: 5672)); define('USER', getenv('TEST_RABBITMQ_USER') ? getenv('TEST_RABBITMQ_USER') : 'guest'); define('PASS', getenv('TEST_RABBITMQ_PASS') ? getenv('TEST_RABBITMQ_PASS') : 'guest'); define('VHOST', '/');