From 35c7bbe69d15551e402590b863371803a51990cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Wed, 17 May 2023 16:05:28 +0200 Subject: [PATCH 1/4] Skip CSFLE automatic encryption tests for non-enterprise servers Remove isEnterprise helper --- tests/DocumentationExamplesTest.php | 4 +--- tests/FunctionalTestCase.php | 15 --------------- .../Prose21_AutomaticDataEncryptionKeysTest.php | 2 ++ 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/tests/DocumentationExamplesTest.php b/tests/DocumentationExamplesTest.php index 001057454..d9628e4c2 100644 --- a/tests/DocumentationExamplesTest.php +++ b/tests/DocumentationExamplesTest.php @@ -1811,9 +1811,7 @@ public function testQueryableEncryption(): void $this->skipIfServerVersion('<', '7.0.0', 'Explicit encryption tests require MongoDB 7.0 or later'); - if (! $this->isEnterprise()) { - $this->markTestSkipped('Automatic encryption requires MongoDB Enterprise'); - } + $this->skipIfClientSideEncryptionIsNotSupported(); // Fetch names for the database and collection under test $collectionName = $this->getCollectionName(); diff --git a/tests/FunctionalTestCase.php b/tests/FunctionalTestCase.php index b4d4fb5ab..b94e870ac 100644 --- a/tests/FunctionalTestCase.php +++ b/tests/FunctionalTestCase.php @@ -28,7 +28,6 @@ use function filter_var; use function getenv; use function implode; -use function in_array; use function is_array; use function is_callable; use function is_object; @@ -397,20 +396,6 @@ protected function isApiVersionRequired(): bool return isset($document->requireApiVersion) && $document->requireApiVersion === true; } - protected function isEnterprise(): bool - { - $buildInfo = $this->getPrimaryServer()->executeCommand( - $this->getDatabaseName(), - new Command(['buildInfo' => 1]) - )->toArray()[0]; - - if (isset($buildInfo->modules) && is_array($buildInfo->modules)) { - return in_array('enterprise', $buildInfo->modules); - } - - throw new UnexpectedValueException('Could not determine server modules'); - } - protected function isLoadBalanced() { return $this->getPrimaryServer()->getType() == Server::TYPE_LOAD_BALANCER; diff --git a/tests/SpecTests/ClientSideEncryption/Prose21_AutomaticDataEncryptionKeysTest.php b/tests/SpecTests/ClientSideEncryption/Prose21_AutomaticDataEncryptionKeysTest.php index ea99ca1c2..c97c87281 100644 --- a/tests/SpecTests/ClientSideEncryption/Prose21_AutomaticDataEncryptionKeysTest.php +++ b/tests/SpecTests/ClientSideEncryption/Prose21_AutomaticDataEncryptionKeysTest.php @@ -30,6 +30,8 @@ public function setUp(): void { parent::setUp(); + $this->skipIfClientSideEncryptionIsNotSupported(); + if ($this->isStandalone() || ($this->isShardedCluster() && ! $this->isShardedClusterUsingReplicasets())) { $this->markTestSkipped('Automatic data encryption key tests require replica sets'); } From ae8b61c97c2a5ab48529da1ebfd6af781889c9b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 20 Jun 2023 18:19:43 +0200 Subject: [PATCH 2/4] Refactor isCryptSharedLibAvailable & isMongocryptdAvailable in the base FunctionalTestCase --- tests/DocumentationExamplesTest.php | 4 +- tests/FunctionalTestCase.php | 38 +++++++++++++++++++ ...reateEncryptedCollectionFunctionalTest.php | 30 --------------- .../FunctionalTestCase.php | 30 --------------- .../ClientSideEncryptionSpecTest.php | 30 --------------- tests/UnifiedSpecTests/UnifiedTestRunner.php | 28 -------------- 6 files changed, 41 insertions(+), 119 deletions(-) diff --git a/tests/DocumentationExamplesTest.php b/tests/DocumentationExamplesTest.php index d9628e4c2..f80dfe880 100644 --- a/tests/DocumentationExamplesTest.php +++ b/tests/DocumentationExamplesTest.php @@ -1811,7 +1811,9 @@ public function testQueryableEncryption(): void $this->skipIfServerVersion('<', '7.0.0', 'Explicit encryption tests require MongoDB 7.0 or later'); - $this->skipIfClientSideEncryptionIsNotSupported(); + if (! static::isCryptSharedLibAvailable() && ! static::isMongocryptdAvailable()) { + $this->markTestSkipped('Neither crypt_shared nor mongocryptd are available'); + } // Fetch names for the database and collection under test $collectionName = $this->getCollectionName(); diff --git a/tests/FunctionalTestCase.php b/tests/FunctionalTestCase.php index b94e870ac..bf564e696 100644 --- a/tests/FunctionalTestCase.php +++ b/tests/FunctionalTestCase.php @@ -30,7 +30,9 @@ use function implode; use function is_array; use function is_callable; +use function is_executable; use function is_object; +use function is_readable; use function is_string; use function key; use function ob_get_clean; @@ -43,8 +45,10 @@ use function sprintf; use function version_compare; +use const DIRECTORY_SEPARATOR; use const FILTER_VALIDATE_BOOLEAN; use const INFO_MODULES; +use const PATH_SEPARATOR; abstract class FunctionalTestCase extends TestCase { @@ -563,6 +567,40 @@ protected function skipIfTransactionsAreNotSupported(): void } } + /** + * The Automatic Encryption Shared Library is installed with MongoDB Enterprise or Atlas (version 6.0 and later). + * + * @see https://www.mongodb.com/docs/manual/core/queryable-encryption/reference/shared-library/ + */ + protected static function isCryptSharedLibAvailable(): bool + { + $cryptSharedLibPath = getenv('CRYPT_SHARED_LIB_PATH'); + + if ($cryptSharedLibPath === false) { + return false; + } + + return is_readable($cryptSharedLibPath); + } + + /** + * mongocryptd is installed with MongoDB Enterprise Server (version 4.2 and later). + * + * @see https://www.mongodb.com/docs/manual/core/queryable-encryption/reference/mongocryptd/ + */ + protected static function isMongocryptdAvailable(): bool + { + $paths = explode(PATH_SEPARATOR, getenv("PATH")); + + foreach ($paths as $path) { + if (is_executable($path . DIRECTORY_SEPARATOR . 'mongocryptd')) { + return true; + } + } + + return false; + } + private static function appendAuthenticationOptions(array $options): array { if (isset($options['username']) || isset($options['password'])) { diff --git a/tests/Operation/CreateEncryptedCollectionFunctionalTest.php b/tests/Operation/CreateEncryptedCollectionFunctionalTest.php index b6d920ce4..b80258915 100644 --- a/tests/Operation/CreateEncryptedCollectionFunctionalTest.php +++ b/tests/Operation/CreateEncryptedCollectionFunctionalTest.php @@ -12,13 +12,7 @@ use MongoDB\Operation\CreateEncryptedCollection; use function base64_decode; -use function explode; use function getenv; -use function is_executable; -use function is_readable; - -use const DIRECTORY_SEPARATOR; -use const PATH_SEPARATOR; class CreateEncryptedCollectionFunctionalTest extends FunctionalTestCase { @@ -217,28 +211,4 @@ public static function createTestClient(?string $uri = null, array $options = [] return parent::createTestClient($uri, $options, $driverOptions); } - - private static function isCryptSharedLibAvailable(): bool - { - $cryptSharedLibPath = getenv('CRYPT_SHARED_LIB_PATH'); - - if ($cryptSharedLibPath === false) { - return false; - } - - return is_readable($cryptSharedLibPath); - } - - private static function isMongocryptdAvailable(): bool - { - $paths = explode(PATH_SEPARATOR, getenv("PATH")); - - foreach ($paths as $path) { - if (is_executable($path . DIRECTORY_SEPARATOR . 'mongocryptd')) { - return true; - } - } - - return false; - } } diff --git a/tests/SpecTests/ClientSideEncryption/FunctionalTestCase.php b/tests/SpecTests/ClientSideEncryption/FunctionalTestCase.php index a48ea03ad..8290e8e8b 100644 --- a/tests/SpecTests/ClientSideEncryption/FunctionalTestCase.php +++ b/tests/SpecTests/ClientSideEncryption/FunctionalTestCase.php @@ -8,15 +8,9 @@ use PHPUnit\Framework\Assert; use stdClass; -use function explode; use function getenv; -use function is_executable; -use function is_readable; use function sprintf; -use const DIRECTORY_SEPARATOR; -use const PATH_SEPARATOR; - /** * Base class for client-side encryption prose tests. * @@ -92,28 +86,4 @@ private static function getEnv(string $name): string return $value; } - - private static function isCryptSharedLibAvailable(): bool - { - $cryptSharedLibPath = getenv('CRYPT_SHARED_LIB_PATH'); - - if ($cryptSharedLibPath === false) { - return false; - } - - return is_readable($cryptSharedLibPath); - } - - private static function isMongocryptdAvailable(): bool - { - $paths = explode(PATH_SEPARATOR, getenv("PATH")); - - foreach ($paths as $path) { - if (is_executable($path . DIRECTORY_SEPARATOR . 'mongocryptd')) { - return true; - } - } - - return false; - } } diff --git a/tests/SpecTests/ClientSideEncryptionSpecTest.php b/tests/SpecTests/ClientSideEncryptionSpecTest.php index 6d30a526e..b8b2d124e 100644 --- a/tests/SpecTests/ClientSideEncryptionSpecTest.php +++ b/tests/SpecTests/ClientSideEncryptionSpecTest.php @@ -32,22 +32,16 @@ use function base64_decode; use function basename; use function count; -use function explode; use function file_get_contents; use function getenv; use function glob; use function in_array; -use function is_executable; -use function is_readable; use function iterator_to_array; use function json_decode; use function sprintf; use function str_repeat; use function substr; -use const DIRECTORY_SEPARATOR; -use const PATH_SEPARATOR; - /** * Client-side encryption spec tests. * @@ -1988,28 +1982,4 @@ private function prepareCorpusData(string $fieldName, stdClass $data, ClientEncr return $data->allowed ? $returnData : $data; } - - private static function isCryptSharedLibAvailable(): bool - { - $cryptSharedLibPath = getenv('CRYPT_SHARED_LIB_PATH'); - - if ($cryptSharedLibPath === false) { - return false; - } - - return is_readable($cryptSharedLibPath); - } - - private static function isMongocryptdAvailable(): bool - { - $paths = explode(PATH_SEPARATOR, getenv("PATH")); - - foreach ($paths as $path) { - if (is_executable($path . DIRECTORY_SEPARATOR . 'mongocryptd')) { - return true; - } - } - - return false; - } } diff --git a/tests/UnifiedSpecTests/UnifiedTestRunner.php b/tests/UnifiedSpecTests/UnifiedTestRunner.php index 946ff32b2..9f30662f7 100644 --- a/tests/UnifiedSpecTests/UnifiedTestRunner.php +++ b/tests/UnifiedSpecTests/UnifiedTestRunner.php @@ -24,8 +24,6 @@ use function getenv; use function implode; use function in_array; -use function is_executable; -use function is_readable; use function is_string; use function parse_url; use function PHPUnit\Framework\assertContainsOnly; @@ -42,9 +40,7 @@ use function substr_replace; use function version_compare; -use const DIRECTORY_SEPARATOR; use const FILTER_VALIDATE_BOOLEAN; -use const PATH_SEPARATOR; /** * Unified test runner. @@ -357,30 +353,6 @@ private function isClientSideEncryptionSupported(): bool return static::isCryptSharedLibAvailable() || static::isMongocryptdAvailable(); } - private static function isCryptSharedLibAvailable(): bool - { - $cryptSharedLibPath = getenv('CRYPT_SHARED_LIB_PATH'); - - if ($cryptSharedLibPath === false) { - return false; - } - - return is_readable($cryptSharedLibPath); - } - - private static function isMongocryptdAvailable(): bool - { - $paths = explode(PATH_SEPARATOR, getenv("PATH")); - - foreach ($paths as $path) { - if (is_executable($path . DIRECTORY_SEPARATOR . 'mongocryptd')) { - return true; - } - } - - return false; - } - /** * Return whether serverless (i.e. proxy as mongos) is being utilized. */ From 5d8be5d9687b541faf28627df0c6fca8966f7d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Wed, 21 Jun 2023 18:03:21 +0200 Subject: [PATCH 3/4] remove incorrect comment --- tests/FunctionalTestCase.php | 12 ++---------- .../Prose21_AutomaticDataEncryptionKeysTest.php | 2 -- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/tests/FunctionalTestCase.php b/tests/FunctionalTestCase.php index bf564e696..2752e022e 100644 --- a/tests/FunctionalTestCase.php +++ b/tests/FunctionalTestCase.php @@ -567,11 +567,7 @@ protected function skipIfTransactionsAreNotSupported(): void } } - /** - * The Automatic Encryption Shared Library is installed with MongoDB Enterprise or Atlas (version 6.0 and later). - * - * @see https://www.mongodb.com/docs/manual/core/queryable-encryption/reference/shared-library/ - */ + /** @see https://www.mongodb.com/docs/manual/core/queryable-encryption/reference/shared-library/ */ protected static function isCryptSharedLibAvailable(): bool { $cryptSharedLibPath = getenv('CRYPT_SHARED_LIB_PATH'); @@ -583,11 +579,7 @@ protected static function isCryptSharedLibAvailable(): bool return is_readable($cryptSharedLibPath); } - /** - * mongocryptd is installed with MongoDB Enterprise Server (version 4.2 and later). - * - * @see https://www.mongodb.com/docs/manual/core/queryable-encryption/reference/mongocryptd/ - */ + /** @see https://www.mongodb.com/docs/manual/core/queryable-encryption/reference/mongocryptd/ */ protected static function isMongocryptdAvailable(): bool { $paths = explode(PATH_SEPARATOR, getenv("PATH")); diff --git a/tests/SpecTests/ClientSideEncryption/Prose21_AutomaticDataEncryptionKeysTest.php b/tests/SpecTests/ClientSideEncryption/Prose21_AutomaticDataEncryptionKeysTest.php index c97c87281..ea99ca1c2 100644 --- a/tests/SpecTests/ClientSideEncryption/Prose21_AutomaticDataEncryptionKeysTest.php +++ b/tests/SpecTests/ClientSideEncryption/Prose21_AutomaticDataEncryptionKeysTest.php @@ -30,8 +30,6 @@ public function setUp(): void { parent::setUp(); - $this->skipIfClientSideEncryptionIsNotSupported(); - if ($this->isStandalone() || ($this->isShardedCluster() && ! $this->isShardedClusterUsingReplicasets())) { $this->markTestSkipped('Automatic data encryption key tests require replica sets'); } From 96d27b70056b08dbd9bc751645d5d4370f7df754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Mon, 26 Jun 2023 15:13:58 +0200 Subject: [PATCH 4/4] Checks for crypt_shared and/or mongocryptd in FunctionalTestCase::skipIfClientSideEncryptionIsNotSupported --- tests/DocumentationExamplesTest.php | 5 +---- tests/FunctionalTestCase.php | 8 ++++++-- tests/SpecTests/ClientSideEncryptionSpecTest.php | 4 ---- tests/UnifiedSpecTests/UnifiedTestRunner.php | 4 +++- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/tests/DocumentationExamplesTest.php b/tests/DocumentationExamplesTest.php index f80dfe880..af336f19a 100644 --- a/tests/DocumentationExamplesTest.php +++ b/tests/DocumentationExamplesTest.php @@ -1810,10 +1810,7 @@ public function testQueryableEncryption(): void } $this->skipIfServerVersion('<', '7.0.0', 'Explicit encryption tests require MongoDB 7.0 or later'); - - if (! static::isCryptSharedLibAvailable() && ! static::isMongocryptdAvailable()) { - $this->markTestSkipped('Neither crypt_shared nor mongocryptd are available'); - } + $this->skipIfClientSideEncryptionIsNotSupported(); // Fetch names for the database and collection under test $collectionName = $this->getCollectionName(); diff --git a/tests/FunctionalTestCase.php b/tests/FunctionalTestCase.php index 2752e022e..cc4df8ef9 100644 --- a/tests/FunctionalTestCase.php +++ b/tests/FunctionalTestCase.php @@ -531,6 +531,10 @@ protected function skipIfClientSideEncryptionIsNotSupported(): void if (static::getModuleInfo('libmongocrypt') === 'disabled') { $this->markTestSkipped('Client Side Encryption is not enabled in the MongoDB extension'); } + + if (! static::isCryptSharedLibAvailable() && ! static::isMongocryptdAvailable()) { + $this->markTestSkipped('Neither crypt_shared nor mongocryptd are available'); + } } protected function skipIfGeoHaystackIndexIsNotSupported(): void @@ -568,7 +572,7 @@ protected function skipIfTransactionsAreNotSupported(): void } /** @see https://www.mongodb.com/docs/manual/core/queryable-encryption/reference/shared-library/ */ - protected static function isCryptSharedLibAvailable(): bool + public static function isCryptSharedLibAvailable(): bool { $cryptSharedLibPath = getenv('CRYPT_SHARED_LIB_PATH'); @@ -580,7 +584,7 @@ protected static function isCryptSharedLibAvailable(): bool } /** @see https://www.mongodb.com/docs/manual/core/queryable-encryption/reference/mongocryptd/ */ - protected static function isMongocryptdAvailable(): bool + public static function isMongocryptdAvailable(): bool { $paths = explode(PATH_SEPARATOR, getenv("PATH")); diff --git a/tests/SpecTests/ClientSideEncryptionSpecTest.php b/tests/SpecTests/ClientSideEncryptionSpecTest.php index b8b2d124e..6d39a83e1 100644 --- a/tests/SpecTests/ClientSideEncryptionSpecTest.php +++ b/tests/SpecTests/ClientSideEncryptionSpecTest.php @@ -117,10 +117,6 @@ public function setUp(): void parent::setUp(); $this->skipIfClientSideEncryptionIsNotSupported(); - - if (! static::isCryptSharedLibAvailable() && ! static::isMongocryptdAvailable()) { - $this->markTestSkipped('Neither crypt_shared nor mongocryptd are available'); - } } /** diff --git a/tests/UnifiedSpecTests/UnifiedTestRunner.php b/tests/UnifiedSpecTests/UnifiedTestRunner.php index 9f30662f7..40f2c3046 100644 --- a/tests/UnifiedSpecTests/UnifiedTestRunner.php +++ b/tests/UnifiedSpecTests/UnifiedTestRunner.php @@ -337,6 +337,8 @@ private function isAuthenticated(): bool /** * Return whether client-side encryption is supported. + * + * @see FunctionalTestCase::skipIfClientSideEncryptionIsNotSupported() */ private function isClientSideEncryptionSupported(): bool { @@ -350,7 +352,7 @@ private function isClientSideEncryptionSupported(): bool return false; } - return static::isCryptSharedLibAvailable() || static::isMongocryptdAvailable(); + return FunctionalTestCase::isCryptSharedLibAvailable() || FunctionalTestCase::isMongocryptdAvailable(); } /**