/
home
/
obinna
/
html
/
cravings
/
vendor
/
mongodb
/
mongodb
/
tests
/
SpecTests
/
Upload File
HOME
<?php namespace MongoDB\Tests\SpecTests; use LogicException; use MongoDB\Client; use MongoDB\Driver\ReadConcern; use MongoDB\Driver\ReadPreference; use MongoDB\Driver\Session; use MongoDB\Driver\WriteConcern; use PHPUnit\Framework\SkippedTestError; use stdClass; use function array_diff_key; use function array_keys; use function getenv; use function implode; use function mt_rand; use function uniqid; /** * Execution context for spec tests. * * This object tracks state that would be difficult to store on the test itself * due to the design of PHPUnit's data providers and setUp/tearDown methods. */ final class Context { /** @var string|null */ public $bucketName; /** @var Client|null */ private $client; /** @var string */ public $collectionName; /** @var string */ public $databaseName; /** @var array */ public $defaultWriteOptions = []; /** @var array */ public $outcomeReadOptions = []; /** @var string */ public $outcomeCollectionName; /** @var Session|null */ public $session0; /** @var object */ public $session0Lsid; /** @var Session|null */ public $session1; /** @var object */ public $session1Lsid; /** @var Client|null */ private $encryptedClient; /** @var bool */ private $useEncryptedClient = false; /** * @param string $databaseName * @param string $collectionName */ private function __construct($databaseName, $collectionName) { $this->databaseName = $databaseName; $this->collectionName = $collectionName; $this->outcomeCollectionName = $collectionName; } public function disableEncryption() { $this->useEncryptedClient = false; } public function enableEncryption() { if (! $this->encryptedClient instanceof Client) { throw new LogicException('Cannot enable encryption without autoEncryption options'); } $this->useEncryptedClient = true; } public static function fromChangeStreams(stdClass $test, $databaseName, $collectionName) { $o = new self($databaseName, $collectionName); $o->client = new Client(FunctionalTestCase::getUri()); return $o; } public static function fromClientSideEncryption(stdClass $test, $databaseName, $collectionName) { $o = new self($databaseName, $collectionName); $clientOptions = isset($test->clientOptions) ? (array) $test->clientOptions : []; /* mongocryptd caches collection information, which causes test failures * if we reuse the client. Thus, we add a random value to ensure we're * creating a new client for each test. */ $driverOptions = ['random' => uniqid()]; $autoEncryptionOptions = []; if (isset($clientOptions['autoEncryptOpts'])) { $autoEncryptionOptions = (array) $clientOptions['autoEncryptOpts'] + ['keyVaultNamespace' => 'admin.datakeys']; unset($clientOptions['autoEncryptOpts']); if (isset($autoEncryptionOptions['kmsProviders']->aws)) { $autoEncryptionOptions['kmsProviders']->aws = self::getAWSCredentials(); } } if (isset($test->outcome->collection->name)) { $o->outcomeCollectionName = $test->outcome->collection->name; } $o->client = new Client(FunctionalTestCase::getUri(), $clientOptions, $driverOptions); if ($autoEncryptionOptions !== []) { $o->encryptedClient = new Client(FunctionalTestCase::getUri(), $clientOptions, $driverOptions + ['autoEncryption' => $autoEncryptionOptions]); } return $o; } public static function fromCommandMonitoring(stdClass $test, $databaseName, $collectionName) { $o = new self($databaseName, $collectionName); $o->client = new Client(FunctionalTestCase::getUri()); return $o; } public static function fromCrud(stdClass $test, $databaseName, $collectionName) { $o = new self($databaseName, $collectionName); $clientOptions = isset($test->clientOptions) ? (array) $test->clientOptions : []; if (isset($test->outcome->collection->name)) { $o->outcomeCollectionName = $test->outcome->collection->name; } $o->defaultWriteOptions = [ 'writeConcern' => new WriteConcern(WriteConcern::MAJORITY), ]; $o->outcomeReadOptions = [ 'readConcern' => new ReadConcern('local'), 'readPreference' => new ReadPreference('primary'), ]; $o->client = new Client(FunctionalTestCase::getUri(), $clientOptions); return $o; } public static function fromRetryableReads(stdClass $test, $databaseName, $collectionName, $bucketName) { $o = new self($databaseName, $collectionName); $o->bucketName = $bucketName; $clientOptions = isset($test->clientOptions) ? (array) $test->clientOptions : []; $o->client = new Client(FunctionalTestCase::getUri(), $clientOptions); return $o; } public static function fromRetryableWrites(stdClass $test, $databaseName, $collectionName, $useMultipleMongoses) { $o = new self($databaseName, $collectionName); $clientOptions = isset($test->clientOptions) ? (array) $test->clientOptions : []; // TODO: Remove this once retryWrites=true by default (see: PHPC-1324) $clientOptions['retryWrites'] = true; if (isset($test->outcome->collection->name)) { $o->outcomeCollectionName = $test->outcome->collection->name; } $o->client = new Client(FunctionalTestCase::getUri($useMultipleMongoses), $clientOptions); return $o; } public static function fromTransactions(stdClass $test, $databaseName, $collectionName, $useMultipleMongoses) { $o = new self($databaseName, $collectionName); $o->defaultWriteOptions = [ 'writeConcern' => new WriteConcern(WriteConcern::MAJORITY), ]; $o->outcomeReadOptions = [ 'readConcern' => new ReadConcern('local'), 'readPreference' => new ReadPreference('primary'), ]; $clientOptions = isset($test->clientOptions) ? (array) $test->clientOptions : []; /* Transaction spec tests expect a new client for each test so that * txnNumber values are deterministic. Append a random option to avoid * re-using a previously persisted libmongoc client object. */ $clientOptions += ['p' => mt_rand()]; $o->client = new Client(FunctionalTestCase::getUri($useMultipleMongoses), $clientOptions); $session0Options = isset($test->sessionOptions->session0) ? (array) $test->sessionOptions->session0 : []; $session1Options = isset($test->sessionOptions->session1) ? (array) $test->sessionOptions->session1 : []; $o->session0 = $o->client->startSession($o->prepareSessionOptions($session0Options)); $o->session1 = $o->client->startSession($o->prepareSessionOptions($session1Options)); $o->session0Lsid = $o->session0->getLogicalSessionId(); $o->session1Lsid = $o->session1->getLogicalSessionId(); return $o; } /** * @return array * * @throws SkippedTestError */ public static function getAWSCredentials() { if (! getenv('AWS_ACCESS_KEY_ID') || ! getenv('AWS_SECRET_ACCESS_KEY')) { throw new SkippedTestError('Please configure AWS credentials to use AWS KMS provider.'); } return [ 'accessKeyId' => getenv('AWS_ACCESS_KEY_ID'), 'secretAccessKey' => getenv('AWS_SECRET_ACCESS_KEY'), ]; } /** * @return Client */ public function getClient() { return $this->useEncryptedClient && $this->encryptedClient ? $this->encryptedClient : $this->client; } public function getCollection(array $collectionOptions = []) { return $this->selectCollection( $this->databaseName, $this->collectionName, $this->prepareOptions($collectionOptions) ); } public function getDatabase(array $databaseOptions = []) { return $this->selectDatabase($this->databaseName, $databaseOptions); } public function getGridFSBucket(array $bucketOptions = []) { return $this->selectGridFSBucket($this->databaseName, $this->bucketName, $bucketOptions); } /** * Prepare options readConcern, readPreference, and writeConcern options by * creating value objects. * * @param array $options * @return array * @throws LogicException if any option keys are unsupported */ public function prepareOptions(array $options) { if (isset($options['readConcern']) && ! ($options['readConcern'] instanceof ReadConcern)) { $readConcern = (array) $options['readConcern']; $diff = array_diff_key($readConcern, ['level' => 1]); if (! empty($diff)) { throw new LogicException('Unsupported readConcern args: ' . implode(',', array_keys($diff))); } $options['readConcern'] = new ReadConcern($readConcern['level']); } if (isset($options['readPreference']) && ! ($options['readPreference'] instanceof ReadPreference)) { $readPreference = (array) $options['readPreference']; $diff = array_diff_key($readPreference, ['mode' => 1]); if (! empty($diff)) { throw new LogicException('Unsupported readPreference args: ' . implode(',', array_keys($diff))); } $options['readPreference'] = new ReadPreference($readPreference['mode']); } if (isset($options['writeConcern']) && ! ($options['writeConcern'] instanceof WriteConcern)) { $writeConcern = (array) $options['writeConcern']; $diff = array_diff_key($writeConcern, ['w' => 1, 'wtimeout' => 1, 'j' => 1]); if (! empty($diff)) { throw new LogicException('Unsupported writeConcern args: ' . implode(',', array_keys($diff))); } $w = $writeConcern['w']; $wtimeout = isset($writeConcern['wtimeout']) ? $writeConcern['wtimeout'] : 0; $j = isset($writeConcern['j']) ? $writeConcern['j'] : null; $options['writeConcern'] = isset($j) ? new WriteConcern($w, $wtimeout, $j) : new WriteConcern($w, $wtimeout); } return $options; } /** * Replace a session placeholder in an operation arguments array. * * Note: this method will modify the $args parameter. * * @param array $args Operation arguments * @throws LogicException if the session placeholder is unsupported */ public function replaceArgumentSessionPlaceholder(array &$args) { if (! isset($args['session'])) { return; } switch ($args['session']) { case 'session0': $args['session'] = $this->session0; break; case 'session1': $args['session'] = $this->session1; break; default: throw new LogicException('Unsupported session placeholder: ' . $args['session']); } } /** * Replace a logical session ID placeholder in a command document. * * Note: this method will modify the $command parameter. * * @param stdClass $command Command document * @throws LogicException if the session placeholder is unsupported */ public function replaceCommandSessionPlaceholder(stdClass $command) { if (! isset($command->lsid)) { return; } switch ($command->lsid) { case 'session0': $command->lsid = $this->session0Lsid; break; case 'session1': $command->lsid = $this->session1Lsid; break; default: throw new LogicException('Unsupported session placeholder: ' . $command->lsid); } } public function selectCollection($databaseName, $collectionName, array $collectionOptions = []) { return $this->getClient()->selectCollection( $databaseName, $collectionName, $this->prepareOptions($collectionOptions) ); } public function selectDatabase($databaseName, array $databaseOptions = []) { return $this->getClient()->selectDatabase( $databaseName, $this->prepareOptions($databaseOptions) ); } public function selectGridFSBucket($databaseName, $bucketName, array $bucketOptions = []) { return $this->selectDatabase($databaseName)->selectGridFSBucket($this->prepareGridFSBucketOptions($bucketOptions, $bucketName)); } private function prepareGridFSBucketOptions(array $options, $bucketPrefix) { if ($bucketPrefix !== null) { $options['bucketPrefix'] = $bucketPrefix; } return $options; } private function prepareSessionOptions(array $options) { if (isset($options['defaultTransactionOptions'])) { $options['defaultTransactionOptions'] = $this->prepareOptions((array) $options['defaultTransactionOptions']); } return $options; } }