3131use function glob ;
3232use function in_array ;
3333use function is_executable ;
34+ use function is_readable ;
3435use function iterator_to_array ;
3536use function json_decode ;
3637use function sprintf ;
4647 * Client-side encryption spec tests.
4748 *
4849 * @see https://github.com/mongodb/specifications/tree/master/source/client-side-encryption
50+ * @group csfle
4951 */
5052class ClientSideEncryptionSpecTest extends FunctionalTestCase
5153{
@@ -65,7 +67,10 @@ public function setUp(): void
6567 parent ::setUp ();
6668
6769 $ this ->skipIfClientSideEncryptionIsNotSupported ();
68- $ this ->skipIfLocalMongocryptdIsUnavailable ();
70+
71+ if (! static ::isCryptSharedLibAvailable () && ! static ::isMongocryptdAvailable ()) {
72+ $ this ->markTestSkipped ('Neither crypt_shared nor mongocryptd are available ' );
73+ }
6974 }
7075
7176 /**
@@ -79,6 +84,15 @@ public static function assertCommandMatches(stdClass $expected, stdClass $actual
7984 static ::assertDocumentsMatch ($ expected , $ actual );
8085 }
8186
87+ public static function createTestClient (?string $ uri = null , array $ options = [], array $ driverOptions = []): Client
88+ {
89+ if (isset ($ driverOptions ['autoEncryption ' ]) && getenv ('CRYPT_SHARED_LIB_PATH ' )) {
90+ $ driverOptions ['autoEncryption ' ]['extraOptions ' ]['cryptSharedLibPath ' ] = getenv ('CRYPT_SHARED_LIB_PATH ' );
91+ }
92+
93+ return parent ::createTestClient ($ uri , $ options , $ driverOptions );
94+ }
95+
8296 /**
8397 * Execute an individual test case from the specification.
8498 *
@@ -825,6 +839,14 @@ static function (self $test, ClientEncryption $clientEncryption, ClientEncryptio
825839 */
826840 public function testBypassSpawningMongocryptdViaBypassSpawn (): void
827841 {
842+ /* If crypt_shared is available it will likely already have been loaded
843+ * by a previous test so there is no way to prevent it from being used.
844+ * Since CSFLE prefers crypt_shared to mongocryptd there is reason to
845+ * run any of the "bypass spawning" tests (see also: MONGOCRYPT-421). */
846+ if (static ::isCryptSharedLibAvailable ()) {
847+ $ this ->markTestSkipped ('Bypass spawning of mongocryptd cannot be tested when crypt_shared is available ' );
848+ }
849+
828850 $ autoEncryptionOpts = [
829851 'keyVaultNamespace ' => 'keyvault.datakeys ' ,
830852 'kmsProviders ' => [
@@ -840,6 +862,7 @@ public function testBypassSpawningMongocryptdViaBypassSpawn(): void
840862 ],
841863 ];
842864
865+ // Disable adding cryptSharedLibPath, as it may interfere with this test
843866 $ clientEncrypted = static ::createTestClient (null , [], ['autoEncryption ' => $ autoEncryptionOpts ]);
844867
845868 try {
@@ -860,6 +883,10 @@ public function testBypassSpawningMongocryptdViaBypassSpawn(): void
860883 */
861884 public function testBypassSpawningMongocryptdViaBypassAutoEncryption (): void
862885 {
886+ if (static ::isCryptSharedLibAvailable ()) {
887+ $ this ->markTestSkipped ('Bypass spawning of mongocryptd cannot be tested when crypt_shared is available ' );
888+ }
889+
863890 $ autoEncryptionOpts = [
864891 'keyVaultNamespace ' => 'keyvault.datakeys ' ,
865892 'kmsProviders ' => [
@@ -871,6 +898,7 @@ public function testBypassSpawningMongocryptdViaBypassAutoEncryption(): void
871898 ],
872899 ];
873900
901+ // Disable adding cryptSharedLibPath, as it may interfere with this test
874902 $ clientEncrypted = static ::createTestClient (null , [], ['autoEncryption ' => $ autoEncryptionOpts ]);
875903
876904 $ clientEncrypted ->selectCollection ('db ' , 'coll ' )->insertOne (['unencrypted ' => 'test ' ]);
@@ -888,6 +916,10 @@ public function testBypassSpawningMongocryptdViaBypassAutoEncryption(): void
888916 */
889917 public function testBypassSpawningMongocryptdViaBypassQueryAnalysis (): void
890918 {
919+ if (static ::isCryptSharedLibAvailable ()) {
920+ $ this ->markTestSkipped ('Bypass spawning of mongocryptd cannot be tested when crypt_shared is available ' );
921+ }
922+
891923 $ autoEncryptionOpts = [
892924 'keyVaultNamespace ' => 'keyvault.datakeys ' ,
893925 'kmsProviders ' => [
@@ -899,6 +931,7 @@ public function testBypassSpawningMongocryptdViaBypassQueryAnalysis(): void
899931 ],
900932 ];
901933
934+ // Disable adding cryptSharedLibPath, as it may interfere with this test
902935 $ clientEncrypted = static ::createTestClient (null , [], ['autoEncryption ' => $ autoEncryptionOpts ]);
903936
904937 $ clientEncrypted ->selectCollection ('db ' , 'coll ' )->insertOne (['unencrypted ' => 'test ' ]);
@@ -1525,16 +1558,27 @@ private function prepareEncryptedFieldsMap(stdClass $encryptedFieldsMap): stdCla
15251558 return $ encryptedFieldsMap ;
15261559 }
15271560
1528- private function skipIfLocalMongocryptdIsUnavailable (): void
1561+ private static function isCryptSharedLibAvailable (): bool
1562+ {
1563+ $ cryptSharedLibPath = getenv ('CRYPT_SHARED_LIB_PATH ' );
1564+
1565+ if ($ cryptSharedLibPath === false ) {
1566+ return false ;
1567+ }
1568+
1569+ return is_readable ($ cryptSharedLibPath );
1570+ }
1571+
1572+ private static function isMongocryptdAvailable (): bool
15291573 {
15301574 $ paths = explode (PATH_SEPARATOR , getenv ("PATH " ));
15311575
15321576 foreach ($ paths as $ path ) {
15331577 if (is_executable ($ path . DIRECTORY_SEPARATOR . 'mongocryptd ' )) {
1534- return ;
1578+ return true ;
15351579 }
15361580 }
15371581
1538- $ this -> markTestSkipped ( ' Mongocryptd is not available on the localhost ' ) ;
1582+ return false ;
15391583 }
15401584}
0 commit comments