### Installation and Execution Commands Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/README.md Commands to install the package via Composer and execute tests in parallel. ```bash composer require mozex/laravel-test-lanes --dev ``` ```bash php artisan test --parallel ``` -------------------------------- ### Example Configuration Scenarios Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md Common patterns for using, extending, or overriding the default advisory lock drivers. ```php 'locks' => [ 'pgsql' => PgsqlAdvisoryLock::class, 'mysql' => MysqlAdvisoryLock::class, 'mariadb' => MysqlAdvisoryLock::class, ], ``` ```php use Mozex estLanes ocks PgsqlAdvisoryLock; use Mozex estLanes ocks MysqlAdvisoryLock; use App estLanes CustomDatabaseAdvisoryLock; 'locks' => [ 'pgsql' => PgsqlAdvisoryLock::class, 'mysql' => MysqlAdvisoryLock::class, 'mariadb' => MysqlAdvisoryLock::class, 'customdb' => CustomDatabaseAdvisoryLock::class, ], ``` ```php use Mozex estLanes ocks PgsqlAdvisoryLock; use App\CustomPgsqlLock; 'locks' => [ 'pgsql' => CustomPgsqlLock::class, // Override default 'mysql' => MysqlAdvisoryLock::class, 'mariadb' => MysqlAdvisoryLock::class, ], ``` -------------------------------- ### Database Connection Configurations Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md Examples of supported and unsupported database connection configurations within config/database.php. ```php // PostgreSQL (supported) 'pgsql' => [ 'driver' => 'pgsql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', 5432), 'database' => env('DB_DATABASE', 'postgres'), 'username' => env('DB_USERNAME', 'postgres'), 'password' => env('DB_PASSWORD', ''), // ... other keys are ignored ], // MySQL (supported) 'mysql' => [ 'driver' => 'mysql', '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', ''), ], // MariaDB (supported via mysql driver) 'mariadb' => [ 'driver' => 'mariadb', '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', ''), ], // Unsupported: URL-style connections (rejected with clear error) 'mysql' => [ 'url' => env('DATABASE_URL'), ], // Unsupported: Drivers with no lock implementation (rejected with clear error) 'oracle' => [ 'driver' => 'oracle', 'host' => '...', ], ``` -------------------------------- ### Install Laravel Test Lanes Source: https://github.com/mozex/laravel-test-lanes/blob/main/README.md Install the package as a development dependency via Composer. ```bash composer require mozex/laravel-test-lanes --dev ``` -------------------------------- ### CleanupCommand Output Examples Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/CleanupCommand.md Displays console output for various scenarios including successful database drops, lanes currently in use, and empty states. ```text Dropped [myapp_test_lane1]. Dropped [myapp_test_lane2]. Kept [myapp_test_lane3]: its lane is claimed by a running test process. Dropped [myapp_test_lane4]. Dropped 3 lane databases, kept 1 in use. ``` ```text Kept [myapp_test_lane1]: its lane is claimed by a running test process. Kept [myapp_test_lane2]: its lane is claimed by a running test process. Dropped 0 lane databases, kept 2 in use. ``` ```text Dropped 0 lane databases. ``` -------------------------------- ### Cleanup Command Usage Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/CleanupCommand.md Examples for executing the cleanup command on the default connection or a specific database connection. ```bash php artisan test-lanes:cleanup ``` ```bash php artisan test-lanes:cleanup --connection=postgres ``` -------------------------------- ### Catch holderConnectionFailed exception Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/errors.md Example of catching and identifying the holderConnectionFailed error during TestLanes::claim(). ```php use Mozex\TestLanes\Exceptions\TestLanesException; try { TestLanes::claim(); } catch (TestLanesException $e) { if (str_contains($e->getMessage(), 'lock-holder connection')) { // Handle connection failure } } ``` -------------------------------- ### Catch invalidPoolSize exception Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/errors.md Example of catching and identifying the invalidPoolSize error during TestLanes::claim(). ```php use Mozex\TestLanes\Exceptions\TestLanesException; try { TestLanes::claim(); } catch (TestLanesException $e) { if (str_contains($e->getMessage(), 'pool size')) { // Handle invalid pool size } } ``` -------------------------------- ### Get Configured Pool Size Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/TestLanes.md Retrieves the total number of available test lanes per base database from the configuration. ```php use Mozex\TestLanes\TestLanes; $size = TestLanes::poolSize(); // Returns 256 (default) ``` -------------------------------- ### Publish Configuration File Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md Command to publish the package configuration file to the project directory. ```bash php artisan vendor:publish --tag=test-lanes-config ``` -------------------------------- ### Deep Merge Configuration Behavior Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md Demonstrates how published configurations are merged with defaults to preserve existing drivers. ```php // config/test-lanes.php (published) 'locks' => [ 'custom' => CustomDatabaseAdvisoryLock::class, ], // Result after deep merge: // Includes pgsql, mysql, mariadb (defaults) PLUS custom (user's addition) ``` -------------------------------- ### Package Configuration File Source: https://github.com/mozex/laravel-test-lanes/blob/main/README.md Default configuration structure for enabling the package, setting pool size, and mapping advisory locks. ```php return [ 'enabled' => (bool) env('TEST_LANES_ENABLED', true), 'pool_size' => (int) env('TEST_LANES_POOL_SIZE', 256), 'locks' => [ 'pgsql' => PgsqlAdvisoryLock::class, 'mysql' => MysqlAdvisoryLock::class, 'mariadb' => MysqlAdvisoryLock::class, ], ]; ``` -------------------------------- ### Define configuration array structure Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/types.md The expected structure for the test-lanes.php configuration file. ```php [ 'enabled' => bool, 'pool_size' => int, 'locks' => [ 'pgsql' => class-string, 'mysql' => class-string, 'mariadb' => class-string, // ... custom drivers can be added here ], ] ``` -------------------------------- ### Register Package Services Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/TestLanesServiceProvider.md Handles the registration phase by applying a deep merge to the package configuration. ```php public function packageRegistered(): void ``` -------------------------------- ### Configure Package Metadata Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/TestLanesServiceProvider.md Defines the package configuration, publishes the config file, and registers the CleanupCommand. ```php public function configurePackage(Package $package): void ``` -------------------------------- ### Boot Package Services Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/TestLanesServiceProvider.md Registers the lane resolver after the application has finished booting, specifically when running unit tests. ```php public function packageBooted(): void ``` -------------------------------- ### Package File Structure Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/README.md Displays the directory layout of the Laravel Test Lanes package. ```text output/ ├── README.md # This file ├── INDEX.md # Complete navigation index ├── REFERENCE.md # Executive overview & architecture ├── types.md # Type definitions & interfaces ├── configuration.md # All config options ├── errors.md # Error conditions & recovery └── api-reference/ ├── TestLanes.md # Main facade class ├── AdvisoryLock.md # Lock interface & implementations ├── CleanupCommand.md # Cleanup command └── TestLanesServiceProvider.md # Service provider ``` -------------------------------- ### Database connection configuration array structure Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/types.md The configuration array must follow this structure, where 'driver' is mandatory and other keys are optional. ```php [ 'driver' => string, // 'pgsql', 'mysql', etc. 'host' => string, // Server hostname 'port' => int|string, // Server port 'database' => string, // Database name 'username' => string, // Username 'password' => string|null, // Password (may be null) // ... other driver-specific keys ] ``` -------------------------------- ### Package File Structure Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/REFERENCE.md The directory layout of the package, highlighting the core logic, lock implementations, and configuration. ```text src/ TestLanes.php # Main claim lifecycle TestLanesServiceProvider.php # Auto-registration & config merge Locks/ AdvisoryLock.php # Interface PgsqlAdvisoryLock.php # PostgreSQL implementation MysqlAdvisoryLock.php # MySQL/MariaDB implementation Commands/ CleanupCommand.php # Cleanup artisan command Exceptions/ TestLanesException.php # All exceptions config/ test-lanes.php # Configuration file ``` -------------------------------- ### CleanupCommand handle method signature Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/CleanupCommand.md The main entry point for the command, returning an integer exit code. ```php public function handle(): int ``` -------------------------------- ### Calculate Postgres Connection Budget Source: https://github.com/mozex/laravel-test-lanes/blob/main/README.md Formula to determine the required max_connections setting based on the number of workers and concurrent test runs. ```text max_connections >= 2 x (workers x concurrent runs) + headroom ``` -------------------------------- ### Manual Registration in TestCase Source: https://github.com/mozex/laravel-test-lanes/blob/main/README.md Register the package manually in the base TestCase if the application environment is not set to testing. ```php use Illuminate\Foundation\Testing\TestCase as BaseTestCase; use Mozex\TestLanes\TestLanes; abstract class TestCase extends BaseTestCase { public function createApplication() { $app = parent::createApplication(); TestLanes::register(); return $app; } } ``` -------------------------------- ### Implement AdvisoryLock Interface Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/AdvisoryLock.md Create a class that implements the AdvisoryLock interface to define custom connection, acquisition, and release logic. ```php namespace App\TestLanes; use Mozex\TestLanes\Locks\AdvisoryLock; use PDO; class CustomDatabaseAdvisoryLock implements AdvisoryLock { public function connect(array $config): PDO { // Construct DSN and return PDO connection $dsn = 'customdb:host=' . ($config['host'] ?? 'localhost'); return new PDO($dsn, $config['username'] ?? null, $config['password'] ?? null, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, ]); } public function tryAcquire(PDO $connection, int $namespace, int $lane): bool { // Attempt non-blocking lock acquisition $statement = $connection->prepare('SELECT acquire_lock(?, ?) AS locked'); $statement->execute([$namespace, $lane]); $row = $statement->fetch(PDO::FETCH_ASSOC); return (bool) ($row['locked'] ?? false); } public function release(PDO $connection, int $namespace, int $lane): void { // Release the lock $statement = $connection->prepare('SELECT release_lock(?, ?)'); $statement->execute([$namespace, $lane]); } } ``` -------------------------------- ### Implement custom database advisory lock Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/REFERENCE.md Create a custom driver by implementing the AdvisoryLock interface and registering it in the configuration. ```php namespace App\TestLanes; use Mozex\TestLanes\Locks\AdvisoryLock; use PDO; class CustomDatabaseAdvisoryLock implements AdvisoryLock { public function connect(array $config): PDO { // Build DSN and return PDO } public function tryAcquire(PDO $connection, int $namespace, int $lane): bool { // Attempt lock } public function release(PDO $connection, int $namespace, int $lane): void { // Release lock } } ``` ```php 'locks' => [ // ... defaults ... 'customdb' => CustomDatabaseAdvisoryLock::class, ], ``` -------------------------------- ### Configure Test Lanes via Environment Variables Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md Use environment variables to override default settings during command execution or within the .env file. ```bash # Disable lanes temporarily TEST_LANES_ENABLED=false php artisan test # Use a smaller pool TEST_LANES_POOL_SIZE=64 php artisan test # Both TEST_LANES_ENABLED=true TEST_LANES_POOL_SIZE=512 php artisan test ``` ```bash TEST_LANES_ENABLED=true TEST_LANES_POOL_SIZE=256 ``` -------------------------------- ### Implementing and Registering a Custom Advisory Lock Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md Create a class implementing the AdvisoryLock interface and register it in the configuration file. ```php // app/TestLanes/CustomDatabaseAdvisoryLock.php namespace App estLanes; use Mozex estLanes ocks AdvisoryLock; use PDO; class CustomDatabaseAdvisoryLock implements AdvisoryLock { public function connect(array $config): PDO { // Custom connection logic } public function tryAcquire(PDO $connection, int $namespace, int $lane): bool { // Custom lock acquisition } public function release(PDO $connection, int $namespace, int $lane): void { // Custom lock release } } // config/test-lanes.php 'locks' => [ 'pgsql' => PgsqlAdvisoryLock::class, 'mysql' => MysqlAdvisoryLock::class, 'mariadb' => MysqlAdvisoryLock::class, 'customdb' => CustomDatabaseAdvisoryLock::class, ], ``` -------------------------------- ### Run tests with automatic lane registration Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/REFERENCE.md Standard commands to execute tests when the environment is set to testing. ```bash # Test suite automatically gets lanes php artisan test php artisan test --parallel ./vendor/bin/pest ./vendor/bin/pest --parallel ``` -------------------------------- ### Configure Enabled Setting Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md Various methods to configure the enabled status of test lanes. ```php 'enabled' => true, ``` ```bash TEST_LANES_ENABLED=false php artisan test ``` ```text TEST_LANES_ENABLED=false ``` ```php 'enabled' => env('TEST_LANES_ENABLED', false), ``` -------------------------------- ### Run Laravel Test Lanes Commands Source: https://github.com/mozex/laravel-test-lanes/blob/main/CLAUDE.md Use these commands to execute test suites, static analysis, and formatting checks within the project. ```bash # Run all checks (formatting + static analysis + type coverage + tests) composer test # Individual checks composer lint # Fix code formatting (Pint) composer test:lint # Check code formatting without fixing composer test:types # PHPStan static analysis (level 6) composer test:type-coverage # Pest type coverage (minimum 100%) composer test:unit # Run Pest tests # Run a single test file ./vendor/bin/pest tests/LocksTest.php # Run a single test by name ./vendor/bin/pest --filter="test name here" ``` -------------------------------- ### Configure pool size for concurrency Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/REFERENCE.md Adjust the number of available lanes for high concurrency CI environments. ```bash TEST_LANES_POOL_SIZE=512 php artisan test --parallel ``` ```php 'pool_size' => (int) env('TEST_LANES_POOL_SIZE', 512), ``` -------------------------------- ### Default Configuration File Structure Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md The full default configuration file located at config/test-lanes.php, which defines the enabled state, pool size, and advisory lock implementations. ```php (bool) env('TEST_LANES_ENABLED', true), /* * How many lanes exist per base database. One lane is claimed per * concurrent test process, not per run: two full-speed 24-worker runs * already claim 48. Lanes are handed out lowest-first and their * databases are created lazily by Laravel, so a generous pool costs * nothing until that many processes actually run at once. */ 'pool_size' => (int) env('TEST_LANES_POOL_SIZE', 256), /* * The advisory-lock implementation per database driver. A driver * missing from this map fails loudly rather than silently sharing * databases. Map your own Mozex\TestLanes\Locks\AdvisoryLock * implementation here to teach lane claiming another driver. The * test-lanes:cleanup command is separate: it knows the pgsql, mysql, * and mariadb catalogs only. */ 'locks' => [ 'pgsql' => PgsqlAdvisoryLock::class, 'mysql' => MysqlAdvisoryLock::class, 'mariadb' => MysqlAdvisoryLock::class, ], ]; ``` -------------------------------- ### Implement PostgreSQL Advisory Locking Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/AdvisoryLock.md Demonstrates connecting to a PostgreSQL database and managing an advisory lock for a specific lane. ```php use Mozex estLanes ocks pgsqlAdvisoryLock; $lock = new PgsqlAdvisoryLock(); $pdo = $lock->connect([ 'host' => '127.0.0.1', 'port' => 5432, 'database' => 'myapp_test', 'username' => 'postgres', 'password' => 'password', ]); $namespace = crc32('myapp_test') & 0x7FFFFFFF; if ($lock->tryAcquire($pdo, $namespace, 1)) { // Lock acquired for lane 1 $lock->release($pdo, $namespace, 1); } ``` -------------------------------- ### Implementing Graceful Degradation Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/errors.md Catch TestLanesException to log errors and allow the test suite to continue using a shared database when lanes are unavailable. ```php use Mozex estLanes\ Exceptions estLanesException; use Mozex estLanes\TestLanes; try { TestLanes::register(); } catch (TestLanesException $e) { // Log the error and continue without lanes logger()->warning('Test lanes unavailable: ' . $e->getMessage()); // Your suite falls back to normal (shared database) behavior } ``` -------------------------------- ### Override Configuration Settings Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md Define only the keys you wish to override in the published configuration file; the package will merge these with defaults. ```php // config/test-lanes.php return [ 'pool_size' => 512, // Override just the pool size // 'enabled' and 'locks' use package defaults ]; ``` -------------------------------- ### Manually Register TestLanes in TestCase Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/TestLanesServiceProvider.md Register TestLanes manually within the createApplication method when the application environment is not set to testing. ```php use Illuminate oundation esting estcase as basetestcase; use mozex\testlanes\testlanes; abstract class testcase extends basetestcase { public function createapplication() { $app = parent::createapplication(); // manual registration when app_env != testing testlanes::register(); return $app; } } ``` -------------------------------- ### Implement MySQL Advisory Locking Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/AdvisoryLock.md Demonstrates connecting to a MySQL database and managing an advisory lock using a generated lock key. ```php use Mozex estLanes ocks ysqlAdvisoryLock; $lock = new MysqlAdvisoryLock(); $pdo = $lock->connect([ 'host' => '127.0.0.1', 'port' => 3306, 'database' => 'myapp_test', 'username' => 'root', 'password' => '', ]); $namespace = crc32('myapp_test') & 0x7FFFFFFF; if ($lock->tryAcquire($pdo, $namespace, 1)) { // Lock acquired for lane 1 $lock->release($pdo, $namespace, 1); } ``` -------------------------------- ### CleanupCommand laneDatabases method signature Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/CleanupCommand.md Scans the database server for lane databases matching the base database pattern. ```php protected function laneDatabases(PDO $holder, string $driver, string $base): array ``` -------------------------------- ### TestLanes::release() Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/REFERENCE.md Releases a previously claimed testing lane. ```APIDOC ## release() ### Description Release claimed lane (testing only). ### Signature `void release()` ``` -------------------------------- ### Run CleanupCommand in terminal Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/CleanupCommand.md Executes the cleanup command to drop databases associated with inactive test lanes. ```bash # Run tests in the background php artisan test --parallel & # In another terminal, cleanup old lane databases # (This won't affect the running tests) php artisan test-lanes:cleanup # Output: # Dropped [myapp_test_lane1]. # Kept [myapp_test_lane2]: its lane is claimed by a running test process. # Dropped 1 lane database, kept 1 in use. ``` -------------------------------- ### Handle urlConfiguredConnection exception Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/errors.md Catch exceptions occurring when database connections are defined via URL strings instead of discrete configuration keys. ```php public static function urlConfiguredConnection(string $connection): TestLanesException ``` ```php use Mozex\TestLanes\Exceptions\TestLanesException; try { TestLanes::claim(); } catch (TestLanesException $e) { if (str_contains($e->getMessage(), 'URL-configured')) { // Handle URL-configured connection } } ``` ```php // config/database.php 'mysql' => [ 'url' => env('DATABASE_URL'), ], ``` ```php // config/database.php 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', 3306), 'database' => env('DB_DATABASE', ''), 'username' => env('DB_USERNAME', ''), 'password' => env('DB_PASSWORD', ''), ], ``` ```bash DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=myapp_test DB_USERNAME=root DB_PASSWORD= ``` -------------------------------- ### Clear Cached Configuration Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md Execute this command to ensure configuration changes take effect after modification. ```bash php artisan config:clear ``` -------------------------------- ### CleanupCommand dropStatement method signature Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/CleanupCommand.md Generates a driver-specific SQL DROP DATABASE statement. ```php protected function dropStatement(string $driver, string $database): string ``` -------------------------------- ### test-lanes:cleanup Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/REFERENCE.md Artisan command to drop unclaimed lane databases. ```APIDOC ## php artisan test-lanes:cleanup ### Description Drop unclaimed lane databases (safe to run during active tests). ### Options - **--connection** (string) - Optional - Database connection name (defaults to default connection) ### Return Codes - **0** - Success - **1** - Connection not found ``` -------------------------------- ### Handle unsupportedDriver exception Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/errors.md Use this pattern to catch and handle cases where the database driver lacks an advisory lock implementation. ```php public static function unsupportedDriver( string $driver, array $supported ): TestLanesException ``` ```php use Mozex\TestLanes\Exceptions\TestLanesException; try { TestLanes::claim(); } catch (TestLanesException $e) { if (str_contains($e->getMessage(), 'no lock primitive')) { // Handle unsupported driver } } ``` -------------------------------- ### TestLanes::register() Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/REFERENCE.md Registers the token resolver and enables parallel testing functionality. ```APIDOC ## register() ### Description Registers the token resolver and enables parallel testing. ### Signature `void register()` ``` -------------------------------- ### Retrieve connection configuration Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/TestLanes.md Validates the default database connection configuration and ensures it does not use a URL parameter to prevent connection switching errors. ```php protected static function connectionConfig(): array ``` -------------------------------- ### TestLanes::poolSize() Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/REFERENCE.md Returns the configured pool size for testing lanes. ```APIDOC ## poolSize() ### Description Get configured pool size. ### Signature `int poolSize()` ``` -------------------------------- ### TestLanes::namespaceFor() Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/TestLanes.md Computes an advisory-lock namespace for a base database name, returning a positive signed 32-bit integer. ```APIDOC ## public static function namespaceFor(string $database): int ### Description Computes the advisory-lock namespace for a base database name. Returns a positive signed 32-bit integer suitable for use as a Postgres advisory lock key. ### Parameters - **$database** (string) - Required - The base database name (e.g., testapp from testapp_test_lane1) ### Return Type int ### Example ```php use Mozex\TestLanes\TestLanes; $namespace = TestLanes::namespaceFor('myapp_test'); ``` ``` -------------------------------- ### Configure Pool Size Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md Various methods to configure the number of available test lanes. ```php 'pool_size' => 256, ``` ```php 'pool_size' => (int) env('TEST_LANES_POOL_SIZE', 256), ``` ```bash TEST_LANES_POOL_SIZE=64 php artisan test ``` ```bash # GitHub Actions with 10 concurrent jobs, each spawning 24 workers # Total lanes needed: 10 × 24 = 240, round up to 512 TEST_LANES_POOL_SIZE=512 ``` -------------------------------- ### Handle poolExhausted exception Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/errors.md Catch and resolve scenarios where all available test lanes are currently occupied by other processes. ```php public static function poolExhausted(int $poolSize): TestLanesException ``` ```php use Mozex\TestLanes\Exceptions\TestLanesException; try { TestLanes::claim(); } catch (TestLanesException $e) { if (str_contains($e->getMessage(), 'lanes is held')) { // Handle pool exhaustion } } ``` ```bash TEST_LANES_POOL_SIZE=512 ``` ```php 'pool_size' => 512, ``` ```bash php artisan test-lanes:cleanup ``` -------------------------------- ### Retrieve Advisory Lock Implementation Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/TestLanes.md Instantiates and returns an advisory lock implementation based on the specified database driver. ```php use Mozex\TestLanes\TestLanes; $lock = TestLanes::lock('pgsql'); // Returns PgsqlAdvisoryLock instance // or $lock = TestLanes::lock('mysql'); // Returns MysqlAdvisoryLock instance ``` -------------------------------- ### Register Custom Driver in Configuration Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/AdvisoryLock.md Add the custom driver class to the locks array within the config/test-lanes.php file. ```php 'locks' => [ 'pgsql' => PgsqlAdvisoryLock::class, 'mysql' => MysqlAdvisoryLock::class, 'mariadb' => MysqlAdvisoryLock::class, 'customdb' => CustomDatabaseAdvisoryLock::class, ], ``` -------------------------------- ### Clean up lane databases Source: https://github.com/mozex/laravel-test-lanes/blob/main/resources/boost/skills/laravel-test-lanes/SKILL.md Use this command to safely remove unused lane databases. It will not drop databases currently claimed by active test runs. ```bash php artisan test-lanes:cleanup ``` -------------------------------- ### Connect to database for advisory locks Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/AdvisoryLock.md Establishes a dedicated PDO connection for holding advisory locks, which must remain open for the duration of the lock. ```php public function connect(array $config): PDO ``` -------------------------------- ### TestLanes::namespaceFor() Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/REFERENCE.md Computes the lock namespace for a given database name. ```APIDOC ## namespaceFor(string $db) ### Description Compute lock namespace for database. ### Parameters - **db** (string) - Required - Database name ### Signature `int namespaceFor(string $db)` ``` -------------------------------- ### Registering TestLanes Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/TestLanes.md Registers the lane resolver with Laravel's parallel testing system. Manual registration is only required when running tests outside the 'testing' environment. ```php use Mozex\TestLanes\TestLanes; // Called automatically by service provider in most cases TestLanes::register(); // After registration, Laravel routes all tests through the parallel machinery, // and databases become {base}_test_lane1, {base}_test_lane2, etc. ``` -------------------------------- ### Define holderConnectionFailed factory method Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/errors.md Factory method signature for creating a TestLanesException when the lock-holder database connection fails. ```php public static function holderConnectionFailed( string $connection, array $config, PDOException $previous ): TestLanesException ``` -------------------------------- ### Command Signature Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/CleanupCommand.md The signature definition for the cleanup command including the optional connection parameter. ```bash test-lanes:cleanup {--connection= : The connection whose lane databases should be dropped (defaults to the default connection)} ``` -------------------------------- ### Define PgsqlAdvisoryLock class Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/types.md Implementation of the AdvisoryLock interface for PostgreSQL databases. ```php class PgsqlAdvisoryLock implements AdvisoryLock ``` -------------------------------- ### Check Lane Status in Code Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md Conditional check to determine if test lanes are currently enabled. ```php if (config('test-lanes.enabled')) { // Lanes are enabled } else { // Lanes are disabled } ``` -------------------------------- ### Default Advisory Lock Configuration Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/configuration.md The default mapping of database drivers to their respective advisory lock implementation classes. ```php [ 'pgsql' => PgsqlAdvisoryLock::class, 'mysql' => MysqlAdvisoryLock::class, 'mariadb' => MysqlAdvisoryLock::class, ] ``` -------------------------------- ### Handling Connection-Specific Errors Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/errors.md Inspect the exception message to perform conditional recovery logic based on the specific failure type. ```php use Mozex estLanes\ Exceptions estLanesException; try { $lane = TestLanes::claim(); } catch (TestLanesException $e) { if (str_contains($e->getMessage(), 'unsupported')) { // Register a custom lock implementation and retry // or switch to a different database driver } elseif (str_contains($e->getMessage(), 'pool')) { // Scale up the pool size } else { // Generic connection issue } } ``` -------------------------------- ### TestLanes::poolSize() Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/TestLanes.md Retrieves the configured lane pool size from the application configuration. ```APIDOC ## public static function poolSize(): int ### Description Retrieves the test-lanes.pool_size configuration value and validates that it is at least 1. The pool size represents the total number of lanes available per base database. ### Return Type int ### Throws - TestLanesException::invalidPoolSize() ### Example ```php use Mozex\TestLanes\TestLanes; $size = TestLanes::poolSize(); ``` ``` -------------------------------- ### Attempt non-blocking lock acquisition Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/AdvisoryLock.md Attempts to acquire an advisory lock for a specific namespace and lane without waiting, returning a boolean success status. ```php public function tryAcquire(PDO $connection, int $namespace, int $lane): bool ``` -------------------------------- ### Merge Configuration Arrays Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/TestLanesServiceProvider.md Performs a recursive deep merge of default and published configuration arrays, preserving map keys while replacing lists. ```php protected function mergeConfig(array $defaults, array $published): array ``` ```php $defaults = [ 'enabled' => true, 'locks' => [ 'pgsql' => 'PgsqlAdvisoryLock', 'mysql' => 'MysqlAdvisoryLock', ], ]; $published = [ 'locks' => [ 'custom' => 'CustomAdvisoryLock', ], ]; $merged = $this->mergeConfig($defaults, $published); // Result: locks contains pgsql, mysql, AND custom ``` -------------------------------- ### Database Namespace Masking Source: https://github.com/mozex/laravel-test-lanes/blob/main/CLAUDE.md Ensures database names are compatible with Postgres advisory lock keys by masking the CRC32 hash to a signed 32-bit integer. ```php crc32(database) & 0x7FFFFFFF ``` -------------------------------- ### TestLanes::claim() Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/REFERENCE.md Claims a testing lane and returns its identifier. ```APIDOC ## claim() ### Description Claim a lane and return identifier (e.g., lane1, lane2). ### Signature `string claim()` ``` -------------------------------- ### Define MysqlAdvisoryLock class Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/types.md Implementation of the AdvisoryLock interface for MySQL and MariaDB databases. ```php class MysqlAdvisoryLock implements AdvisoryLock ``` -------------------------------- ### Manually register Test Lanes Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/REFERENCE.md Register lanes within the base TestCase when the application environment is not set to testing. ```php use Illuminate ou use Mozex\TestLanes\TestLanes; abstract class TestCase extends BaseTestCase { public function createApplication() { $app = parent::createApplication(); // Register lanes manually when APP_ENV != testing TestLanes::register(); return $app; } } ``` -------------------------------- ### MysqlAdvisoryLock Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/api-reference/AdvisoryLock.md Provides methods to manage advisory locks in MySQL and MariaDB using GET_LOCK and RELEASE_LOCK. ```APIDOC ## MysqlAdvisoryLock ### Description Implements advisory locking for MySQL and MariaDB using `GET_LOCK()` and `RELEASE_LOCK()`. ### Methods - **connect(array $config)**: Constructs a `mysql:` DSN. Config keys: `host` (default 127.0.0.1), `port` (default 3306), `database` (optional), `username`, `password`. - **tryAcquire(PDO $pdo, int $namespace, int $lane)**: Executes `SELECT GET_LOCK(lock_key, 0)` where the key is `{namespace}-test-lane-{lane}`. Returns true if the lock is acquired. - **release(PDO $pdo, int $namespace, int $lane)**: Executes `SELECT RELEASE_LOCK(lock_key)` using the same key format. ``` -------------------------------- ### Define invalidPoolSize factory method Source: https://github.com/mozex/laravel-test-lanes/blob/main/_autodocs/errors.md Factory method signature for creating a TestLanesException when the configured pool size is invalid. ```php public static function invalidPoolSize(int $size): TestLanesException ```