Skip to content

Commit ef435d6

Browse files
committed
feat: Added DbContainerBuilder and OpenSearchContainerBuilder
1 parent df181b0 commit ef435d6

21 files changed

+1003
-0
lines changed

.gitattributes

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/build export-ignore
2+
/tests export-ignore
3+
/.github export-ignore

.github/workflows/php-package.yml

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: PHP Package
2+
on:
3+
push:
4+
pull_request:
5+
jobs:
6+
format-check:
7+
name: Check PSR12 Standarts
8+
runs-on: ubuntu-24.04
9+
steps:
10+
- uses: actions/checkout@v4
11+
- name: Setup PHP
12+
uses: shivammathur/setup-php@v2
13+
with:
14+
php-version: 8.3
15+
tools: composer:v2
16+
- run: composer install
17+
shell: bash
18+
- run: composer format:check
19+
shell: bash
20+
tests:
21+
name: Run Tests
22+
runs-on: ubuntu-24.04
23+
steps:
24+
- uses: actions/checkout@v4
25+
- name: Setup PHP
26+
uses: shivammathur/setup-php@v2
27+
with:
28+
php-version: 8.3
29+
tools: composer:v2
30+
- run: composer install
31+
shell: bash
32+
- run: composer test
33+
shell: bash

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/vendor/
22
/composer.lock
3+
/.idea/

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 EcomDev B.V.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# 🐳 Test-Containers for Quick Magento Development
2+
[![Docker Build](https://github.com/EcomDev/testcontainer-magento-data/actions/workflows/docker-images.yml/badge.svg)](https://github.com/EcomDev/testcontainer-magento-data/actions/workflows/docker-images.yml)
3+
[![PHP Package](https://github.com/EcomDev/testcontainer-magento-data-php/actions/workflows/php-package.yml/badge.svg)](https://github.com/EcomDev/testcontainer-magento-data-php/actions/workflows/php-package.yml)
4+
5+
This package simplifies the process of automated testing with real database and search engine
6+
7+
## ✨ Features
8+
9+
- 📦 **Pre-configured database and search containers**: Instantly spin up containers with ready-to-use Magento data
10+
- ⚙️ **Easy setup and use**: Use PHP package to automatically discard container after tests
11+
- 🎯 **Blazingly Fast**: Container takes only few seconds to start, so you can focus on testing instead of waiting for db initialization
12+
13+
## 📋 Requirements
14+
15+
- **🐳 Docker**: Ensure Docker is installed and operational on your system.
16+
17+
## 📦 Available images
18+
19+
All the available Docker image version can be found in build repository [EcomDev/testcontainer-magento-data](https://github.com/EcomDev/testcontainer-magento-data?tab=readme-ov-file#-available-images)
20+
21+
## Installation
22+
23+
Use composer with `--dev` flag to add it as dependency for your tests
24+
```bash
25+
composer require --dev ecomdev/testcontainers-magento-data
26+
```
27+
28+
29+
## Examples
30+
31+
### MySQL container
32+
33+
Create Latest Magento Database Build
34+
```php
35+
use EcomDev\TestContainers\MagentoData\DbContainerBuilder;
36+
37+
$container = DbContainerBuilder::mysql()
38+
->build();
39+
```
40+
41+
Create Latest Magento Database Build with sample data
42+
```php
43+
use EcomDev\TestContainers\MagentoData\DbContainerBuilder;
44+
45+
$container = DbContainerBuilder::mysql()
46+
->withSampleData()
47+
->build();
48+
```
49+
50+
Create 2.4.7-p2 with sample data and fetch number of products
51+
```php
52+
use EcomDev\TestContainers\MagentoData\DbContainerBuilder;
53+
use PDO;
54+
55+
$container = DbContainerBuilder::mysql()
56+
->withMagentoVersion('2.4.7-p2')
57+
->withSampleData()
58+
->build();
59+
60+
$connectionSettings = $container->getConnectionSettings();
61+
$connection = new PDO(
62+
$connectionSettings->dsn(),
63+
$connectionSettings->user,
64+
$connectionSettings->password
65+
);
66+
67+
$result = $connection->query('SELECT COUNT(*) FROM catalog_product_entity');
68+
// Outputs 2040
69+
echo $result->fetch(PDO::FETCH_COLUMN);
70+
```
71+
72+
### MariaDB container
73+
Everything the same as for MySQL container, just a different builder method
74+
75+
```php
76+
use EcomDev\TestContainers\MagentoData\DbContainerBuilder;
77+
78+
$container = DbContainerBuilder::mariadb()
79+
->withMagentoVersion('2.4.7-p2')
80+
->withSampleData()
81+
->build();
82+
```
83+
84+
## OpenSearch container
85+
86+
For OpenSearch container there is a different builder and container, that allows building base url for http connection
87+
88+
Here is a small example
89+
90+
```php
91+
use EcomDev\TestContainers\MagentoData\OpenSearchContainerBuilder;
92+
use GuzzleHttp\Client;
93+
94+
$container = OpenSearchContainerBuilder::new()
95+
->withSampleData()
96+
->build();
97+
98+
$client = new Client([
99+
'base_uri' => $container->getBaseUrl()
100+
]);
101+
102+
$result = json_decode(
103+
$client->get('magento2_product_1/_count')->getBody()->getContents(),
104+
true
105+
);
106+
107+
// Outputs 181
108+
echo $result['count'];
109+
```
110+
111+
## 📜 License
112+
113+
This project is licensed under the MIT License.
114+
115+
See the [LICENSE](LICENSE) file for more details.

composer.json

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"name": "ecomdev/testcontainers-magento-data",
3+
"description": "TestContainers for Magento data in integration/functional tests",
4+
"type": "library",
5+
"require": {
6+
"php": "^8.3",
7+
"testcontainers/testcontainers": "^0.2.0"
8+
},
9+
"require-dev": {
10+
"phpunit/phpunit": "^11.5",
11+
"ext-pdo": "*",
12+
"brianium/paratest": "^7.7",
13+
"guzzlehttp/guzzle": "^7.0",
14+
"squizlabs/php_codesniffer": "^3.0"
15+
},
16+
"license": "MIT",
17+
"autoload": {
18+
"psr-4": {
19+
"EcomDev\\TestContainers\\MagentoData\\": "src"
20+
}
21+
},
22+
"autoload-dev": {
23+
"psr-4": {
24+
"EcomDev\\TestContainers\\MagentoData\\": "tests"
25+
}
26+
},
27+
"scripts": {
28+
"test": "paratest ./tests/ ",
29+
"unit": "paratest ./tests/ --exclude-group=slow",
30+
"format:check": "phpcs --standard=PSR12 ./",
31+
"format:write": "phpcbf --standard=PSR12 ./"
32+
},
33+
"authors": [
34+
{
35+
"name": "Ivan Chepurnyi",
36+
"email": "[email protected]"
37+
}
38+
],
39+
"minimum-stability": "stable"
40+
}

release-please-config.json

Whitespace-only changes.

src/ContainerBuilder.php

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace EcomDev\TestContainers\MagentoData;
4+
5+
/**
6+
* Interface defining methods for building and configuring containers.
7+
*/
8+
interface ContainerBuilder
9+
{
10+
/**
11+
* Sets the Magento version and returns a new instance with the updated value.
12+
*
13+
* @param string $version The version of Magento to be set.
14+
* @return self A new instance with the specified Magento version.
15+
*/
16+
public function withMagentoVersion(string $version): self;
17+
18+
/**
19+
* Sets the variation and returns a new instance with the updated value.
20+
*
21+
* @param string $variation The variation to be set.
22+
* @return self A new instance with the specified variation.
23+
*/
24+
public function withVariation(string $variation): self;
25+
26+
/**
27+
* Configures the instance to use sample data and returns a new instance with the updated configuration.
28+
*
29+
* @return self A new instance configured to include sample data.
30+
*/
31+
public function withSampleData(): self;
32+
33+
/**
34+
* Builds container with configured input
35+
*/
36+
public function build(): RunningContainer;
37+
38+
/**
39+
* Creates new container with unique identifier or returns existing one with the same id
40+
*
41+
* Helpful for re-using read-only container usage
42+
*/
43+
public function shared(string $id): RunningContainer;
44+
45+
/**
46+
* Returns final image name based on all configuration provided
47+
*/
48+
public function getImageName(): string;
49+
}

src/ContainerBuilderConfiguration.php

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace EcomDev\TestContainers\MagentoData;
4+
5+
/**
6+
* Provides configuration options for building a container.
7+
*/
8+
trait ContainerBuilderConfiguration
9+
{
10+
/**
11+
* Version of Magento which container is based on
12+
*
13+
* @var string
14+
*/
15+
private string $magentoVersion = 'latest';
16+
17+
/**
18+
* Name of the container variations
19+
*
20+
* @var string
21+
*/
22+
private string $variation = '';
23+
24+
/**
25+
* Sets the Magento version and returns a new instance with the updated value.
26+
*/
27+
public function withMagentoVersion(string $version): self
28+
{
29+
$other = clone $this;
30+
$other->magentoVersion = $version;
31+
return $other;
32+
}
33+
34+
/**
35+
* Sets the variation and returns a new instance with the updated value.
36+
*/
37+
public function withVariation(string $variation): self
38+
{
39+
$other = clone $this;
40+
$other->variation = $variation;
41+
return $other;
42+
}
43+
44+
/**
45+
* Configures the instance to use sample data and returns a new instance with the updated configuration.
46+
*/
47+
public function withSampleData(): self
48+
{
49+
return $this->withVariation('sampledata');
50+
}
51+
52+
private function generateImageTag(): string
53+
{
54+
return $this->magentoVersion . ($this->variation ? '-' . $this->variation : '');
55+
}
56+
}

src/ContainerMetadata.php

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace EcomDev\TestContainers\MagentoData;
4+
5+
final class ContainerMetadata
6+
{
7+
private const CONTAINER_NAME = 'ghcr.io/ecomdev/testcontainer-magento-data/%s';
8+
9+
public static function getImageName(string $type)
10+
{
11+
return sprintf(self::CONTAINER_NAME, $type);
12+
}
13+
}

src/ContainerRegistry.php

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace EcomDev\TestContainers\MagentoData;
4+
5+
/**
6+
* A class responsible for managing a registry of running containers,
7+
* identified by their image name and a unique identifier.
8+
*/
9+
final class ContainerRegistry
10+
{
11+
private static array $containers = [];
12+
13+
/**
14+
* Register container with specified id
15+
*/
16+
public static function registerContainer(string $id, RunningContainer $container): RunningContainer
17+
{
18+
$imageName = $container->getImageName();
19+
self::$containers[$imageName][$id] = $container;
20+
return $container;
21+
}
22+
23+
/**
24+
* Returns container by image and id if it was registered before
25+
*/
26+
public static function findContainer(string $image, string $id): ?RunningContainer
27+
{
28+
return self::$containers[$image][$id] ?? null;
29+
}
30+
}

0 commit comments

Comments
 (0)