From 0dc8c80a02efbee5676cc72e648e108037ca5268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sun, 4 Aug 2019 20:04:25 +0200 Subject: [PATCH] Fix Redis scan for predis, make phpunit use multiple configs (e.g. different Redis drivers) --- src/StorageDrivers/RedisStorageDriver.php | 22 +++++++++++++--------- test | 1 + tests/BootstrapsTenancyTest.php | 5 +++++ tests/DataSeparationTest.php | 4 ++++ tests/TenantManagerTest.php | 8 ++++++++ tests/TestCase.php | 10 ++++++---- 6 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/StorageDrivers/RedisStorageDriver.php b/src/StorageDrivers/RedisStorageDriver.php index 50e1fb8e..af055b12 100644 --- a/src/StorageDrivers/RedisStorageDriver.php +++ b/src/StorageDrivers/RedisStorageDriver.php @@ -82,17 +82,21 @@ class RedisStorageDriver implements StorageDriver }, $uuids); if (! $hashes) { - // Apparently, the PREFIX is applied to all functions except scan(). - // Therefore, if the `tenancy` Redis connection has a prefix set - // (and PhpRedis is used), prepend the prefix to the search. - $redis_prefix = ''; + // Prefix is applied to all functions except scan(). + // This code applies the correct prefix manually. + $redis_prefix = config('database.redis.options.prefix'); + if (config('database.redis.client') === 'phpredis') { - $redis_prefix = $this->redis->getOption($this->redis->client()::OPT_PREFIX); + $redis_prefix = $this->redis->getOption($this->redis->client()::OPT_PREFIX) ?? $redis_prefix; + $all_keys = $this->redis->scan(null, $redis_prefix . 'tenants:*'); + } else { + $all_keys = $this->redis->scan(null, 'MATCH', $redis_prefix . 'tenants:*')[1]; } - $hashes = array_map(function ($hash) use ($redis_prefix) { - // Left strip $redis_prefix from $hash - return substr($hash, strlen($redis_prefix)); - }, $this->redis->scan(null, $redis_prefix.'tenants:*')); + + $hashes = array_map(function ($key) use ($redis_prefix) { + // Left strip $redis_prefix from $key + return substr($key, strlen($redis_prefix)); + }, $all_keys); } return array_map(function ($tenant) { diff --git a/test b/test index 0d9f4044..0d11eef3 100755 --- a/test +++ b/test @@ -22,4 +22,5 @@ for variant in variants: system('docker-compose exec test vendor/bin/phpunit --configuration "%s" --coverage-php %s %s' % (filename_base + '.xml', 'coverage/' + filename_base + '.cov', ' '.join(other))) +# todo delete folder contents first? system("docker-compose exec test vendor/bin/phpcov merge --clover clover.xml coverage/") diff --git a/tests/BootstrapsTenancyTest.php b/tests/BootstrapsTenancyTest.php index 6a3a9263..fc0d761f 100644 --- a/tests/BootstrapsTenancyTest.php +++ b/tests/BootstrapsTenancyTest.php @@ -24,6 +24,10 @@ class BootstrapsTenancyTest extends TestCase /** @test */ public function redis_is_prefixed() { + if (! config('tenancy.redis.tenancy')) { + $this->markTestSkipped('Redis tenancy disabled.'); + } + $this->initTenancy(); foreach (config('tenancy.redis.prefixed_connections', ['default']) as $connection) { $prefix = config('tenancy.redis.prefix_base') . tenant('uuid'); @@ -35,6 +39,7 @@ class BootstrapsTenancyTest extends TestCase /** @test */ public function predis_is_supported() { + // No setDriver() before that version. if (app()->version() < 'v5.8.27') { $this->markTestSkipped(); } diff --git a/tests/DataSeparationTest.php b/tests/DataSeparationTest.php index 7a635c23..89790df0 100644 --- a/tests/DataSeparationTest.php +++ b/tests/DataSeparationTest.php @@ -66,6 +66,10 @@ class DataSeparationTest extends TestCase /** @test */ public function redis_is_separated() { + if (! config('tenancy.redis.tenancy')) { + $this->markTestSkipped('Redis tenancy disabled.'); + } + tenancy()->create('tenant1.localhost'); tenancy()->create('tenant2.localhost'); diff --git a/tests/TenantManagerTest.php b/tests/TenantManagerTest.php index 7fdd443a..050c729a 100644 --- a/tests/TenantManagerTest.php +++ b/tests/TenantManagerTest.php @@ -186,4 +186,12 @@ class TenantManagerTest extends TestCase $tenant = tenant()->create('foo.localhost'); $this->assertSame([$tenant], tenancy()->all()->toArray()); } + + /** @test */ + public function all_returns_a_list_of_all_tenants() + { + $tenant1 = tenant()->create('foo.localhost'); + $tenant2 = tenant()->create('bar.localhost'); + $this->assertEqualsCanonicalizing([$tenant1, $tenant2], tenant()->all()->toArray()); + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index a2beeafc..815e5d3d 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -63,6 +63,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase 'database.redis.client' => 'phpredis', 'database.redis.cache.host' => env('TENANCY_TEST_REDIS_HOST', '127.0.0.1'), 'database.redis.default.host' => env('TENANCY_TEST_REDIS_HOST', '127.0.0.1'), + 'database.redis.options.prefix' => 'foo', 'database.redis.tenancy' => [ 'host' => env('TENANCY_TEST_REDIS_HOST', '127.0.0.1'), 'password' => env('TENANCY_TEST_REDIS_PASSWORD', null), @@ -70,6 +71,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase // Use the #14 Redis database unless specified otherwise. // Make sure you don't store anything in this db! 'database' => env('TENANCY_TEST_REDIS_DB', 14), + 'prefix' => 'abc', // todo unrelated to tenancy, but this doesn't seem to have an effect? try to replicate in a fresh laravel installation ], 'tenancy.database' => [ 'based_on' => 'sqlite', @@ -92,14 +94,14 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase switch ((string) env('STANCL_TENANCY_TEST_VARIANT', '1')) { case '2': $app['config']->set([ - 'tenancy.redis.tenancy' => true, - 'database.redis.client' => 'phpredis', + 'tenancy.redis.tenancy' => false, + 'database.redis.client' => 'predis', ]); break; default: $app['config']->set([ - 'tenancy.redis.tenancy' => false, - 'database.redis.client' => 'predis', + 'tenancy.redis.tenancy' => true, + 'database.redis.client' => 'phpredis', ]); } }