Add PHP CI test script and optimize Redis config in tests
- Introduced a PHP CI test script for managing test suites. - Consolidated Redis configuration retrieval. - Optimized test fixture queries with dynamic object type assignments.
This commit is contained in:
@@ -0,0 +1,102 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
suite="${1:-}"
|
||||||
|
case "$suite" in
|
||||||
|
unit|integration|api|legacy|all)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 <unit|integration|api|legacy|all>" >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
script_dir="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
|
||||||
|
repo_root="$(CDPATH= cd -- "$script_dir/.." && pwd)"
|
||||||
|
cd "$repo_root"
|
||||||
|
|
||||||
|
compose_files="-f docker-compose.yml -f .github/docker-compose.ci.yml"
|
||||||
|
project_suffix="$(date +%s)-$$"
|
||||||
|
export COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-php-local-${suite}-${project_suffix}}"
|
||||||
|
|
||||||
|
log_dir=".tmp/ci-logs/$suite"
|
||||||
|
mkdir -p "$log_dir"
|
||||||
|
|
||||||
|
env_backup_dir=".tmp/php-ci-env-backup-$project_suffix"
|
||||||
|
mkdir -p "$env_backup_dir"
|
||||||
|
had_env=0
|
||||||
|
had_env_staging=0
|
||||||
|
if [ -f .env ]; then
|
||||||
|
cp .env "$env_backup_dir/env"
|
||||||
|
had_env=1
|
||||||
|
fi
|
||||||
|
if [ -f .env.staging ]; then
|
||||||
|
cp .env.staging "$env_backup_dir/env.staging"
|
||||||
|
had_env_staging=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp .github/ci.env .env
|
||||||
|
cp .github/ci.env.staging .env.staging
|
||||||
|
|
||||||
|
collect_logs() {
|
||||||
|
status="$1"
|
||||||
|
if [ "$status" -eq 0 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$log_dir"
|
||||||
|
docker compose $compose_files ps > "$log_dir/docker-compose-ps.txt" 2>&1 || true
|
||||||
|
docker compose $compose_files logs --no-color > "$log_dir/docker-compose.log" 2>&1 || true
|
||||||
|
docker compose $compose_files cp php1:/var/www/html/build/logs "$log_dir/app-build-logs" >/dev/null 2>&1 || true
|
||||||
|
docker compose $compose_files cp php1:/var/log/php "$log_dir/php-logs" >/dev/null 2>&1 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
status="$?"
|
||||||
|
collect_logs "$status"
|
||||||
|
docker compose $compose_files down -v >/dev/null 2>&1 || true
|
||||||
|
if [ "$had_env" -eq 1 ]; then
|
||||||
|
cp "$env_backup_dir/env" .env
|
||||||
|
else
|
||||||
|
rm -f .env
|
||||||
|
fi
|
||||||
|
if [ "$had_env_staging" -eq 1 ]; then
|
||||||
|
cp "$env_backup_dir/env.staging" .env.staging
|
||||||
|
else
|
||||||
|
rm -f .env.staging
|
||||||
|
fi
|
||||||
|
rm -rf "$env_backup_dir"
|
||||||
|
exit "$status"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
docker compose $compose_files up -d redis mysql-debug php1
|
||||||
|
|
||||||
|
docker compose $compose_files exec -T php1 sh -lc '
|
||||||
|
set -eu
|
||||||
|
for i in $(seq 1 90); do
|
||||||
|
if MYSQL_PWD="${CONFIG_DB_PASSWORD:-debug_root_password}" mysqladmin \
|
||||||
|
-h "${CONFIG_DB_HOST:-mysql-debug}" \
|
||||||
|
-P "${CONFIG_DB_PORT:-3306}" \
|
||||||
|
-u "${CONFIG_DB_USER:-root}" \
|
||||||
|
ping --silent >/dev/null 2>&1; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
echo "Timed out waiting for mysql-debug" >&2
|
||||||
|
exit 1
|
||||||
|
'
|
||||||
|
|
||||||
|
tar \
|
||||||
|
--exclude='./vendor' \
|
||||||
|
--exclude='./.phpunit.cache' \
|
||||||
|
--exclude='./build/logs' \
|
||||||
|
-C services/nginx/app -cf - . \
|
||||||
|
| docker compose $compose_files exec -T php1 tar -C /var/www/html -xf -
|
||||||
|
|
||||||
|
docker compose $compose_files exec -T php1 sh -lc \
|
||||||
|
'cd /var/www/html && composer install --no-interaction --prefer-dist --no-progress'
|
||||||
|
|
||||||
|
docker compose $compose_files exec -T php1 sh -lc \
|
||||||
|
"cd /var/www/html && composer test:ci:$suite"
|
||||||
@@ -8,31 +8,17 @@ function selfserve_fixture_ensure_legacy_redis_constant(): void
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$client = api_test_runtime()->redis();
|
global $REDIS_CONFIG;
|
||||||
if ($client === null) {
|
|
||||||
throw new RuntimeException('Self-serve lane tests require Redis.');
|
|
||||||
}
|
|
||||||
|
|
||||||
define('redis', new class($client) {
|
$REDIS_CONFIG = [
|
||||||
public function __construct(private readonly \Predis\Client $client)
|
'host' => getenv('REDIS_CONFIG_HOST') ?: getenv('REDIS_CONFIG_DEBUG_HOST') ?: 'redis',
|
||||||
{
|
'user' => getenv('REDIS_CONFIG_USER') ?: getenv('REDIS_CONFIG_DEBUG_USER') ?: 'default',
|
||||||
}
|
'database' => getenv('REDIS_CONFIG_DATABASE') ?: getenv('REDIS_CONFIG_DEBUG_DATABASE') ?: '0',
|
||||||
|
'password' => getenv('REDIS_CONFIG_PASSWORD') ?: getenv('REDIS_CONFIG_DEBUG_PASSWORD') ?: '',
|
||||||
|
'port' => getenv('REDIS_CONFIG_PORT') ?: getenv('REDIS_CONFIG_DEBUG_PORT') ?: '6379',
|
||||||
|
];
|
||||||
|
|
||||||
public function get(string $key): mixed
|
define('redis', (new \classes\redis())->connect());
|
||||||
{
|
|
||||||
return $this->client->get($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set(string $key, mixed $value): mixed
|
|
||||||
{
|
|
||||||
return $this->client->set($key, $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete(string $key): mixed
|
|
||||||
{
|
|
||||||
return $this->client->del([$key]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it('creates a comprehensive self-serve API scenario with demo relays', function (): void {
|
it('creates a comprehensive self-serve API scenario with demo relays', function (): void {
|
||||||
@@ -86,13 +72,14 @@ it('creates self-serve invoice orders on the draft customer with original custom
|
|||||||
expect($orderId)->toBeInt()->toBeGreaterThan(0);
|
expect($orderId)->toBeInt()->toBeGreaterThan(0);
|
||||||
|
|
||||||
$order = api_fixtures()->fetchRowById('orders', $orderId);
|
$order = api_fixtures()->fetchRowById('orders', $orderId);
|
||||||
|
$attachmentObjectType = '`orders`';
|
||||||
$invoiceCollectionId = (int)($order['invoice_collection_id'] ?? 0);
|
$invoiceCollectionId = (int)($order['invoice_collection_id'] ?? 0);
|
||||||
if ($invoiceCollectionId > 0) {
|
if ($invoiceCollectionId > 0) {
|
||||||
api_fixtures()->cleanupDeleteById('collected_order_invoices', $invoiceCollectionId);
|
api_fixtures()->cleanupDeleteById('collected_order_invoices', $invoiceCollectionId);
|
||||||
}
|
}
|
||||||
api_fixtures()->cleanupDeleteById('orders', $orderId);
|
api_fixtures()->cleanupDeleteById('orders', $orderId);
|
||||||
api_fixtures()->cleanupDeleteWhere('order_items', ['order_id' => $orderId]);
|
api_fixtures()->cleanupDeleteWhere('order_items', ['order_id' => $orderId]);
|
||||||
api_fixtures()->cleanupDeleteWhere('object_attachments', ['object_type' => 'orders', 'object_id' => $orderId]);
|
api_fixtures()->cleanupDeleteWhere('object_attachments', ['object_type' => $attachmentObjectType, 'object_id' => $orderId]);
|
||||||
|
|
||||||
expect($order)->not->toBeNull()
|
expect($order)->not->toBeNull()
|
||||||
->and((int)$order['customer_id'])->toBe((int)$draftCustomer['customer_number'])
|
->and((int)$order['customer_id'])->toBe((int)$draftCustomer['customer_number'])
|
||||||
@@ -103,7 +90,7 @@ it('creates self-serve invoice orders on the draft customer with original custom
|
|||||||
|
|
||||||
$db = api_test_runtime()->db();
|
$db = api_test_runtime()->db();
|
||||||
$result = $db->query(
|
$result = $db->query(
|
||||||
'SELECT content FROM object_attachments WHERE object_type = "orders" AND object_id = ' . (int)$orderId . ' AND deleted_at IS NULL ORDER BY id DESC LIMIT 1'
|
"SELECT content FROM object_attachments WHERE object_type = '{$attachmentObjectType}' AND object_id = " . (int)$orderId . ' AND deleted_at IS NULL ORDER BY id DESC LIMIT 1'
|
||||||
);
|
);
|
||||||
$attachment = $result ? $result->fetch_assoc() : null;
|
$attachment = $result ? $result->fetch_assoc() : null;
|
||||||
$content = json_decode((string)($attachment['content'] ?? ''), true);
|
$content = json_decode((string)($attachment['content'] ?? ''), true);
|
||||||
|
|||||||
Reference in New Issue
Block a user