mirror of
https://github.com/archtechx/tenancy-queue-tester.git
synced 2025-12-12 21:04:03 +00:00
initial commit
This commit is contained in:
commit
52d95e9370
12 changed files with 525 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
src/
|
||||||
15
README.md
Normal file
15
README.md
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# Tenancy for Laravel queue testing suite
|
||||||
|
|
||||||
|
In addition to the tests we can write using testbench, we have this repository which:
|
||||||
|
1. Creates a new Laravel application
|
||||||
|
2. Sets up Tenancy
|
||||||
|
3. Creates a sample job
|
||||||
|
4. Asserts that the queue worker is working as expected
|
||||||
|
|
||||||
|
This is mostly due to some past bugs that were hard to catch in our test suite.
|
||||||
|
|
||||||
|
With this repo, we can have a separate CI job validating queue behavior _in a real application_.
|
||||||
|
|
||||||
|
## TODOs
|
||||||
|
|
||||||
|
- Verify how `queue:restart` works in v4
|
||||||
25
cli/Dockerfile
Normal file
25
cli/Dockerfile
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
ARG PHP_VERSION=8.4
|
||||||
|
|
||||||
|
FROM php:${PHP_VERSION}-cli-bookworm
|
||||||
|
|
||||||
|
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
|
||||||
|
|
||||||
|
RUN apt update && apt install -y git unzip libzip-dev libicu-dev \
|
||||||
|
&& apt autoremove && apt clean
|
||||||
|
|
||||||
|
RUN pecl install redis && docker-php-ext-enable redis
|
||||||
|
RUN docker-php-ext-install zip && docker-php-ext-enable zip
|
||||||
|
RUN docker-php-ext-install pdo_mysql && docker-php-ext-enable pdo_mysql
|
||||||
|
RUN docker-php-ext-install intl && docker-php-ext-enable intl
|
||||||
|
|
||||||
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && php composer-setup.php
|
||||||
|
|
||||||
|
RUN mv composer.phar /usr/local/bin/composer
|
||||||
|
|
||||||
|
RUN mkdir /var/www/.composer && chmod -R 777 /var/www/.composer
|
||||||
|
|
||||||
|
RUN mkdir -p /var/www/.config/psysh && chmod -R 777 /var/www/.config/psysh
|
||||||
|
|
||||||
|
USER www-data
|
||||||
6
cli/build.sh
Executable file
6
cli/build.sh
Executable file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
tag="tenancy-queue-test-cli"
|
||||||
|
php="8.4"
|
||||||
|
|
||||||
|
docker build --build-arg PHP_VERSION=$php -t $tag .
|
||||||
26
docker-compose.yml
Normal file
26
docker-compose.yml
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
services:
|
||||||
|
redis:
|
||||||
|
image: redis:7-bookworm
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 2
|
||||||
|
start_period: 1s
|
||||||
|
|
||||||
|
queue:
|
||||||
|
image: tenancy-queue-test-cli
|
||||||
|
working_dir: /var/www/html
|
||||||
|
user: www-data
|
||||||
|
command: php artisan queue:work -vvv
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pidof php"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 2s
|
||||||
|
retries: 2
|
||||||
|
start_period: 2s
|
||||||
|
depends_on:
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
volumes:
|
||||||
|
- ./src:/var/www/html
|
||||||
11
setup.sh
Executable file
11
setup.sh
Executable file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
TENANCY_VERSION=${TENANCY_VERSION:-"dev-master"}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
(cd cli && ./build.sh)
|
||||||
|
|
||||||
|
rm -rf src
|
||||||
|
|
||||||
|
docker run --rm -it -e TENANCY_VERSION="${TENANCY_VERSION}" -v .:/var/www/html tenancy-queue-test-cli bash setup/_tenancy_setup.sh
|
||||||
19
setup/FooJob.php
Normal file
19
setup/FooJob.php
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Queue\Queueable;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class FooJob implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Queueable;
|
||||||
|
|
||||||
|
public function handle(): void
|
||||||
|
{
|
||||||
|
User::create(['name' => Str::random(12), 'email' => Str::random(12), 'password' => Str::random(12)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
13
setup/Tenant_base.php
Normal file
13
setup/Tenant_base.php
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Stancl\Tenancy\Database\Models\Tenant as BaseTenant;
|
||||||
|
use Stancl\Tenancy\Contracts\TenantWithDatabase;
|
||||||
|
use Stancl\Tenancy\Database\Concerns\HasDatabase;
|
||||||
|
use Stancl\Tenancy\Database\Concerns\HasDomains;
|
||||||
|
|
||||||
|
class Tenant extends BaseTenant implements TenantWithDatabase
|
||||||
|
{
|
||||||
|
use HasDatabase, HasDomains;
|
||||||
|
}
|
||||||
39
setup/_tenancy_setup.sh
Executable file
39
setup/_tenancy_setup.sh
Executable file
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
composer global require laravel/installer
|
||||||
|
~/.composer/vendor/laravel/installer/bin/laravel new --no-interaction --database=sqlite --git src/
|
||||||
|
|
||||||
|
cd src/
|
||||||
|
|
||||||
|
# If a specific Laravel version is desired
|
||||||
|
# composer require -W laravel/framework:11.15.0
|
||||||
|
|
||||||
|
composer config minimum-stability dev
|
||||||
|
composer require "stancl/tenancy:$TENANCY_VERSION"
|
||||||
|
|
||||||
|
php artisan tenancy:install --no-interaction
|
||||||
|
php artisan migrate
|
||||||
|
|
||||||
|
rm bootstrap/providers.php
|
||||||
|
cp ../setup/providers.php bootstrap/providers.php
|
||||||
|
|
||||||
|
cp ../setup/Tenant_base.php app/Models/Tenant.php
|
||||||
|
if [ ! -f vendor/stancl/tenancy/src/Contracts/TenantWithDatabase.php ]; then
|
||||||
|
sed -i 's/use Stancl\\Tenancy\\Contracts\\TenantWithDatabase/use Stancl\\Tenancy\\Database\\Contracts\\TenantWithDatabase/' app/Models/Tenant.php
|
||||||
|
fi
|
||||||
|
|
||||||
|
sed -i 's/QUEUE_CONNECTION=database/QUEUE_CONNECTION=redis/' .env
|
||||||
|
sed -i 's/REDIS_HOST=127.0.0.1/REDIS_HOST=redis/' .env
|
||||||
|
sed -i 's/CACHE_STORE=database/CACHE_STORE=redis/' .env
|
||||||
|
sed -i 's/Stancl\\Tenancy\\Database\\Models\\Tenant/App\\Models\\Tenant/' config/tenancy.php
|
||||||
|
sed -i 's/.*RedisTenancyBootstrapper::class.*/ \\Stancl\\Tenancy\\Bootstrappers\\RedisTenancyBootstrapper::class,/' config/tenancy.php
|
||||||
|
sed -i 's/'\''prefixed_connections'\'' => \[.*$/'\''prefixed_connections'\'' => [ '\''cache'\'',/' config/tenancy.php
|
||||||
|
echo "REDIS_QUEUE_CONNECTION=queue" >> .env
|
||||||
|
|
||||||
|
rm config/database.php
|
||||||
|
cp ../setup/database.php config/database.php
|
||||||
|
|
||||||
|
cp database/migrations/*create_users*.php database/migrations/tenant
|
||||||
|
|
||||||
|
mkdir app/Jobs
|
||||||
|
cp ../setup/FooJob.php app/Jobs/FooJob.php
|
||||||
182
setup/database.php
Normal file
182
setup/database.php
Normal file
|
|
@ -0,0 +1,182 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Database Connection Name
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify which of the database connections below you wish
|
||||||
|
| to use as your default connection for database operations. This is
|
||||||
|
| the connection which will be utilized unless another connection
|
||||||
|
| is explicitly specified when you execute a query / statement.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'default' => env('DB_CONNECTION', 'sqlite'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Database Connections
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Below are all of the database connections defined for your application.
|
||||||
|
| An example configuration is provided for each database system which
|
||||||
|
| is supported by Laravel. You're free to add / remove connections.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'connections' => [
|
||||||
|
|
||||||
|
'sqlite' => [
|
||||||
|
'driver' => 'sqlite',
|
||||||
|
'url' => env('DB_URL'),
|
||||||
|
'database' => env('DB_DATABASE', database_path('database.sqlite')),
|
||||||
|
'prefix' => '',
|
||||||
|
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
|
||||||
|
'busy_timeout' => null,
|
||||||
|
'journal_mode' => null,
|
||||||
|
'synchronous' => null,
|
||||||
|
],
|
||||||
|
|
||||||
|
'mysql' => [
|
||||||
|
'driver' => 'mysql',
|
||||||
|
'url' => env('DB_URL'),
|
||||||
|
'host' => env('DB_HOST', '127.0.0.1'),
|
||||||
|
'port' => env('DB_PORT', '3306'),
|
||||||
|
'database' => env('DB_DATABASE', 'laravel'),
|
||||||
|
'username' => env('DB_USERNAME', 'root'),
|
||||||
|
'password' => env('DB_PASSWORD', ''),
|
||||||
|
'unix_socket' => env('DB_SOCKET', ''),
|
||||||
|
'charset' => env('DB_CHARSET', 'utf8mb4'),
|
||||||
|
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
|
||||||
|
'prefix' => '',
|
||||||
|
'prefix_indexes' => true,
|
||||||
|
'strict' => true,
|
||||||
|
'engine' => null,
|
||||||
|
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
||||||
|
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
||||||
|
]) : [],
|
||||||
|
],
|
||||||
|
|
||||||
|
'mariadb' => [
|
||||||
|
'driver' => 'mariadb',
|
||||||
|
'url' => env('DB_URL'),
|
||||||
|
'host' => env('DB_HOST', '127.0.0.1'),
|
||||||
|
'port' => env('DB_PORT', '3306'),
|
||||||
|
'database' => env('DB_DATABASE', 'laravel'),
|
||||||
|
'username' => env('DB_USERNAME', 'root'),
|
||||||
|
'password' => env('DB_PASSWORD', ''),
|
||||||
|
'unix_socket' => env('DB_SOCKET', ''),
|
||||||
|
'charset' => env('DB_CHARSET', 'utf8mb4'),
|
||||||
|
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
|
||||||
|
'prefix' => '',
|
||||||
|
'prefix_indexes' => true,
|
||||||
|
'strict' => true,
|
||||||
|
'engine' => null,
|
||||||
|
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
||||||
|
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
||||||
|
]) : [],
|
||||||
|
],
|
||||||
|
|
||||||
|
'pgsql' => [
|
||||||
|
'driver' => 'pgsql',
|
||||||
|
'url' => env('DB_URL'),
|
||||||
|
'host' => env('DB_HOST', '127.0.0.1'),
|
||||||
|
'port' => env('DB_PORT', '5432'),
|
||||||
|
'database' => env('DB_DATABASE', 'laravel'),
|
||||||
|
'username' => env('DB_USERNAME', 'root'),
|
||||||
|
'password' => env('DB_PASSWORD', ''),
|
||||||
|
'charset' => env('DB_CHARSET', 'utf8'),
|
||||||
|
'prefix' => '',
|
||||||
|
'prefix_indexes' => true,
|
||||||
|
'search_path' => 'public',
|
||||||
|
'sslmode' => 'prefer',
|
||||||
|
],
|
||||||
|
|
||||||
|
'sqlsrv' => [
|
||||||
|
'driver' => 'sqlsrv',
|
||||||
|
'url' => env('DB_URL'),
|
||||||
|
'host' => env('DB_HOST', 'localhost'),
|
||||||
|
'port' => env('DB_PORT', '1433'),
|
||||||
|
'database' => env('DB_DATABASE', 'laravel'),
|
||||||
|
'username' => env('DB_USERNAME', 'root'),
|
||||||
|
'password' => env('DB_PASSWORD', ''),
|
||||||
|
'charset' => env('DB_CHARSET', 'utf8'),
|
||||||
|
'prefix' => '',
|
||||||
|
'prefix_indexes' => true,
|
||||||
|
// 'encrypt' => env('DB_ENCRYPT', 'yes'),
|
||||||
|
// 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Migration Repository Table
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This table keeps track of all the migrations that have already run for
|
||||||
|
| your application. Using this information, we can determine which of
|
||||||
|
| the migrations on disk haven't actually been run on the database.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'migrations' => [
|
||||||
|
'table' => 'migrations',
|
||||||
|
'update_date_on_publish' => true,
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Redis Databases
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Redis is an open source, fast, and advanced key-value store that also
|
||||||
|
| provides a richer body of commands than a typical key-value system
|
||||||
|
| such as Memcached. You may define your connection settings here.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'redis' => [
|
||||||
|
|
||||||
|
'client' => env('REDIS_CLIENT', 'phpredis'),
|
||||||
|
|
||||||
|
'options' => [
|
||||||
|
'cluster' => env('REDIS_CLUSTER', 'redis'),
|
||||||
|
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
|
||||||
|
],
|
||||||
|
|
||||||
|
'default' => [
|
||||||
|
'url' => env('REDIS_URL'),
|
||||||
|
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||||
|
'username' => env('REDIS_USERNAME'),
|
||||||
|
'password' => env('REDIS_PASSWORD'),
|
||||||
|
'port' => env('REDIS_PORT', '6379'),
|
||||||
|
'database' => env('REDIS_DB', '0'),
|
||||||
|
],
|
||||||
|
|
||||||
|
'queue' => [
|
||||||
|
'url' => env('REDIS_URL'),
|
||||||
|
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||||
|
'username' => env('REDIS_USERNAME'),
|
||||||
|
'password' => env('REDIS_PASSWORD'),
|
||||||
|
'port' => env('REDIS_PORT', '6379'),
|
||||||
|
'database' => env('REDIS_DB', '0'),
|
||||||
|
],
|
||||||
|
|
||||||
|
'cache' => [
|
||||||
|
'url' => env('REDIS_URL'),
|
||||||
|
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||||
|
'username' => env('REDIS_USERNAME'),
|
||||||
|
'password' => env('REDIS_PASSWORD'),
|
||||||
|
'port' => env('REDIS_PORT', '6379'),
|
||||||
|
'database' => env('REDIS_CACHE_DB', '1'),
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
||||||
6
setup/providers.php
Normal file
6
setup/providers.php
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
App\Providers\AppServiceProvider::class,
|
||||||
|
App\Providers\TenancyServiceProvider::class,
|
||||||
|
];
|
||||||
182
test.sh
Executable file
182
test.sh
Executable file
|
|
@ -0,0 +1,182 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
assert_queue_worker_running() {
|
||||||
|
if docker compose ps -a --format '{{.Status}}' queue | grep -q "Exited"; then
|
||||||
|
echo "ERR: Queue worker has exited!"
|
||||||
|
docker compose logs queue
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_queue_worker_exited() {
|
||||||
|
if ! docker compose ps -a --format '{{.Status}}' queue | grep -q "Exited"; then
|
||||||
|
echo "ERR: Queue worker has NOT exited!"
|
||||||
|
docker compose logs queue
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_no_queue_failures() {
|
||||||
|
assert_queue_worker_running
|
||||||
|
if docker compose logs queue -n 2 | grep -q "FAIL"; then
|
||||||
|
echo "ERR: Queue failures detected in logs"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_tenant_users() {
|
||||||
|
assert_no_queue_failures
|
||||||
|
local expected_count=$1
|
||||||
|
test "$(sqlite3 src/database/tenantfoo.sqlite 'SELECT count(*) from USERS')" -eq "$expected_count" || { echo "ERR: Tenant DB expects $expected_count user(s)."; exit 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_central_users() {
|
||||||
|
assert_no_queue_failures
|
||||||
|
local expected_count=$1
|
||||||
|
test "$(sqlite3 src/database/database.sqlite 'SELECT count(*) from USERS')" -eq "$expected_count" || { echo "ERR: Central DB expects $expected_count user(s)."; exit 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
without_queue_assertions() {
|
||||||
|
# Store the original function
|
||||||
|
local original_assert_no_queue_failures=$(declare -f assert_no_queue_failures)
|
||||||
|
|
||||||
|
assert_no_queue_failures() { :; }
|
||||||
|
|
||||||
|
# Run the provided command with its arguments
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Restore the original function
|
||||||
|
eval "$original_assert_no_queue_failures"
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch_central_job() {
|
||||||
|
echo "Dispatching job from central context..."
|
||||||
|
docker compose exec -T queue php artisan tinker --execute "dispatch(new App\Jobs\FooJob);"
|
||||||
|
sleep 5
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch_tenant_job() {
|
||||||
|
echo "Dispatching job from tenant context..."
|
||||||
|
docker compose exec -T queue php artisan tinker --execute "App\\Models\\Tenant::first()->run(function () { dispatch(new App\Jobs\FooJob); });"
|
||||||
|
sleep 5
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
###################################### SETUP ######################################
|
||||||
|
|
||||||
|
rm -f src/database.sqlite
|
||||||
|
rm -f src/database/tenantfoo.sqlite
|
||||||
|
|
||||||
|
docker compose start redis # in case it's not running - the below setup code needs Redis to be running
|
||||||
|
|
||||||
|
docker compose run --rm queue php artisan migrate:fresh >/dev/null
|
||||||
|
docker compose run --rm queue php artisan tinker -v --execute "App\\Models\\Tenant::create(['id' => 'foo', 'tenancy_db_name' => 'tenantfoo.sqlite']);"
|
||||||
|
|
||||||
|
docker compose down; docker compose up -d --wait
|
||||||
|
docker compose logs -f queue &
|
||||||
|
|
||||||
|
# Kill any log watchers that may still be alive
|
||||||
|
trap "docker compose stop queue" EXIT
|
||||||
|
|
||||||
|
echo "Setup complete, starting tests...\n"
|
||||||
|
|
||||||
|
################### BASIC PHASE: Assert jobs use the right context ###################
|
||||||
|
|
||||||
|
dispatch_tenant_job
|
||||||
|
assert_tenant_users 1
|
||||||
|
assert_central_users 0
|
||||||
|
echo "OK: User created in tenant\n"
|
||||||
|
|
||||||
|
dispatch_central_job
|
||||||
|
assert_tenant_users 1
|
||||||
|
assert_central_users 1
|
||||||
|
echo "OK: User created in central\n"
|
||||||
|
|
||||||
|
############# RESTART PHASE: Assert the worker always responds to signals #############
|
||||||
|
|
||||||
|
echo "Running queue:restart (after a central job)..."
|
||||||
|
docker compose exec -T queue php artisan queue:restart >/dev/null
|
||||||
|
sleep 3
|
||||||
|
assert_queue_worker_exited
|
||||||
|
echo "OK: Queue worker has exited\n"
|
||||||
|
|
||||||
|
echo "Starting queue worker again..."
|
||||||
|
docker compose restart queue
|
||||||
|
sleep 3
|
||||||
|
docker compose logs -f queue &
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
dispatch_tenant_job
|
||||||
|
# IMPORTANT:
|
||||||
|
# If the worker remains in the tenant context after running a job
|
||||||
|
# it not only fails the final assertion here by not responding to queue:restart.
|
||||||
|
# It ALSO prematurely restarts right here! See https://github.com/archtechx/tenancy/issues/1229#issuecomment-2566111616
|
||||||
|
# However, we're not too interested in checking for an extra restart, so we skip
|
||||||
|
# queue assertions here and only check that the job executed correctly.
|
||||||
|
# Then, if the queue worker has shut down, we simply start it up again and continue
|
||||||
|
# with the tests. That said, if the warning has been printed, it should be pretty much
|
||||||
|
# guaranteed that the assertion about queue:restart post-tenant job will fail too.
|
||||||
|
without_queue_assertions assert_tenant_users 2
|
||||||
|
without_queue_assertions assert_central_users 1
|
||||||
|
echo "OK: User created in tenant\n"
|
||||||
|
|
||||||
|
if docker compose ps -a --format '{{.Status}}' queue | grep -q "Exited"; then
|
||||||
|
echo "WARN: Queue worker restarted after running a tenant job post-restart (https://github.com/archtechx/tenancy/issues/1229#issuecomment-2566111616) following assertions will likely fail."
|
||||||
|
docker compose start queue # Start the worker back up
|
||||||
|
sleep 3
|
||||||
|
docker compose logs -f queue &
|
||||||
|
else
|
||||||
|
echo "OK: No extra restart took place"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Following the above, we also want to check if this only happens the first
|
||||||
|
# time a job is dispatched for a tenant (with central illuminate:queue:restart) filled
|
||||||
|
# and fills the TENANT's illuminate:queue:restart from then on, or if this happens on
|
||||||
|
# future jobs of that tenant as well.
|
||||||
|
|
||||||
|
# This time, just to add more context, we can try to dispatch a central job first
|
||||||
|
# in case it changes anything. But odds are that in broken setups we'll see both warnings.
|
||||||
|
dispatch_central_job
|
||||||
|
without_queue_assertions assert_tenant_users 2
|
||||||
|
without_queue_assertions assert_central_users 2
|
||||||
|
echo "OK: User created in central\n"
|
||||||
|
|
||||||
|
dispatch_tenant_job
|
||||||
|
without_queue_assertions assert_tenant_users 3
|
||||||
|
without_queue_assertions assert_central_users 2
|
||||||
|
echo "OK: User created in tenant\n"
|
||||||
|
|
||||||
|
if docker compose ps -a --format '{{.Status}}' queue | grep -q "Exited"; then
|
||||||
|
echo "WARN: ANOTHER extra restart took place after running a tenant job"
|
||||||
|
docker compose start queue # Start the worker back up
|
||||||
|
sleep 3
|
||||||
|
docker compose logs -f queue &
|
||||||
|
else
|
||||||
|
echo "OK: No second extra restart took place"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# We have to clear the central illuminate:queue:restart value here
|
||||||
|
# to make the last assertion work, because if the previous WARNs were
|
||||||
|
# triggered, that means the following *tenant job dispatch* will trigger
|
||||||
|
# a restart as well.
|
||||||
|
# -n 1 = DB number for cache connection, configured in setup/database.php
|
||||||
|
docker compose exec redis redis-cli -n 1 DEL laravel_database_illuminate:queue:restart >/dev/null
|
||||||
|
|
||||||
|
# Also make the queue worker reload the value from cache
|
||||||
|
docker compose restart queue
|
||||||
|
docker compose logs -f queue &
|
||||||
|
|
||||||
|
# Finally, we dispatch a tenant job *immediately* before a restart.
|
||||||
|
dispatch_tenant_job
|
||||||
|
assert_tenant_users 4
|
||||||
|
assert_central_users 2
|
||||||
|
echo "OK: User created in tenant\n"
|
||||||
|
|
||||||
|
echo "Running queue:restart (after a tenant job)..."
|
||||||
|
docker compose exec -T queue php artisan queue:restart >/dev/null
|
||||||
|
sleep 3
|
||||||
|
assert_queue_worker_exited
|
||||||
|
echo "OK: Queue worker has exited"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue