Skip to content

Commit

Permalink
Merge pull request #127 from mermshaus/update-tests-php8
Browse files Browse the repository at this point in the history
Update tests to work in PHP 8 Docker Compose setup
  • Loading branch information
WyriHaximus authored Nov 30, 2022
2 parents 79e0bdf + c099a45 commit aba52e4
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 78 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,22 +80,27 @@ jobs:
- name: Run UnitTests
if: matrix.ssl_test == 'no'
run: ./vendor/bin/phpunit
env:
SSL_TEST: "no"
TEST_RABBITMQ_CONNECTION_URI: "amqp://guest:guest@localhost:5672/"
- name: Run UnitTests
if: matrix.ssl_test == 'yes'
run: ./vendor/bin/phpunit
env:
SSL_TEST: "yes"
SSL_CA: "ssl/ca.pem"
SSL_PEER_NAME: "server.rmq"
TEST_RABBITMQ_CONNECTION_URI: "amqp://guest:guest@localhost:5672/"
- name: Run UnitTests
if: matrix.ssl_test == 'client'
run: ./vendor/bin/phpunit
env:
SSL_TEST: "yes"
SSL_TEST: "client"
SSL_CA: "ssl/ca.pem"
SSL_PEER_NAME: "server.rmq"
SSL_CLIENT_CERT: "ssl/client.pem"
SSL_CLIENT_KEY: "ssl/client.key"
TEST_RABBITMQ_CONNECTION_URI: "amqp://guest:guest@localhost:5672/"
- name: Docker Logs
if: ${{ failure() }}
run: docker logs rabbitmq
14 changes: 5 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,18 +211,14 @@ There is [amqp interop](https://github.com/queue-interop/amqp-interop) compatibl

## Testing

You need access to a RabbitMQ instance to run the test suite. You can either connect to an existing instance or use the
provided Docker Compose setup to create an isolated environment, including a RabbitMQ container, to run the test suite
in.
Create client/server SSL certificates by running:

**Local RabbitMQ**
```
$ cd test/ssl && make all && cd -
```

- Change `TEST_RABBITMQ_CONNECTION_URI` in `phpunit.xml` to fit your environment. Then run:
You need access to a RabbitMQ instance in order to run the test suite. The easiest way is to use the provided Docker Compose setup to create an isolated environment, including a RabbitMQ container, to run the test suite in.

```
$ vendor/bin/phpunit
```

**Docker Compose**

- Use Docker Compose to create a network with a RabbitMQ container and a PHP container to run the tests in. The project
Expand Down
15 changes: 8 additions & 7 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@ services:
- main
hostname: rabbit_node_1
ports:
- "15672:15672"
- "5672:5672"
- "5673:5673"
- "15672:15672"
tty: true
bunny:
build: docker/bunny
init: true
environment:
SSL_TEST: 'yes'
SSL_CA: ssl/ca.pem
SSL_PEER_NAME: server.rmq
SSL_CLIENT_CERT: ssl/client.pem
SSL_CLIENT_KEY: ssl/client.key
SSL_TEST: "client"
SSL_CA: "ssl/ca.pem"
SSL_CLIENT_CERT: "ssl/client.pem"
SSL_CLIENT_KEY: "ssl/client.key"
SSL_PEER_NAME: "server.rmq"
TEST_RABBITMQ_CONNECTION_URI: "amqp://testuser:testpassword@bunny_rabbit_node_1_1:5672/testvhost"
volumes:
- .:/opt/bunny
networks:
Expand Down
3 changes: 2 additions & 1 deletion docker/bunny/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM php:7.4-cli
FROM php:8.1-cli

RUN apt-get update \
&& apt-get dist-upgrade -y \
Expand All @@ -10,6 +10,7 @@ RUN apt-get update \

RUN pecl install xdebug \
&& docker-php-ext-enable xdebug
RUN echo "xdebug.mode=coverage" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

RUN curl --silent --show-error https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer
Expand Down
39 changes: 25 additions & 14 deletions docker/rabbitmq/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
#!/bin/bash

set -eu
set -eux

is_rabbitmq_gte_3_7_0() {
[[ "3.7.0" = $(echo -e "3.7.0\n$RABBITMQ_VERSION" | sort -V | head -n1) ]]
}

install_certs() {
local certs_dir="/rabbitmq-certs"

rm -rf "${certs_dir}"
mkdir "${certs_dir}"
cp "${TEST_DATA_ROOT}"/{ca.pem,server.pem,server.key} "${certs_dir}"
chown rabbitmq "${certs_dir}"/{ca.pem,server.pem,server.key}
chmod 0400 "${certs_dir}"/{ca.pem,server.pem,server.key}
}

install_config() {
if [[ -n "$CONFIG_NAME" ]]; then
if is_rabbitmq_gte_3_7_0; then
cp "${TEST_DATA_ROOT}/${CONFIG_NAME}.conf" /etc/rabbitmq/rabbitmq.conf
chown rabbitmq /etc/rabbitmq/rabbitmq.conf
else
cp "${TEST_DATA_ROOT}/${CONFIG_NAME}.config" /etc/rabbitmq/rabbitmq.config
chown rabbitmq /etc/rabbitmq/rabbitmq.config
fi
fi
}

TEST_DATA_ROOT=/opt/bunny/test/ssl
CONFIG_NAME=${CONFIG_NAME:-}

cp ${TEST_DATA_ROOT}/{ca.pem,server.pem,server.key} /etc/rabbitmq/
chown rabbitmq /etc/rabbitmq/{ca.pem,server.pem,server.key}
chmod 0400 /etc/rabbitmq/{ca.pem,server.pem,server.key}

if [[ -n "$CONFIG_NAME" ]]; then
if is_rabbitmq_gte_3_7_0; then
cp ${TEST_DATA_ROOT}/${CONFIG_NAME}.conf /etc/rabbitmq/rabbitmq.conf
chown rabbitmq /etc/rabbitmq/rabbitmq.conf
else
cp ${TEST_DATA_ROOT}/${CONFIG_NAME}.config /etc/rabbitmq/rabbitmq.config
chown rabbitmq /etc/rabbitmq/rabbitmq.config
fi
fi
install_certs
install_config

exec "$@"
40 changes: 11 additions & 29 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,31 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.5/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true">

<testsuites>
<testsuite name="Tests">
<directory suffix="Test.php">test/Bunny</directory>
</testsuite>
</testsuites>

<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>

<php>
<!-- This is the default configuration when running the test suite
through the docker-compose setup -->
<env name="TEST_RABBITMQ_CONNECTION_URI" value="amqp://guest:guest@localhost:5672/"/>

<!-- RabbitMQ running on localhost with default user (guest:guest) and
vhost "/" would be (slashes in the actual vhost name need to be
percent-encoded, see https://www.rabbitmq.com/uri-spec.html): -->
<!--<env name="TEST_RABBITMQ_CONNECTION_URI" value="amqp://localhost:5672/%2f"/>-->
</php>

<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true">
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
<testsuites>
<testsuite name="Tests">
<directory suffix="Test.php">test/Bunny</directory>
</testsuite>
</testsuites>
</phpunit>
28 changes: 13 additions & 15 deletions test/Bunny/SSLTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
use Bunny\Exception\ClientException;
use Bunny\Test\Exception\TimeoutException;
use Bunny\Test\Library\AsynchronousClientHelper;
use Bunny\Test\Library\Environment;
use Bunny\Test\Library\SynchronousClientHelper;
use PHPUnit\Framework\TestCase;

use React\EventLoop\Factory;

use function dirname;
use function file_exists;
use function getenv;
use function is_file;
use function putenv;

Expand Down Expand Up @@ -78,7 +78,9 @@ public function testConnectWithMissingClientCert()
// let's try without client certificate - it should fail
unset($options['ssl']['local_cert'], $options['ssl']['local_pk']);

$this->expectException(ClientException::class);
if (Environment::getSslTest() === 'client') {
$this->expectException(ClientException::class);
}

$client = $this->helper->createClient($options);
$client->connect();
Expand Down Expand Up @@ -112,26 +114,20 @@ public function testConnectWithWrongPeerName()
protected function getOptions()
{
// should we do SSL-tests
if (empty(getenv('SSL_TEST'))) {
$this->markTestSkipped('Skipped due empty ENV-variable "SSL_TEST"');
if (!in_array(Environment::getSslTest(), ['yes', 'client'], true)) {
$this->markTestSkipped('Skipped because env var SSL_TEST not set to "yes" or "client"');
}

// checking CA-file
$caFile = getenv('SSL_CA');
if (empty($caFile)) {
$this->fail('Missing CA file ENV-variable: "SSL_CA"');
}
$caFile = Environment::getSslCa();

$testsDir = dirname(__DIR__);
$caFile = $testsDir . '/' . $caFile;
if (!file_exists($caFile) || !is_file($caFile)) {
$this->fail('Missing CA file: "' . $caFile . '"');
}

$peerName = getenv('SSL_PEER_NAME');
if (empty($peerName)) {
// setting default value from tests/ssl/Makefile
$peerName = 'server.rmq';
}
$peerName = Environment::getSslPeerName();

// minimal SSL-options
$options = [
Expand All @@ -145,8 +141,9 @@ protected function getOptions()
];


$certFile = getenv('SSL_CLIENT_CERT');
$keyFile = getenv('SSL_CLIENT_KEY');
$certFile = Environment::getSslClientCert();
$keyFile = Environment::getSslClientKey();

if (!empty($certFile) && !empty($keyFile)) {
$certFile = $testsDir . '/' . $certFile;
$keyFile = $testsDir . '/' . $keyFile;
Expand All @@ -159,6 +156,7 @@ protected function getOptions()
$options['ssl']['local_cert'] = $certFile;
$options['ssl']['local_pk'] = $keyFile;
}

return $options;
}
}
2 changes: 1 addition & 1 deletion test/Library/AsynchronousClientHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function getDefaultOptions(): array
{
$options = [];

$options = array_merge($options, $this->parseAmqpUri(getenv('TEST_RABBITMQ_CONNECTION_URI')));
$options = array_merge($options, $this->parseAmqpUri(Environment::getTestRabbitMqConnectionUri()));

return $options;
}
Expand Down
65 changes: 65 additions & 0 deletions test/Library/Environment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace Bunny\Test\Library;

final class Environment
{
public static function getSslCa(): string
{
return trim(self::getenv('SSL_CA'));
}

public static function getSslClientCert(): string
{
return trim(self::getenv('SSL_CLIENT_CERT', ''));
}

public static function getSslClientKey(): string
{
return trim(self::getenv('SSL_CLIENT_KEY', ''));
}

public static function getSslPeerName(): string
{
return trim(self::getenv('SSL_PEER_NAME'));
}

/**
* Can have the following values:
*
* - "client" -> run all SSL tests, expect peer cert (c.f. rabbitmq.ssl.verify_peer.conf)
* - "yes" -> run all SSL tests, do *not* expect peer cert (c.f. rabbitmq.ssl.verify_none.conf)
* - "no" (default) -> skip SSL-related tests
*/
public static function getSslTest(): string
{
$value = self::getenv('SSL_TEST', 'no');

switch ($value) {
case 'client':
case 'no':
case 'yes':
return $value;
}

throw new EnvironmentException('SSL_TEST');
}

public static function getTestRabbitMqConnectionUri(): string
{
return trim(self::getenv('TEST_RABBITMQ_CONNECTION_URI'));
}

private static function getenv(string $envVariable, ?string $default = null):string
{
$value = getenv($envVariable);

if ($value === false && $default === null) {
throw new EnvironmentException($envVariable);
}

return $value!==false?$value:$default;
}
}
15 changes: 15 additions & 0 deletions test/Library/EnvironmentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Bunny\Test\Library;

class EnvironmentException extends \RuntimeException
{
public function __construct(string $envVariable)
{
$value = getenv($envVariable);

$valueFormatted = $value===false?'false': '"' . $value . '"';

parent::__construct(sprintf('Invalid value for env var %s: %s', $envVariable, $valueFormatted), 1);
}
}
2 changes: 1 addition & 1 deletion test/Library/SynchronousClientHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public function getDefaultOptions(): array
{
$options = [];

$options = array_merge($options, $this->parseAmqpUri(getenv('TEST_RABBITMQ_CONNECTION_URI')));
$options = array_merge($options, $this->parseAmqpUri(Environment::getTestRabbitMqConnectionUri()));

return $options;
}
Expand Down

0 comments on commit aba52e4

Please sign in to comment.