Skip to content

Commit

Permalink
feat: Real Deal 🎉
Browse files Browse the repository at this point in the history
  • Loading branch information
leocavalcante committed Dec 14, 2023
1 parent 2847b1c commit 4b78da1
Show file tree
Hide file tree
Showing 8 changed files with 232 additions and 91 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
],
"minimum-stability": "stable",
"require": {
"php": "^8.2"
"php": "^8.2",
"symfony/process": "^7.0"
},
"require-dev": {
"phpunit/phpunit": "^10.5",
Expand Down
127 changes: 64 additions & 63 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 0 additions & 10 deletions src/ContainerInterface.php

This file was deleted.

13 changes: 0 additions & 13 deletions src/GenericContainer.php

This file was deleted.

88 changes: 88 additions & 0 deletions src/GenericTestContainer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

declare(strict_types=1);

namespace Testcontainers;

use Symfony\Component\Process\Process;

class GenericTestContainer implements TestContainer
{
private string $name;

/** @var array<string> */
private array $command;

public function __construct(
private readonly string $image,
) {
$this->name = uniqid('testcontainers-php_');
}

/**
* @throws TestContainerException
*/
public function start(): void
{
$process = new Process([
'docker', 'run', '--rm', '-d',
'--name', $this->name,
$this->image,
...$this->command,
]);

$process->run();

if (!$process->isSuccessful()) {
throw TestContainerException::start($process->getErrorOutput());
}
}

/**
* @throws TestContainerException
*/
public function stop(): void
{
$process = new Process([
'docker',
'stop',
$this->name,
]);

$process->run();

if (!$process->isSuccessful()) {
throw TestContainerException::stop($this->name, $process->getErrorOutput());
}
}

/**
* @inheritDoc
* @throws TestContainerException
*/
public function exec(array $command): string
{
$process = new Process([
'docker', 'exec',
$this->name,
...$command,
]);

$process->run();

if (!$process->isSuccessful()) {
throw TestContainerException::exec($this->name, $process->getErrorOutput());
}

return $process->getOutput();
}

/**
* @inheritDoc
*/
public function withCommand(array $command): TestContainer
{
$this->command = $command;
return $this;
}
}
24 changes: 24 additions & 0 deletions src/TestContainer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Testcontainers;

interface TestContainer
{
public function start(): void;

public function stop(): void;

/**
* @param array<string> $command
* @return string
*/
public function exec(array $command): string;

/**
* @param array<string> $command
* @return $this
*/
public function withCommand(array $command): self;
}
23 changes: 23 additions & 0 deletions src/TestContainerException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Testcontainers;

final class TestContainerException extends \Exception
{
public static function start(string $errorMessage): self
{
return new self(sprintf('Failed to start container: %s', $errorMessage));
}

public static function stop(string $containerName, string $errorMessage): self
{
return new self(sprintf('Failed to stop container (%s): %s', $containerName, $errorMessage));
}

public static function exec(string $name, string $errorMessage): self
{
return new self(sprintf('Failed to exec command in container (%s): %s', $name, $errorMessage));
}
}
35 changes: 31 additions & 4 deletions tests/GenericContainerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,40 @@
namespace Test\Testcontainers;

use PHPUnit\Framework\TestCase;
use Testcontainers\GenericContainer;
use Testcontainers\TestContainer;
use Testcontainers\GenericTestContainer;
use Testcontainers\TestContainerException;

final class GenericContainerTest extends TestCase
{
public function testStart(): void
private static TestContainer $container;

/**
* @throws TestContainerException
*/
public static function setUpBeforeClass(): void
{
self::$container = new GenericTestContainer('alpine');
self::$container->withCommand(['tail', '-f', '/dev/null']);
self::$container->start();
}

/**
* @throws TestContainerException
*/
public static function tearDownAfterClass(): void
{
$container = new GenericContainer();
$this->assertSame('Hello, World!', $container->start());
self::$container->stop();
}

/**
* @throws TestContainerException
*/
public function testExec(): void
{
$expected = uniqid();
$actual = self::$container->exec(['echo', $expected]);

$this->assertSame($expected, trim($actual));
}
}

0 comments on commit 4b78da1

Please sign in to comment.