diff --git a/.circleci/config.yml b/.circleci/config.yml
index 6519b6c8..1fd7ae26 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -125,7 +125,7 @@ jobs:
- check_mongodb_lib_version
- run_test
- test-replica-set:
+ test-replica-set-mongo:
parameters:
mongo_version: { type: string }
docker:
@@ -153,12 +153,16 @@ workflows:
jobs:
- lint
- test:
- name: test-php74
- php_version: php74
- mongo_version: 4.0.28
+ mongo_version: "4.2"
+ matrix:
+ parameters:
+ php_version:
+ - php74
+ - php84
+ - php85
- test-multiple-stores
- test-replica-set-mmap
- - test-replica-set:
+ - test-replica-set-mongo:
matrix:
parameters:
mongo_version:
diff --git a/.gitignore b/.gitignore
index ad315119..7921eae5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ tags
atlassian-ide-plugin.xml
composer.lock
+docker-compose.override.yml
profiler
test-results
.phpunit.result.cache
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
index 822972a2..14b568e1 100644
--- a/.php-cs-fixer.dist.php
+++ b/.php-cs-fixer.dist.php
@@ -41,4 +41,5 @@
->ignoreVCSIgnored(true)
->ignoreDotFiles(false)
->notPath('rector.php')
+ ->notPath('test/unit/mongo/mocks')
);
diff --git a/README.md b/README.md
index 0cc7514a..d59b4859 100644
--- a/README.md
+++ b/README.md
@@ -31,8 +31,8 @@ Quickstart
require_once("tripod.inc.php");
// Queue worker must register these event listeners
-Resque_Event::listen('beforePerform', [\Tripod\Mongo\Jobs\JobBase::class, 'beforePerform']);
-Resque_Event::listen('onFailure', [\Tripod\Mongo\Jobs\JobBase::class, 'onFailure']);
+Resque\Event::listen('beforePerform', [\Tripod\Mongo\Jobs\JobBase::class, 'beforePerform']);
+Resque\Event::listen('onFailure', [\Tripod\Mongo\Jobs\JobBase::class, 'onFailure']);
\Tripod\Config::setConfig($conf); // set the config, usually read in as JSON from a file
diff --git a/composer.json b/composer.json
index c6a53d78..8ff0f797 100644
--- a/composer.json
+++ b/composer.json
@@ -21,20 +21,23 @@
"resque/php-resque": "Redis backed library for background jobs"
},
"require": {
- "php" : ">=7.4",
+ "php": ">=7.4",
+ "ext-mongodb": ">=1.7.0",
"mongodb/mongodb": "*",
- "monolog/monolog" : "~1.13",
- "semsol/arc2": "2.2.6"
+ "psr/log": "*",
+ "semsol/arc2": "^2.2.6 || ^3.1.0"
},
"require-dev": {
"phpunit/phpunit": "^9.6.20",
- "resque/php-resque": "v1.3.6",
+ "resque/php-resque": "v1.3.6 || dev-develop",
"friendsofphp/php-cs-fixer": "^3.4",
"perftools/php-profiler": "^1.2",
- "phpstan/phpstan": "^2.1"
+ "phpstan/phpstan": "^2.1",
+ "monolog/monolog": "^2.11 || ^3.10"
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": ["src/"],
+ "exclude-from-classmap": ["src/resque/compat.inc.php"]
},
"autoload-dev": {
"classmap": ["test/"]
diff --git a/docker-compose.php-versions.yml b/docker-compose.php-versions.yml
new file mode 100644
index 00000000..1ce89f5a
--- /dev/null
+++ b/docker-compose.php-versions.yml
@@ -0,0 +1,26 @@
+# An override file to allow using separate vendor directories for each PHP version.
+# Usage:
+# 1. Create the directories and composer.lock files for each PHP version:
+# mkdir -p docker/{php74,php84,php85}/vendor
+# echo '{}' > docker/{php74,php84,php85}/composer.lock
+# 2. Run the desired PHP version with the appropriate vendor directory:
+# docker compose -f docker-compose.yml -f docker-compose.php-versions.yml run --rm -it php84
+
+services:
+ php74:
+ volumes:
+ - ./docker/php74/vendor:/var/tripod-php/vendor
+ - ./docker/php74/composer.lock:/var/tripod-php/composer.lock
+
+ php84:
+ volumes:
+ - ./docker/php84/vendor:/var/tripod-php/vendor
+ - ./docker/php84/composer.lock:/var/tripod-php/composer.lock
+
+ php85:
+ volumes:
+ - ./docker/php85/vendor:/var/tripod-php/vendor
+ - ./docker/php85/composer.lock:/var/tripod-php/composer.lock
+
+ mongodb2:
+ image: mongo:4.4
diff --git a/docker-compose.yml b/docker-compose.yml
index 81a577f0..27f5b470 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -11,12 +11,26 @@ services:
php74:
build:
context: ./docker
- dockerfile: Dockerfile-php74
+ dockerfile: php74.Dockerfile
image: talis/tripod-php:php74-latest
<<: *base-config
+ php84:
+ build:
+ context: ./docker
+ dockerfile: php84.Dockerfile
+ image: talis/tripod-php:php84-latest
+ <<: *base-config
+
+ php85:
+ build:
+ context: ./docker
+ dockerfile: php85.Dockerfile
+ image: talis/tripod-php:php85-latest
+ <<: *base-config
+
mongodb:
- image: mongo:3.6.23
+ image: mongo:4.0
redis:
image: valkey/valkey:8-alpine
diff --git a/docker/Dockerfile-php74 b/docker/php74.Dockerfile
similarity index 100%
rename from docker/Dockerfile-php74
rename to docker/php74.Dockerfile
diff --git a/docker/php84.Dockerfile b/docker/php84.Dockerfile
new file mode 100644
index 00000000..400aef2a
--- /dev/null
+++ b/docker/php84.Dockerfile
@@ -0,0 +1,18 @@
+FROM php:8.4.19-cli
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ ca-certificates \
+ curl \
+ git \
+ unzip \
+ zip \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN curl -sLo /tmp/mongosh.deb https://downloads.mongodb.com/compass/mongodb-mongosh_2.6.0_amd64.deb \
+ && dpkg -i /tmp/mongosh.deb \
+ && rm /tmp/mongosh.deb
+
+COPY --from=mlocati/php-extension-installer:2.10.6 /usr/bin/install-php-extensions /usr/local/bin/
+COPY --from=composer:2.9.5 /usr/bin/composer /usr/local/bin/
+
+RUN IPE_ICU_EN_ONLY=1 install-php-extensions pcntl mongodb-1.19.4 xhprof
diff --git a/docker/php85.Dockerfile b/docker/php85.Dockerfile
new file mode 100644
index 00000000..47574e61
--- /dev/null
+++ b/docker/php85.Dockerfile
@@ -0,0 +1,18 @@
+FROM php:8.5.4-cli
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ ca-certificates \
+ curl \
+ git \
+ unzip \
+ zip \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN curl -sLo /tmp/mongosh.deb https://downloads.mongodb.com/compass/mongodb-mongosh_2.6.0_amd64.deb \
+ && dpkg -i /tmp/mongosh.deb \
+ && rm /tmp/mongosh.deb
+
+COPY --from=mlocati/php-extension-installer:2.10.6 /usr/bin/install-php-extensions /usr/local/bin/
+COPY --from=composer:2.9.5 /usr/bin/composer /usr/local/bin/
+
+RUN IPE_ICU_EN_ONLY=1 install-php-extensions pcntl mongodb-2.2.1 xhprof
diff --git a/phpstan.neon b/phpstan.neon
index 951a7121..894e93de 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,15 +1,15 @@
parameters:
level: 6
- phpVersion:
- min: 70400 # PHP 7.4
- max: 80419 # PHP 8.4.19
+ bootstrapFiles:
+ - src/resque/compat.inc.php
tips:
treatPhpDocTypesAsCertain: false
ignoreErrors:
- - '#Access to undefined constant MongoDB\\Driver\\ReadPreference\:\:RP_.*#'
- - '#Call to an undefined method MongoDB\\Driver\\ReadPreference\:\:getMode\(\)#'
- identifier: missingType.iterableValue
reportUnmatched: false
paths:
- src
- test
+ excludePaths:
+ - src/resque/compat.inc.php
+ - test/unit/mongo/mocks
diff --git a/scripts/mongo/worker.inc.php b/scripts/mongo/worker.inc.php
index 1ecedcf7..596565c8 100644
--- a/scripts/mongo/worker.inc.php
+++ b/scripts/mongo/worker.inc.php
@@ -9,8 +9,7 @@
require_once __DIR__ . '/../../src/tripod.inc.php';
// the global is necessary for Resque worker to send statements to
-$logger = new Logger('TRIPOD-WORKER');
-$logger->pushHandler(new StreamHandler('php://stderr', LogLevel::WARNING)); // resque too chatty on NOTICE & INFO. YMMV
+$logger = new Logger('TRIPOD-WORKER', [new StreamHandler('php://stderr', LogLevel::NOTICE)]);
// this is so tripod itself uses the same logger
-DriverBase::$logger = new Logger('TRIPOD-JOB', [new StreamHandler('php://stderr', LogLevel::DEBUG)]);
+DriverBase::$logger = $logger;
diff --git a/src/classes/ChangeSet.php b/src/classes/ChangeSet.php
index cac45c1c..8be74883 100644
--- a/src/classes/ChangeSet.php
+++ b/src/classes/ChangeSet.php
@@ -78,7 +78,7 @@ public function __construct(array $a)
$parser->parse(false, $a[$rdf]);
$a[$rdf] = $parser->getSimpleIndex(0);
} elseif (
- is_array($a[$rdf]) && isset($a[$rdf][0], $a[$rdf][0]['s'])
+ is_array($a[$rdf]) && isset($a[$rdf][0]['s'])
) { // triples array
/** @var \ARC2_RDFSerializer $ser */
$ser = \ARC2::getTurtleSerializer();
diff --git a/src/classes/ExtendedGraph.php b/src/classes/ExtendedGraph.php
index ff7d6689..1001c031 100644
--- a/src/classes/ExtendedGraph.php
+++ b/src/classes/ExtendedGraph.php
@@ -116,11 +116,6 @@ public function __construct($graph = null)
}
}
- public function __destruct()
- {
- unset($this->_index);
- }
-
/**
* Map a portion of a URI to a short prefix for use when serialising the graph.
*
diff --git a/src/mongo/Config.php b/src/mongo/Config.php
index 38e8c1d9..a9b5ee22 100644
--- a/src/mongo/Config.php
+++ b/src/mongo/Config.php
@@ -568,11 +568,9 @@ public function getSearchProviderClassName(string $storeName): ?string
}
/**
- * @param int|string $readPreference
- *
* @throws ConfigException
*/
- public function getDatabase(string $storeName, ?string $dataSource = null, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Database
+ public function getDatabase(string $storeName, ?string $dataSource = null, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Database
{
if (!isset($this->dbConfig[$storeName])) {
throw new ConfigException(sprintf("Store name '%s' not in configuration", $storeName));
@@ -590,13 +588,11 @@ public function getDatabase(string $storeName, ?string $dataSource = null, $read
}
/**
- * @param int|string $readPreference
- *
* @throws ConfigException
*/
- public function getCollectionForCBD(string $storeName, string $podName, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection
+ public function getCollectionForCBD(string $storeName, string $podName, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection
{
- if (isset($this->podConnections[$storeName], $this->podConnections[$storeName][$podName])) {
+ if (isset($this->podConnections[$storeName][$podName])) {
return $this->getMongoCollection(
$this->getDatabase($storeName, $this->podConnections[$storeName][$podName], $readPreference),
$podName
@@ -607,11 +603,9 @@ public function getCollectionForCBD(string $storeName, string $podName, $readPre
}
/**
- * @param int|string $readPreference
- *
* @throws ConfigException
*/
- public function getCollectionForView(string $storeName, string $viewId, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection
+ public function getCollectionForView(string $storeName, string $viewId, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection
{
if (!isset($this->viewSpecs[$storeName][$viewId])) {
throw new ConfigException(sprintf("View id '%s' not in configuration for store '%s'", $viewId, $storeName));
@@ -626,11 +620,9 @@ public function getCollectionForView(string $storeName, string $viewId, $readPre
}
/**
- * @param int|string $readPreference
- *
* @throws ConfigException
*/
- public function getCollectionForSearchDocument(string $storeName, string $searchDocumentId, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection
+ public function getCollectionForSearchDocument(string $storeName, string $searchDocumentId, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection
{
if (!isset($this->searchDocSpecs[$storeName][$searchDocumentId])) {
throw new ConfigException(sprintf("Search document id '%s' not in configuration for store '%s'", $searchDocumentId, $storeName));
@@ -645,11 +637,9 @@ public function getCollectionForSearchDocument(string $storeName, string $search
}
/**
- * @param int|string $readPreference
- *
* @throws ConfigException
*/
- public function getCollectionForTable(string $storeName, string $tableId, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection
+ public function getCollectionForTable(string $storeName, string $tableId, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection
{
if (!isset($this->tableSpecs[$storeName][$tableId])) {
throw new ConfigException(sprintf("Table id '%s' not in configuration for store '%s'", $tableId, $storeName));
@@ -664,13 +654,11 @@ public function getCollectionForTable(string $storeName, string $tableId, $readP
}
/**
- * @param int|string $readPreference
- *
* @return Collection[]
*
* @throws ConfigException
*/
- public function getCollectionsForTables(string $storeName, array $tables = [], $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): array
+ public function getCollectionsForTables(string $storeName, array $tables = [], string $readPreference = ReadPreference::PRIMARY_PREFERRED): array
{
if (!isset($this->tableSpecs[$storeName])) {
return [];
@@ -701,13 +689,11 @@ public function getCollectionsForTables(string $storeName, array $tables = [], $
}
/**
- * @param int|string $readPreference
- *
* @return Collection[]
*
* @throws ConfigException
*/
- public function getCollectionsForViews(string $storeName, array $views = [], $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): array
+ public function getCollectionsForViews(string $storeName, array $views = [], string $readPreference = ReadPreference::PRIMARY_PREFERRED): array
{
if (!isset($this->viewSpecs[$storeName])) {
return [];
@@ -738,13 +724,11 @@ public function getCollectionsForViews(string $storeName, array $views = [], $re
}
/**
- * @param int|string $readPreference
- *
* @return Collection[]
*
* @throws ConfigException
*/
- public function getCollectionsForSearch(string $storeName, array $searchSpecIds = [], $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): array
+ public function getCollectionsForSearch(string $storeName, array $searchSpecIds = [], string $readPreference = ReadPreference::PRIMARY_PREFERRED): array
{
if (!isset($this->searchDocSpecs[$storeName])) {
return [];
@@ -774,10 +758,7 @@ public function getCollectionsForSearch(string $storeName, array $searchSpecIds
return $collections;
}
- /**
- * @param int|string $readPreference
- */
- public function getCollectionForTTLCache(string $storeName, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection
+ public function getCollectionForTTLCache(string $storeName, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection
{
return $this->getMongoCollection(
$this->getDatabase($storeName, $this->dbConfig[$storeName]['data_source'], $readPreference),
@@ -785,10 +766,7 @@ public function getCollectionForTTLCache(string $storeName, $readPreference = Re
);
}
- /**
- * @param int|string $readPreference
- */
- public function getCollectionForLocks(string $storeName, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection
+ public function getCollectionForLocks(string $storeName, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection
{
return $this->getMongoCollection(
$this->getDatabase($storeName, $this->dbConfig[$storeName]['data_source'], $readPreference),
@@ -796,10 +774,7 @@ public function getCollectionForLocks(string $storeName, $readPreference = ReadP
);
}
- /**
- * @param int|string $readPreference
- */
- public function getCollectionForManualRollbackAudit(string $storeName, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection
+ public function getCollectionForManualRollbackAudit(string $storeName, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection
{
return $this->getMongoCollection(
$this->getDatabase($storeName, $this->dbConfig[$storeName]['data_source'], $readPreference),
@@ -807,10 +782,7 @@ public function getCollectionForManualRollbackAudit(string $storeName, $readPref
);
}
- /**
- * @param int|string $readPreference
- */
- public function getCollectionForJobGroups(string $storeName, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection
+ public function getCollectionForJobGroups(string $storeName, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection
{
return $this->getMongoCollection(
$this->getDatabase($storeName, $this->dbConfig[$storeName]['data_source'], $readPreference),
@@ -819,11 +791,9 @@ public function getCollectionForJobGroups(string $storeName, $readPreference = R
}
/**
- * @param int|string $readPreference
- *
* @throws ConfigException
*/
- public function getTransactionLogDatabase($readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Database
+ public function getTransactionLogDatabase(string $readPreference = ReadPreference::PRIMARY_PREFERRED): Database
{
$client = $this->getConnectionForDataSource($this->tConfig['data_source']);
$db = $client->selectDatabase($this->tConfig['database']);
diff --git a/src/mongo/Driver.php b/src/mongo/Driver.php
index 61741321..495f8472 100755
--- a/src/mongo/Driver.php
+++ b/src/mongo/Driver.php
@@ -41,7 +41,7 @@ class Driver extends DriverBase implements IDriver
*
defaultContext: (string) to use where a specific default context is not defined. Default is Null
* async: (array) determines the async behaviour of views, tables and search. For each of these array keys, if set to true, generation of these elements will be done asyncronously on save. Default is array(OP_VIEWS=>false,OP_TABLES=>true,OP_SEARCH=>true)
* stat: this sets the stats object to use to record statistics around operations performed by Driver. Default is null
- * readPreference: The Read preference to set for Mongo: Default is ReadPreference::RP_PRIMARY_PREFERRED
+ * readPreference: The Read preference to set for Mongo: Default is ReadPreference::PRIMARY_PREFERRED
* retriesToGetLock: Retries to do when unable to get lock on a document, default is 20
*/
public function __construct(string $podName, string $storeName, array $opts = [])
@@ -50,7 +50,7 @@ public function __construct(string $podName, string $storeName, array $opts = []
'defaultContext' => null,
OP_ASYNC => [OP_VIEWS => false, OP_TABLES => true, OP_SEARCH => true],
'statsConfig' => [],
- 'readPreference' => ReadPreference::RP_PRIMARY_PREFERRED,
+ 'readPreference' => ReadPreference::PRIMARY_PREFERRED,
'retriesToGetLock' => 20,
], $opts);
@@ -321,7 +321,7 @@ public function getCount(array $query, ?string $groupBy = null, ?int $ttl = null
$cursor = $this->collection->aggregate($ops);
foreach ($cursor as $doc) {
if (!is_array($doc[_ID_KEY])) {
- $results[$doc[_ID_KEY]] = $doc['total'];
+ $results[$doc[_ID_KEY] ?? ''] = $doc['total'];
} else {
$results[implode(';', $doc[_ID_KEY])] = $doc['total'];
}
@@ -618,7 +618,7 @@ protected function getLabeller(): Labeller
protected function getDataUpdater(): Updates
{
if ($this->updates === null) {
- $readPreference = $this->collection->getReadPreference()->getMode();
+ $readPreference = $this->collection->getReadPreference()->getModeString();
$opts = [
'defaultContext' => $this->defaultContext,
diff --git a/src/mongo/IConfigInstance.php b/src/mongo/IConfigInstance.php
index 05fbf287..f83bd5bd 100644
--- a/src/mongo/IConfigInstance.php
+++ b/src/mongo/IConfigInstance.php
@@ -184,56 +184,56 @@ public function getSearchProviderClassName(string $storeName): ?string;
/**
* @param string $storeName Store (database) name
* @param string|null $dataSource Database server identifier
- * @param int|string $readPreference Mongo read preference
+ * @param string $readPreference Mongo read preference
*
* @throws ConfigException
*/
- public function getDatabase(string $storeName, ?string $dataSource = null, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Database;
+ public function getDatabase(string $storeName, ?string $dataSource = null, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Database;
/**
- * @param string $storeName Store (database) name
- * @param string $podName Pod (collection) name
- * @param int|string $readPreference Mongo read preference
+ * @param string $storeName Store (database) name
+ * @param string $podName Pod (collection) name
+ * @param string $readPreference Mongo read preference
*
* @throws ConfigException
*/
- public function getCollectionForCBD(string $storeName, string $podName, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection;
+ public function getCollectionForCBD(string $storeName, string $podName, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection;
/**
- * @param string $storeName Store (database) name
- * @param string $viewId View spec ID
- * @param int|string $readPreference Mongo read preference
+ * @param string $storeName Store (database) name
+ * @param string $viewId View spec ID
+ * @param string $readPreference Mongo read preference
*
* @throws ConfigException
*/
- public function getCollectionForView(string $storeName, string $viewId, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection;
+ public function getCollectionForView(string $storeName, string $viewId, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection;
/**
- * @param string $storeName Store (database) name
- * @param string $searchDocumentId Search document spec ID
- * @param int|string $readPreference Mongo read preference
+ * @param string $storeName Store (database) name
+ * @param string $searchDocumentId Search document spec ID
+ * @param string $readPreference Mongo read preference
*
* @throws ConfigException
*/
public function getCollectionForSearchDocument(
string $storeName,
string $searchDocumentId,
- $readPreference = ReadPreference::RP_PRIMARY_PREFERRED
+ string $readPreference = ReadPreference::PRIMARY_PREFERRED
): Collection;
/**
- * @param string $storeName Store (database) name
- * @param string $tableId Table spec ID
- * @param int|string $readPreference Mongo read preference
+ * @param string $storeName Store (database) name
+ * @param string $tableId Table spec ID
+ * @param string $readPreference Mongo read preference
*
* @throws ConfigException
*/
- public function getCollectionForTable(string $storeName, string $tableId, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection;
+ public function getCollectionForTable(string $storeName, string $tableId, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection;
/**
- * @param string $storeName Store (database) name
- * @param array $tables Array of table spec IDs
- * @param int|string $readPreference Mongo read preference
+ * @param string $storeName Store (database) name
+ * @param array $tables Array of table spec IDs
+ * @param string $readPreference Mongo read preference
*
* @return Collection[]
*
@@ -242,13 +242,13 @@ public function getCollectionForTable(string $storeName, string $tableId, $readP
public function getCollectionsForTables(
string $storeName,
array $tables = [],
- $readPreference = ReadPreference::RP_PRIMARY_PREFERRED
+ string $readPreference = ReadPreference::PRIMARY_PREFERRED
): array;
/**
- * @param string $storeName Store (database) name
- * @param array $views Array of view spec IDs
- * @param int|string $readPreference Mongo read preference
+ * @param string $storeName Store (database) name
+ * @param array $views Array of view spec IDs
+ * @param string $readPreference Mongo read preference
*
* @return Collection[]
*
@@ -257,13 +257,13 @@ public function getCollectionsForTables(
public function getCollectionsForViews(
string $storeName,
array $views = [],
- $readPreference = ReadPreference::RP_PRIMARY_PREFERRED
+ string $readPreference = ReadPreference::PRIMARY_PREFERRED
): array;
/**
- * @param string $storeName Store (database) name
- * @param array $searchSpecIds Array of search document spec IDs
- * @param int|string $readPreference Mongo read preference
+ * @param string $storeName Store (database) name
+ * @param array $searchSpecIds Array of search document spec IDs
+ * @param string $readPreference Mongo read preference
*
* @return Collection[]
*
@@ -272,41 +272,38 @@ public function getCollectionsForViews(
public function getCollectionsForSearch(
string $storeName,
array $searchSpecIds = [],
- $readPreference = ReadPreference::RP_PRIMARY_PREFERRED
+ string $readPreference = ReadPreference::PRIMARY_PREFERRED
): array;
/**
- * @param string $storeName Store (database) name
- * @param int|string $readPreference Mongo read preference
+ * @param string $storeName Store (database) name
+ * @param string $readPreference Mongo read preference
*/
- public function getCollectionForTTLCache(string $storeName, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection;
+ public function getCollectionForTTLCache(string $storeName, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection;
- /**
- * @param int|string $readPreference
- */
- public function getCollectionForLocks(string $storeName, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection;
+ public function getCollectionForLocks(string $storeName, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection;
/**
- * @param string $storeName Store (database) name
- * @param int|string $readPreference Mongo read preference
+ * @param string $storeName Store (database) name
+ * @param string $readPreference Mongo read preference
*/
public function getCollectionForManualRollbackAudit(
string $storeName,
- $readPreference = ReadPreference::RP_PRIMARY_PREFERRED
+ string $readPreference = ReadPreference::PRIMARY_PREFERRED
): Collection;
/**
- * @param string $storeName Store (database) name
- * @param int|string $readPreference Mongo read preference
+ * @param string $storeName Store (database) name
+ * @param string $readPreference Mongo read preference
*/
- public function getCollectionForJobGroups(string $storeName, $readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Collection;
+ public function getCollectionForJobGroups(string $storeName, string $readPreference = ReadPreference::PRIMARY_PREFERRED): Collection;
/**
- * @param int|string $readPreference Mongo read preference
+ * @param string $readPreference Mongo read preference
*
* @throws ConfigException
*/
- public function getTransactionLogDatabase($readPreference = ReadPreference::RP_PRIMARY_PREFERRED): Database;
+ public function getTransactionLogDatabase(string $readPreference = ReadPreference::PRIMARY_PREFERRED): Database;
/**
* Return the maximum batch size for async operations.
diff --git a/src/mongo/ImpactedSubject.php b/src/mongo/ImpactedSubject.php
index a4a00044..bb647884 100644
--- a/src/mongo/ImpactedSubject.php
+++ b/src/mongo/ImpactedSubject.php
@@ -126,7 +126,7 @@ public function update(): void
protected function getTripod(): Driver
{
return new Driver($this->getPodName(), $this->getStoreName(), [
- 'readPreference' => ReadPreference::RP_PRIMARY,
+ 'readPreference' => ReadPreference::PRIMARY,
]);
}
}
diff --git a/src/mongo/base/DriverBase.php b/src/mongo/base/DriverBase.php
index f165189b..f2ded43c 100644
--- a/src/mongo/base/DriverBase.php
+++ b/src/mongo/base/DriverBase.php
@@ -7,10 +7,10 @@
use MongoDB\Collection;
use MongoDB\Database;
use MongoDB\Driver\ReadPreference;
-use Monolog\Logger;
use Psr\Log\LoggerInterface;
-use Psr\Log\LogLevel;
+use Psr\Log\NullLogger;
use Tripod\ITripodStat;
+use Tripod\LoggerTrait;
use Tripod\Mongo\Composites\Views;
use Tripod\StatsD;
use Tripod\Timer;
@@ -18,6 +18,8 @@
abstract class DriverBase
{
+ use LoggerTrait;
+
public static ?LoggerInterface $logger = null;
protected string $storeName;
@@ -34,15 +36,24 @@ abstract class DriverBase
protected ?Collection $collection = null;
- /**
- * @var int|string
- */
- protected $readPreference = ReadPreference::RP_PRIMARY_PREFERRED;
+ protected string $readPreference = ReadPreference::PRIMARY_PREFERRED;
protected Labeller $labeller;
protected IConfigInstance $config;
+ /**
+ * @codeCoverageIgnore
+ */
+ public static function getLogger(): LoggerInterface
+ {
+ if (self::$logger == null) {
+ self::$logger = new NullLogger();
+ }
+
+ return self::$logger;
+ }
+
public function getStat(): ITripodStat
{
if ($this->stat == null) {
@@ -80,64 +91,6 @@ public function getPodName(): string
return $this->podName;
}
- /**
- * @codeCoverageIgnore
- */
- public function timingLog(string $type, ?array $params = null): void
- {
- $type = '[PID ' . getmypid() . '] ' . $type;
- $this->log(LogLevel::DEBUG, $type, $params);
- }
-
- /**
- * @codeCoverageIgnore
- */
- public function infoLog(string $message, ?array $params = null): void
- {
- $message = '[PID ' . getmypid() . '] ' . $message;
- $this->log(LogLevel::INFO, $message, $params);
- }
-
- /**
- * @codeCoverageIgnore
- */
- public function debugLog(string $message, ?array $params = null): void
- {
- $message = '[PID ' . getmypid() . '] ' . $message;
- $this->log(LogLevel::DEBUG, $message, $params);
- }
-
- /**
- * @codeCoverageIgnore
- */
- public function errorLog(string $message, ?array $params = null): void
- {
- $message = '[PID ' . getmypid() . '] ' . $message;
- $this->log(LogLevel::ERROR, $message, $params);
- }
-
- /**
- * @codeCoverageIgnore
- */
- public function warningLog(string $message, ?array $params = null): void
- {
- $message = '[PID ' . getmypid() . '] ' . $message;
- $this->log(LogLevel::WARNING, $message, $params);
- }
-
- /**
- * @codeCoverageIgnore
- */
- public static function getLogger(): LoggerInterface
- {
- if (self::$logger == null) {
- $log = new Logger('TRIPOD');
- self::$logger = $log;
- }
-
- return self::$logger;
- }
-
/**
* For mocking out the creation of stat objects.
*/
@@ -320,12 +273,4 @@ protected function getCollection(): Collection
return $this->collection;
}
-
- /**
- * @codeCoverageIgnore
- */
- private function log(string $level, string $message, ?array $params): void
- {
- self::getLogger()->log($level, $message, $params ?: []);
- }
}
diff --git a/src/mongo/base/JobBase.php b/src/mongo/base/JobBase.php
index 63af5ac1..dfd6cae8 100644
--- a/src/mongo/base/JobBase.php
+++ b/src/mongo/base/JobBase.php
@@ -5,45 +5,33 @@
namespace Tripod\Mongo\Jobs;
use MongoDB\Driver\ReadPreference;
+use Psr\Log\LoggerInterface;
+use Resque\Job\Job;
+use Resque\Job\Status;
+use Resque\JobHandler;
+use Resque\Resque;
use Tripod\Config;
use Tripod\Exceptions\Exception;
use Tripod\Exceptions\JobException;
use Tripod\ITripodConfigSerializer;
use Tripod\ITripodStat;
+use Tripod\LoggerTrait;
use Tripod\Mongo\Driver;
use Tripod\Mongo\DriverBase;
use Tripod\Mongo\IConfigInstance;
use Tripod\Timer;
+use Tripod\TripodStatFactory;
-abstract class JobBase extends DriverBase
+abstract class JobBase extends Job
{
+ use LoggerTrait;
+
public const TRIPOD_CONFIG_KEY = 'tripodConfig';
public const TRIPOD_CONFIG_GENERATOR = 'tripodConfigGenerator';
public const QUEUE_KEY = 'queue';
- /**
- * Resque Job arguments, set by Resque_Job_Factory.
- *
- * @var array
- */
- public $args;
-
- /**
- * Resque Job queue, set by Resque_Job_Factory.
- *
- * @var string
- */
- public $queue;
-
- /**
- * Resque Job.
- *
- * @var \Resque_Job
- */
- public $job;
-
/**
* @var string[]
*/
@@ -54,6 +42,10 @@ abstract class JobBase extends DriverBase
*/
protected $configRequired = false;
+ protected ?ITripodStat $stat = null;
+
+ protected array $statsConfig = [];
+
protected ?IConfigInstance $tripodConfig = null;
protected ?Timer $timer = null;
@@ -95,7 +87,7 @@ abstract public function perform(): void;
/**
* Called in every job prior to perform().
*/
- public static function beforePerform(\Resque_Job $job): void
+ public static function beforePerform(JobHandler $job): void
{
$instance = $job->getInstance();
if (!$instance instanceof self) {
@@ -109,9 +101,9 @@ public static function beforePerform(\Resque_Job $job): void
* Resque event when a job failures.
*
* @param \Exception|\Throwable $e Exception or Error
- * @param \Resque_Job $job The failed job
+ * @param JobHandler $job The failed job
*/
- public static function onFailure($e, \Resque_Job $job): void
+ public static function onFailure($e, JobHandler $job): void
{
$failedJob = $job->getInstance();
if (!$failedJob instanceof self) {
@@ -122,13 +114,27 @@ public static function onFailure($e, \Resque_Job $job): void
$failedJob->getStat()->increment($failedJob->getStatFailureIncrementKey());
}
+ public static function getLogger(): LoggerInterface
+ {
+ return DriverBase::getLogger();
+ }
+
public function getStat(): ITripodStat
{
if ($this->statsConfig === []) {
$this->getStatsConfig();
}
- return parent::getStat();
+ if ($this->stat == null) {
+ $this->setStat($this->getStatFromStatFactory());
+ }
+
+ return $this->stat;
+ }
+
+ public function setStat(ITripodStat $stat): void
+ {
+ $this->stat = $stat;
}
/**
@@ -143,6 +149,14 @@ public function getStatsConfig(): array
return $this->statsConfig;
}
+ /**
+ * For mocking out the creation of stat objects.
+ */
+ protected function getStatFromStatFactory(): ITripodStat
+ {
+ return TripodStatFactory::create($this->statsConfig);
+ }
+
/**
* Stat string for successful job timer.
*/
@@ -161,7 +175,7 @@ protected function getTripod(string $storeName, string $podName, array $opts = [
$opts,
[
'stat' => $this->getStat(),
- 'readPreference' => ReadPreference::RP_PRIMARY, // important: make sure we always read from the primary
+ 'readPreference' => ReadPreference::PRIMARY, // important: make sure we always read from the primary
]
);
if ($this->tripod == null) {
@@ -267,7 +281,7 @@ protected function submitJob(string $queueName, string $class, array $data, int
*/
protected function enqueue(string $queueName, string $class, array $data)
{
- return \Resque::enqueue($queueName, $class, $data, true);
+ return Resque::enqueue($queueName, $class, $data, true);
}
/**
@@ -275,7 +289,7 @@ protected function enqueue(string $queueName, string $class, array $data)
*/
protected function hasJobStatus(string $token): bool
{
- $status = new \Resque_Job_Status($token);
+ $status = new Status($token);
return !empty($status->get());
}
@@ -312,6 +326,14 @@ protected function deserializeConfig(array $config): IConfigInstance
return Config::getInstance();
}
+ /**
+ * For mocking.
+ */
+ protected function getConfigInstance(): IConfigInstance
+ {
+ return Config::getInstance();
+ }
+
/**
* Sets the Tripod config for the job.
*/
diff --git a/src/mongo/delegates/SearchDocuments.php b/src/mongo/delegates/SearchDocuments.php
index 91ace9e0..f8c1ccab 100644
--- a/src/mongo/delegates/SearchDocuments.php
+++ b/src/mongo/delegates/SearchDocuments.php
@@ -14,10 +14,8 @@ class SearchDocuments extends DriverBase
/**
* Construct accepts actual objects rather than strings as this class is a delegate of
* Tripod and should inherit connections set up there.
- *
- * @param int|string $readPreference
*/
- public function __construct(string $storeName, Collection $collection, string $defaultContext, ?ITripodStat $stat = null, $readPreference = ReadPreference::RP_PRIMARY)
+ public function __construct(string $storeName, Collection $collection, string $defaultContext, ?ITripodStat $stat = null, string $readPreference = ReadPreference::PRIMARY)
{
$this->labeller = new Labeller();
$this->storeName = $storeName;
diff --git a/src/mongo/delegates/SearchIndexer.php b/src/mongo/delegates/SearchIndexer.php
index 405ad2ea..ffbb17bd 100644
--- a/src/mongo/delegates/SearchIndexer.php
+++ b/src/mongo/delegates/SearchIndexer.php
@@ -23,11 +23,9 @@ class SearchIndexer extends CompositeBase
private ?ISearchProvider $searchProvider = null;
/**
- * @param int|string $readPreference
- *
* @throws SearchException
*/
- public function __construct(Driver $tripod, $readPreference = ReadPreference::RP_PRIMARY)
+ public function __construct(Driver $tripod, string $readPreference = ReadPreference::PRIMARY)
{
$this->tripod = $tripod;
$this->storeName = $tripod->getStoreName();
diff --git a/src/mongo/delegates/Tables.php b/src/mongo/delegates/Tables.php
index 869a81f8..1d553203 100644
--- a/src/mongo/delegates/Tables.php
+++ b/src/mongo/delegates/Tables.php
@@ -68,15 +68,13 @@ class Tables extends CompositeBase
/**
* Construct accepts actual objects rather than strings as this class is a delegate of
* Tripod and should inherit connections set up there.
- *
- * @param int|string $readPreference
*/
public function __construct(
string $storeName,
Collection $collection,
?string $defaultContext,
?ITripodStat $stat = null,
- $readPreference = ReadPreference::RP_PRIMARY
+ string $readPreference = ReadPreference::PRIMARY
) {
$this->labeller = new Labeller();
$this->storeName = $storeName;
diff --git a/src/mongo/delegates/Updates.php b/src/mongo/delegates/Updates.php
index 3c668fd2..7ba365ce 100644
--- a/src/mongo/delegates/Updates.php
+++ b/src/mongo/delegates/Updates.php
@@ -40,14 +40,14 @@ class Updates extends DriverBase
private ?TransactionLog $transactionLog = null;
/**
- * @var int|string the original read preference gets stored here when changing for a write
+ * @var string the original read preference gets stored here when changing for a write
*/
- private $originalCollectionReadPreference = '';
+ private string $originalCollectionReadPreference = '';
/**
- * @var int|string the original read preference gets stored here when changing for a write
+ * @var string the original read preference gets stored here when changing for a write
*/
- private $originalDbReadPreference = '';
+ private string $originalDbReadPreference = '';
private int $retriesToGetLock;
@@ -74,7 +74,7 @@ public function __construct(Driver $tripod, array $opts = [])
'defaultContext' => null,
OP_ASYNC => [OP_VIEWS => false, OP_TABLES => true, OP_SEARCH => true],
'stat' => null,
- 'readPreference' => ReadPreference::RP_PRIMARY_PREFERRED,
+ 'readPreference' => ReadPreference::PRIMARY_PREFERRED,
'retriesToGetLock' => 20,
], $opts);
$this->readPreference = $opts['readPreference'];
@@ -396,23 +396,23 @@ protected function setReadPreferenceToPrimary(): void
/** @var ReadPreference $dbReadPref */
$dbReadPref = $this->getDatabase()->getReadPreference();
- $dbPref = $dbReadPref->getMode();
+ $dbPref = $dbReadPref->getModeString();
$dbTagsets = $dbReadPref->getTagsets();
- $this->originalDbReadPreference = $this->db->getReadPreference()->getMode();
- if ($dbPref !== ReadPreference::RP_PRIMARY) {
- $this->db = $this->db->withOptions(['readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY, $dbTagsets)]);
+ $this->originalDbReadPreference = $this->db->getReadPreference()->getModeString();
+ if ($dbPref !== ReadPreference::PRIMARY) {
+ $this->db = $this->db->withOptions(['readPreference' => new ReadPreference(ReadPreference::PRIMARY, $dbTagsets)]);
}
/** @var ReadPreference $collReadPref */
$collReadPref = $this->getCollection()->getReadPreference();
- $collPref = $collReadPref->getMode();
+ $collPref = $collReadPref->getModeString();
$collTagsets = $collReadPref->getTagsets();
// Set collection preference
$this->originalCollectionReadPreference = $collPref;
- if ($collPref !== ReadPreference::RP_PRIMARY) {
- $this->collection = $this->collection->withOptions(['readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY, $collTagsets)]);
+ if ($collPref !== ReadPreference::PRIMARY) {
+ $this->collection = $this->collection->withOptions(['readPreference' => new ReadPreference(ReadPreference::PRIMARY, $collTagsets)]);
}
}
@@ -422,7 +422,7 @@ protected function setReadPreferenceToPrimary(): void
protected function resetOriginalReadPreference(): void
{
$dbReadPref = $this->db->getReadPreference();
- if ($this->originalDbReadPreference !== $dbReadPref->getMode()) {
+ if ($this->originalDbReadPreference !== $dbReadPref->getModeString()) {
$pref = $this->originalDbReadPreference ?: $this->readPreference;
$dbTagsets = $dbReadPref->getTagsets();
@@ -433,7 +433,7 @@ protected function resetOriginalReadPreference(): void
// Reset collection object
$collReadPref = $this->getCollection()->getReadPreference();
- if ($this->originalCollectionReadPreference !== $collReadPref->getMode()) {
+ if ($this->originalCollectionReadPreference !== $collReadPref->getModeString()) {
$pref = $this->originalCollectionReadPreference ?: $this->readPreference;
$collTagsets = $collReadPref->getTagsets();
$this->collection = $this->collection->withOptions([
diff --git a/src/mongo/delegates/Views.php b/src/mongo/delegates/Views.php
index 0955a56f..e445c2d5 100644
--- a/src/mongo/delegates/Views.php
+++ b/src/mongo/delegates/Views.php
@@ -23,10 +23,8 @@ class Views extends CompositeBase
/**
* Construct accepts actual objects rather than strings as this class is a delegate of
* Tripod and should inherit connections set up there.
- *
- * @param int|string $readPreference
*/
- public function __construct(string $storeName, Collection $collection, ?string $defaultContext, ?ITripodStat $stat = null, $readPreference = ReadPreference::RP_PRIMARY)
+ public function __construct(string $storeName, Collection $collection, ?string $defaultContext, ?ITripodStat $stat = null, string $readPreference = ReadPreference::PRIMARY)
{
$this->storeName = $storeName;
$this->labeller = new Labeller();
@@ -671,7 +669,7 @@ protected function extractProperties(array $source, array $viewSpec, string $fro
$obj[$p] = $source[$p];
}
- if (isset($source[$p], $source[$p][$i])) {
+ if (isset($source[$p][$i])) {
if (!isset($obj[$p])) {
$obj[$p] = [];
}
@@ -686,7 +684,7 @@ protected function extractProperties(array $source, array $viewSpec, string $fro
}
} else {
foreach ($source as $p => $val) {
- if (isset($viewSpec['joins'], $viewSpec['joins'][$p], $viewSpec['joins'][$p]['maxJoins'])) {
+ if (isset($viewSpec['joins'][$p]['maxJoins'])) {
// todo: refactor with above (extract method)
// only include up to maxJoins
for ($i = 0; $i < $viewSpec['joins'][$p]['maxJoins']; $i++) {
@@ -695,7 +693,7 @@ protected function extractProperties(array $source, array $viewSpec, string $fro
}
if ($val && isset($val[$i])) {
- if (!$obj[$p]) {
+ if (!isset($obj[$p])) {
$obj[$p] = [];
}
diff --git a/src/resque/compat.inc.php b/src/resque/compat.inc.php
new file mode 100644
index 00000000..20dbf9f2
--- /dev/null
+++ b/src/resque/compat.inc.php
@@ -0,0 +1,86 @@
+log(LogLevel::DEBUG, $type, $params);
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ public function infoLog(string $message, ?array $params = null): void
+ {
+ $message = '[PID ' . getmypid() . '] ' . $message;
+ $this->log(LogLevel::INFO, $message, $params);
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ public function debugLog(string $message, ?array $params = null): void
+ {
+ $message = '[PID ' . getmypid() . '] ' . $message;
+ $this->log(LogLevel::DEBUG, $message, $params);
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ public function errorLog(string $message, ?array $params = null): void
+ {
+ $message = '[PID ' . getmypid() . '] ' . $message;
+ $this->log(LogLevel::ERROR, $message, $params);
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ public function warningLog(string $message, ?array $params = null): void
+ {
+ $message = '[PID ' . getmypid() . '] ' . $message;
+ $this->log(LogLevel::WARNING, $message, $params);
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ private function log(string $level, string $message, ?array $params): void
+ {
+ self::getLogger()->log($level, $message, $params ?: []);
+ }
+}
diff --git a/src/tripod.inc.php b/src/tripod.inc.php
index 75d0a1d8..14e1dc97 100644
--- a/src/tripod.inc.php
+++ b/src/tripod.inc.php
@@ -7,8 +7,9 @@
}
require_once TRIPOD_DIR . '/mongo/MongoTripodConstants.php';
+require_once TRIPOD_DIR . '/resque/compat.inc.php';
-Resque::setBackend(Config::getResqueServer());
+Resque\Resque::setBackend(Config::getResqueServer());
define('RDF_TYPE', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
define('RDF_SUBJECT', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#subject');
diff --git a/test/bootstrap.php b/test/bootstrap.php
index 14962e0f..c0dcd354 100644
--- a/test/bootstrap.php
+++ b/test/bootstrap.php
@@ -1,7 +1,7 @@
pushHandler(new NullHandler());
-DriverBase::$logger = $log;
+$logger = new NullLogger();
+DriverBase::$logger = $logger;
diff --git a/test/unit/ExtendedGraphTest.php b/test/unit/ExtendedGraphTest.php
index dbba091c..9832f52f 100644
--- a/test/unit/ExtendedGraphTest.php
+++ b/test/unit/ExtendedGraphTest.php
@@ -29,6 +29,8 @@ public function testAddValidValueToLiteralResultsInTriple($value): void
public function addValidValueToLiteralResultsInTriple_Provider(): iterable
{
yield ['String'];
+ yield [''];
+ yield ['0'];
yield [1];
yield [1.2];
yield [true];
@@ -63,7 +65,7 @@ public function addInvalidValueToLiteralResultsInNoTriple_Provider(): iterable
*/
public function testAddInvalidSubjectToLiteralThrowsException($value): void
{
- $this->expectExceptionMessageMatches('/^(The subject is invalid|Argument 1.+must be of the type string.+)$/');
+ $this->expectExceptionMessageMatches('/^The subject is invalid$|Argument #?1.+must be of (the )?type string.+/');
$graph = new ExtendedGraph();
$graph->add_resource_triple($value, 'http://some/predicate', 'http://someplace.com');
@@ -72,6 +74,7 @@ public function testAddInvalidSubjectToLiteralThrowsException($value): void
public function addInvalidSubjectToLiteralResultsInNoTriple_Provider(): iterable
{
yield [''];
+ yield ['0'];
yield [1];
yield [1.2];
yield [true];
@@ -88,7 +91,7 @@ public function addInvalidSubjectToLiteralResultsInNoTriple_Provider(): iterable
*/
public function testAddInvalidPredicateToLiteralThrowsException($value): void
{
- $this->expectExceptionMessageMatches('/^(The predicate is invalid|Argument 2.+must be of the type string.+)$/');
+ $this->expectExceptionMessageMatches('/^The predicate is invalid$|Argument #?2.+must be of (the )?type string.+/');
$graph = new ExtendedGraph();
$graph->add_resource_triple('http://some/subject/1', $value, 'http://someplace.com');
@@ -97,6 +100,7 @@ public function testAddInvalidPredicateToLiteralThrowsException($value): void
public function addInvalidPredicateToLiteralResultsInNoTriple_Provider(): iterable
{
yield [''];
+ yield ['0'];
yield [1];
yield [1.2];
yield [true];
@@ -158,7 +162,7 @@ public function addInvalidValueToResourceResultsInNoTriple_Provider(): iterable
*/
public function testAddInvalidSubjectToResourceThrowsException($value): void
{
- $this->expectExceptionMessageMatches('/^(The subject is invalid|Argument 1.+must be of the type string.+)$/');
+ $this->expectExceptionMessageMatches('/^The subject is invalid$|Argument #?1.+must be of (the )?type string.+/');
$graph = new ExtendedGraph();
$graph->add_resource_triple($value, 'http://some/predicate', 'http://someplace.com');
@@ -167,6 +171,7 @@ public function testAddInvalidSubjectToResourceThrowsException($value): void
public function addInvalidSubjectToResourceResultsInNoTriple_Provider(): iterable
{
yield [''];
+ yield ['0'];
yield [1];
yield [1.2];
yield [true];
@@ -183,7 +188,7 @@ public function addInvalidSubjectToResourceResultsInNoTriple_Provider(): iterabl
*/
public function testAddInvalidPredicateToResourceThrowsException($value): void
{
- $this->expectExceptionMessageMatches('/^(The predicate is invalid|Argument 2.+must be of the type string.+)$/');
+ $this->expectExceptionMessageMatches('/^The predicate is invalid$|Argument #?2.+must be of (the )?type string.+/');
$graph = new ExtendedGraph();
$graph->add_resource_triple('http://some/subject/1', $value, 'http://someplace.com');
@@ -192,6 +197,7 @@ public function testAddInvalidPredicateToResourceThrowsException($value): void
public function addInvalidPredicateToResourceResultsInNoTriple_Provider(): iterable
{
yield [''];
+ yield ['0'];
yield [1];
yield [1.2];
yield [true];
diff --git a/test/unit/mongo/ApplyOperationTest.php b/test/unit/mongo/ApplyOperationTest.php
index 161082cc..6b225414 100644
--- a/test/unit/mongo/ApplyOperationTest.php
+++ b/test/unit/mongo/ApplyOperationTest.php
@@ -4,6 +4,7 @@
use MongoDB\BSON\ObjectId;
use MongoDB\BSON\UTCDateTime;
+use Resque\JobHandler;
use Tripod\Config;
use Tripod\Exceptions\JobException;
use Tripod\Mongo\Composites\SearchIndexer;
@@ -25,7 +26,7 @@ public function testMandatoryArgTripodConfig(): void
unset($this->args['tripodConfig']);
$job = new ApplyOperation();
$job->args = $this->args;
- $job->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $job->job = new JobHandler('queue', ['id' => uniqid()]);
$this->expectException(Exception::class);
$this->expectExceptionMessage('Argument tripodConfig or tripodConfigGenerator was not present in supplied job args for job Tripod\Mongo\Jobs\ApplyOperation');
$this->performJob($job);
@@ -37,7 +38,7 @@ public function testMandatoryArgSubject(): void
unset($this->args['subjects']);
$job = new ApplyOperation();
$job->args = $this->args;
- $job->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $job->job = new JobHandler('queue', ['id' => uniqid()]);
$this->expectException(Exception::class);
$this->expectExceptionMessage('Argument subjects was not present in supplied job args for job Tripod\Mongo\Jobs\ApplyOperation');
$this->performJob($job);
@@ -51,7 +52,7 @@ public function testApplyViewOperation(): void
->getMock();
$applyOperation->args = $this->args;
- $applyOperation->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $applyOperation->job = new JobHandler('queue', ['id' => uniqid()]);
$statMock = $this->getMockStat(
$this->args['statsConfig']['config']['host'],
@@ -129,7 +130,7 @@ public function testApplyViewOperationDecrementsJobGroupForBatchOperations(): vo
->getMock();
$applyOperation->args = $this->args;
- $applyOperation->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $applyOperation->job = new JobHandler('queue', ['id' => uniqid()]);
$jobTrackerId = new ObjectId();
$applyOperation->args[ApplyOperation::TRACKING_KEY] = $jobTrackerId->__toString();
@@ -231,7 +232,7 @@ public function testApplyViewOperationCleanupIfAllGroupJobsComplete(): void
->getMock();
$applyOperation->args = $this->args;
- $applyOperation->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $applyOperation->job = new JobHandler('queue', ['id' => uniqid()]);
$jobTrackerId = new ObjectId();
$applyOperation->args[ApplyOperation::TRACKING_KEY] = $jobTrackerId->__toString();
@@ -358,7 +359,7 @@ public function testApplyTableOperation(): void
$this->args['subjects'] = [$impactedSubject->toArray()];
$applyOperation->args = $this->args;
- $applyOperation->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $applyOperation->job = new JobHandler('queue', ['id' => uniqid()]);
$subject = $this->getMockBuilder(ImpactedSubject::class)
->onlyMethods(['getTripod'])
@@ -436,7 +437,7 @@ public function testApplyTableOperationDecrementsJobGroupForBatchOperations(): v
);
$applyOperation->args = $this->args;
- $applyOperation->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $applyOperation->job = new JobHandler('queue', ['id' => uniqid()]);
$jobTrackerId = new ObjectId();
$applyOperation->args[ApplyOperation::TRACKING_KEY] = $jobTrackerId->__toString();
@@ -539,7 +540,7 @@ public function testApplyTableOperationCleanupIfAllGroupJobsComplete(): void
);
$applyOperation->args = $this->args;
- $applyOperation->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $applyOperation->job = new JobHandler('queue', ['id' => uniqid()]);
$jobTrackerId = new ObjectId();
$applyOperation->args[ApplyOperation::TRACKING_KEY] = $jobTrackerId->__toString();
@@ -646,7 +647,7 @@ public function testApplySearchOperation(): void
);
$applyOperation->args = $this->args;
- $applyOperation->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $applyOperation->job = new JobHandler('queue', ['id' => uniqid()]);
$subject = $this->getMockBuilder(ImpactedSubject::class)
->onlyMethods(['getTripod'])
@@ -721,7 +722,7 @@ public function testApplySearchOperationDecrementsJobGroupForBatchOperations():
);
$applyOperation->args = $this->args;
- $applyOperation->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $applyOperation->job = new JobHandler('queue', ['id' => uniqid()]);
$jobTrackerId = new ObjectId();
$applyOperation->args[ApplyOperation::TRACKING_KEY] = $jobTrackerId->__toString();
@@ -817,7 +818,7 @@ public function testApplySearchOperationCleanupIfAllGroupJobsComplete(): void
);
$applyOperation->args = $this->args;
- $applyOperation->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $applyOperation->job = new JobHandler('queue', ['id' => uniqid()]);
$jobTrackerId = new ObjectId();
$applyOperation->args[ApplyOperation::TRACKING_KEY] = $jobTrackerId->__toString();
diff --git a/test/unit/mongo/ConfigGeneratorTest.php b/test/unit/mongo/ConfigGeneratorTest.php
index bd43f2a2..17e01f4e 100644
--- a/test/unit/mongo/ConfigGeneratorTest.php
+++ b/test/unit/mongo/ConfigGeneratorTest.php
@@ -2,11 +2,13 @@
declare(strict_types=1);
+use Resque\JobHandler;
use Tripod\Config;
use Tripod\ExtendedGraph;
use Tripod\ITripodConfigSerializer;
use Tripod\Mongo\Composites\Views;
use Tripod\Mongo\Driver;
+use Tripod\Mongo\DriverBase;
use Tripod\Mongo\ImpactedSubject;
use Tripod\Mongo\Jobs\ApplyOperation;
use Tripod\Mongo\Jobs\DiscoverImpactedSubjects;
@@ -46,6 +48,15 @@ public function testSerializeConfig(): void
$this->assertEquals($this->config, $instance->serialize());
}
+ public function testLoggerInstance(): void
+ {
+ $this->assertSame(
+ DriverBase::getLogger(),
+ Config::getInstance()::getLogger(),
+ 'Config instance should return the same logger instance as DriverBase'
+ );
+ }
+
public function testConfigGeneratorsSerializedInDiscoverJobs(): void
{
$originalGraph = new ExtendedGraph();
@@ -150,7 +161,7 @@ public function testSerializedConfigGeneratorsSentToApplyJobs(): void
->setMockClassName('ApplyOperation_TestConfigGenerator')
->getMock();
$discoverJob->args = $jobArgs;
- $discoverJob->job = new Resque_Job('discover_queue', ['id' => uniqid()]);
+ $discoverJob->job = new JobHandler('discover_queue', ['id' => uniqid()]);
$discoverJob->expects($this->once())->method('getTripod')->willReturn($tripod);
$discoverJob->expects($this->once())->method('getApplyOperation')->willReturn($applyJob);
$configInstance = Config::getInstance();
diff --git a/test/unit/mongo/DiscoverImpactedSubjectsTest.php b/test/unit/mongo/DiscoverImpactedSubjectsTest.php
index b7b1da2a..eb32265b 100644
--- a/test/unit/mongo/DiscoverImpactedSubjectsTest.php
+++ b/test/unit/mongo/DiscoverImpactedSubjectsTest.php
@@ -2,6 +2,7 @@
declare(strict_types=1);
+use Resque\JobHandler;
use Tripod\Config;
use Tripod\Mongo\Composites\SearchIndexer;
use Tripod\Mongo\Composites\Tables;
@@ -22,7 +23,7 @@ public function testMandatoryArgTripodConfig(): void
unset($this->args['tripodConfig']);
$job = new DiscoverImpactedSubjects();
$job->args = $this->args;
- $job->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $job->job = new JobHandler('queue', ['id' => uniqid()]);
$this->expectException(Exception::class);
$this->expectExceptionMessage('Argument tripodConfig or tripodConfigGenerator was not present in supplied job args for job Tripod\Mongo\Jobs\DiscoverImpactedSubjects');
$this->performJob($job);
@@ -34,7 +35,7 @@ public function testMandatoryArgStoreName(): void
unset($this->args['storeName']);
$job = new DiscoverImpactedSubjects();
$job->args = $this->args;
- $job->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $job->job = new JobHandler('queue', ['id' => uniqid()]);
$this->expectException(Exception::class);
$this->expectExceptionMessage('Argument storeName was not present in supplied job args for job Tripod\Mongo\Jobs\DiscoverImpactedSubjects');
$this->performJob($job);
@@ -46,7 +47,7 @@ public function testMandatoryArgPodName(): void
unset($this->args['podName']);
$job = new DiscoverImpactedSubjects();
$job->args = $this->args;
- $job->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $job->job = new JobHandler('queue', ['id' => uniqid()]);
$this->expectException(Exception::class);
$this->expectExceptionMessage('Argument podName was not present in supplied job args for job Tripod\Mongo\Jobs\DiscoverImpactedSubjects');
$this->performJob($job);
@@ -58,7 +59,7 @@ public function testMandatoryArgChanges(): void
unset($this->args['changes']);
$job = new DiscoverImpactedSubjects();
$job->args = $this->args;
- $job->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $job->job = new JobHandler('queue', ['id' => uniqid()]);
$this->expectException(Exception::class);
$this->expectExceptionMessage('Argument changes was not present in supplied job args for job Tripod\Mongo\Jobs\DiscoverImpactedSubjects');
$this->performJob($job);
@@ -70,7 +71,7 @@ public function testMandatoryArgOperations(): void
unset($this->args['operations']);
$job = new DiscoverImpactedSubjects();
$job->args = $this->args;
- $job->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $job->job = new JobHandler('queue', ['id' => uniqid()]);
$this->expectException(Exception::class);
$this->expectExceptionMessage('Argument operations was not present in supplied job args for job Tripod\Mongo\Jobs\DiscoverImpactedSubjects');
$this->performJob($job);
@@ -82,7 +83,7 @@ public function testMandatoryArgContextAlias(): void
unset($this->args['contextAlias']);
$job = new DiscoverImpactedSubjects();
$job->args = $this->args;
- $job->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $job->job = new JobHandler('queue', ['id' => uniqid()]);
$this->expectException(Exception::class);
$this->expectExceptionMessage('Argument contextAlias was not present in supplied job args for job Tripod\Mongo\Jobs\DiscoverImpactedSubjects');
$this->performJob($job);
@@ -148,12 +149,12 @@ public function testSubmitApplyOperationsJob(): void
->willReturn($tripod);
$discoverImpactedSubjects->args = $this->args;
- $discoverImpactedSubjects->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $discoverImpactedSubjects->job = new JobHandler('queue', ['id' => uniqid()]);
$applyOperation = $this->getMockBuilder(ApplyOperation::class)
->onlyMethods(['createJob'])
->getMock();
- $applyOperation->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $applyOperation->job = new JobHandler('queue', ['id' => uniqid()]);
$viewSubject = new ImpactedSubject(
[
@@ -352,7 +353,7 @@ public function testManualQueueNamePersistsThroughJob(): void
$args = $this->args;
$args['queue'] = 'TRIPOD_TESTING_QUEUE_' . uniqid();
$discoverImpactedSubjects->args = $args;
- $discoverImpactedSubjects->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $discoverImpactedSubjects->job = new JobHandler('queue', ['id' => uniqid()]);
$tripod->expects($this->exactly(3))
->method('getComposite')
@@ -517,7 +518,7 @@ public function testDiscoverOperationWillSubmitApplyOperationForDistinctQueues()
$args = $this->args;
$args['operations'] = [OP_TABLES];
$discoverImpactedSubjects->args = $args;
- $discoverImpactedSubjects->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $discoverImpactedSubjects->job = new JobHandler('queue', ['id' => uniqid()]);
$tripod = $this->getMockBuilder(Driver::class)
->onlyMethods(['getComposite'])
@@ -749,7 +750,7 @@ public function testManuallySpecifiedQueueWillOverrideQueuesDefinedInConfig(): v
$args['operations'] = [OP_TABLES];
$args['queue'] = 'TRIPOD_TESTING_QUEUE_' . uniqid();
$discoverImpactedSubjects->args = $args;
- $discoverImpactedSubjects->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $discoverImpactedSubjects->job = new JobHandler('queue', ['id' => uniqid()]);
$tripod = $this->getMockBuilder(Driver::class)
->onlyMethods(['getComposite'])
diff --git a/test/unit/mongo/EnsureIndexesTest.php b/test/unit/mongo/EnsureIndexesTest.php
index 015dd1e5..31e7892a 100644
--- a/test/unit/mongo/EnsureIndexesTest.php
+++ b/test/unit/mongo/EnsureIndexesTest.php
@@ -3,6 +3,7 @@
declare(strict_types=1);
use PHPUnit\Framework\MockObject\MockObject;
+use Resque\JobHandler;
use Tripod\Config;
use Tripod\Exceptions\JobException;
use Tripod\Mongo\IndexUtils;
@@ -40,7 +41,7 @@ public function testMandatoryArgs(string $argument, ?string $argumentName = null
$job = new EnsureIndexes();
$job->args = $this->args;
- $job->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $job->job = new JobHandler('queue', ['id' => uniqid()]);
unset($job->args[$argument]);
$this->expectException(Exception::class);
@@ -217,7 +218,7 @@ private function createMockJob(array $methods = ['getIndexUtils', 'submitJob', '
->onlyMethods($methods)
->setMockClassName('MockEnsureIndexes')
->getMock();
- $mockEnsureIndexesJob->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $mockEnsureIndexesJob->job = new JobHandler('queue', ['id' => uniqid()]);
return $mockEnsureIndexesJob;
}
diff --git a/test/unit/mongo/JobBaseTest.php b/test/unit/mongo/JobBaseTest.php
index 0203be85..f07a0a69 100644
--- a/test/unit/mongo/JobBaseTest.php
+++ b/test/unit/mongo/JobBaseTest.php
@@ -2,16 +2,27 @@
declare(strict_types=1);
+use Resque\JobHandler;
use Tripod\Config;
+use Tripod\Mongo\DriverBase;
use Tripod\Mongo\IConfigInstance;
class JobBaseTest extends MongoTripodTestBase
{
+ public function testLoggerInstance(): void
+ {
+ $this->assertSame(
+ DriverBase::getLogger(),
+ TestJobBase::getLogger(),
+ 'JobBase should return the same logger instance as DriverBase'
+ );
+ }
+
public function testGetTripodConfig(): void
{
$job = new TestJobBase();
$job->args = $this->getArgs();
- $job->job = new Resque_Job('queue', ['id' => uniqid()]);
+ $job->job = new JobHandler('queue', ['id' => uniqid()]);
$this->assertInstanceOf(IConfigInstance::class, $job->getTripodConfig());
}
diff --git a/test/unit/mongo/MongoGraphTest.php b/test/unit/mongo/MongoGraphTest.php
index 16921b4a..2b0e9187 100644
--- a/test/unit/mongo/MongoGraphTest.php
+++ b/test/unit/mongo/MongoGraphTest.php
@@ -132,6 +132,8 @@ public function testAddTripodArrayContainingValidLiteralValues($value): void
public function addTripodArrayContainingValidLiteralValues_Provider(): iterable
{
yield ['A String'];
+ yield [''];
+ yield ['0'];
yield [1];
yield [1.2];
yield [true];
@@ -200,8 +202,9 @@ public function testAddTripodArrayContainingInvalidPredicates($value): void
public function addTripodArrayContainingInvalidPredicates_Provider(): iterable
{
+ yield [''];
+ yield ['0'];
yield [1];
- yield [1.2];
yield [true];
}
@@ -255,6 +258,7 @@ public function testAddTripodArrayContainingInvalidSubject($value): void
public function addTripodArrayContainingInvalidSubject_Provider(): iterable
{
yield [''];
+ yield ['0'];
yield [1];
yield [1.2];
yield [true];
@@ -318,6 +322,8 @@ public function addTripodArrayContainingInvalidResourceValues_Provider(): iterab
{
yield [1];
yield [1.2];
+ yield [''];
+ yield ['0'];
yield [true];
yield [[]];
yield [null];
diff --git a/test/unit/mongo/MongoSearchProviderTest.php b/test/unit/mongo/MongoSearchProviderTest.php
index 40192cf8..ebe4b8b0 100644
--- a/test/unit/mongo/MongoSearchProviderTest.php
+++ b/test/unit/mongo/MongoSearchProviderTest.php
@@ -372,7 +372,9 @@ public function testSearchIndexingIsRetriedOnDuplicateKeyError(): void
$searchProviderReflection = new ReflectionClass(MongoSearchProvider::class);
$searchProviderConfigProperty = $searchProviderReflection->getProperty('config');
- $searchProviderConfigProperty->setAccessible(true);
+ if (PHP_VERSION_ID < 80100) {
+ $searchProviderConfigProperty->setAccessible(true);
+ }
$searchProviderConfigProperty->setValue($this->mongoSearchProvider, $configInstance);
$this->mongoSearchProvider->indexDocument([
diff --git a/test/unit/mongo/MongoTransactionLogTest.php b/test/unit/mongo/MongoTransactionLogTest.php
index 7e63d255..88c5f1be 100644
--- a/test/unit/mongo/MongoTransactionLogTest.php
+++ b/test/unit/mongo/MongoTransactionLogTest.php
@@ -626,7 +626,7 @@ public function testTransactionIsLoggedCorrectlyWhenSaveFails(): void
ksort($expectedCBD);
$this->assertEquals($expectedCBD, $actualCBD, 'CBD in transaction should match our expected value exactly');
// finally check that the actual error was logged in the transaction_log
- $this->assertTrue(isset($transactionDocument['error'], $transactionDocument['error']['reason']) && isset($transactionDocument['error']['trace']), 'The error should be logged, both the message and a stack trace');
+ $this->assertTrue(isset($transactionDocument['error']['reason'], $transactionDocument['error']['trace']), 'The error should be logged, both the message and a stack trace');
$this->assertEquals('exception thrown by mock test', $transactionDocument['error']['reason'], 'The transaction log should have logged the exception our test suite threw');
$this->assertNotEmpty($transactionDocument['error']['trace'], 'The transaction log have a non empty error trace');
}
diff --git a/test/unit/mongo/MongoTripodConfigUnitTest.php b/test/unit/mongo/MongoTripodConfigUnitTest.php
index b7813a43..f2759454 100644
--- a/test/unit/mongo/MongoTripodConfigUnitTest.php
+++ b/test/unit/mongo/MongoTripodConfigUnitTest.php
@@ -1010,8 +1010,8 @@ public function testCollectionReadPreferencesAreAppliedToDatabase(): void
$mockConfig->expects($this->exactly(2))
->method('getDatabase')
->withConsecutive(
- ['tripod_php_testing', 'rs1', ReadPreference::RP_SECONDARY_PREFERRED],
- ['tripod_php_testing', 'rs1', ReadPreference::RP_NEAREST]
+ ['tripod_php_testing', 'rs1', ReadPreference::SECONDARY_PREFERRED],
+ ['tripod_php_testing', 'rs1', ReadPreference::NEAREST]
)
->willReturnCallback(function () {
$mongo = new Client();
@@ -1019,8 +1019,8 @@ public function testCollectionReadPreferencesAreAppliedToDatabase(): void
return $mongo->selectDatabase('tripod_php_testing');
});
- $mockConfig->getCollectionForCBD('tripod_php_testing', 'CBD_testing', ReadPreference::RP_SECONDARY_PREFERRED);
- $mockConfig->getCollectionForCBD('tripod_php_testing', 'CBD_testing', ReadPreference::RP_NEAREST);
+ $mockConfig->getCollectionForCBD('tripod_php_testing', 'CBD_testing', ReadPreference::SECONDARY_PREFERRED);
+ $mockConfig->getCollectionForCBD('tripod_php_testing', 'CBD_testing', ReadPreference::NEAREST);
}
public function testDataLoadedInConfiguredDataSource(): void
@@ -1689,9 +1689,9 @@ public function testMongoConnectionNoExceptions(): void
->method('getMongoClient')
->with('mongodb://mongodb:27017/', ['connectTimeoutMS' => 20000])
->willReturnCallback(fn (): Client => new Client());
- $mockConfig->getDatabase('tripod_php_testing', 'rs1', ReadPreference::RP_SECONDARY_PREFERRED);
- $mockConfig->getCollectionForCBD('tripod_php_testing', 'CBD_testing', ReadPreference::RP_SECONDARY_PREFERRED);
- $mockConfig->getCollectionForCBD('tripod_php_testing', 'CBD_testing', ReadPreference::RP_NEAREST);
+ $mockConfig->getDatabase('tripod_php_testing', 'rs1', ReadPreference::SECONDARY_PREFERRED);
+ $mockConfig->getCollectionForCBD('tripod_php_testing', 'CBD_testing', ReadPreference::SECONDARY_PREFERRED);
+ $mockConfig->getCollectionForCBD('tripod_php_testing', 'CBD_testing', ReadPreference::NEAREST);
}
public function testMongoConnectionExceptionThrown(): void
@@ -1707,7 +1707,7 @@ public function testMongoConnectionExceptionThrown(): void
->with('mongodb://mongodb:27017/', ['connectTimeoutMS' => 20000])
->willThrowException(new ConnectionTimeoutException('Exception thrown when connecting to Mongo'));
- $mockConfig->getDatabase('tripod_php_testing', 'rs1', ReadPreference::RP_SECONDARY_PREFERRED);
+ $mockConfig->getDatabase('tripod_php_testing', 'rs1', ReadPreference::SECONDARY_PREFERRED);
}
public function testMongoConnectionNoExceptionThrownWhenConnectionThrowsSomeExceptions(): void
@@ -1728,8 +1728,8 @@ public function testMongoConnectionNoExceptionThrownWhenConnectionThrowsSomeExce
)
);
- $mockConfig->getDatabase('tripod_php_testing', 'rs1', ReadPreference::RP_SECONDARY_PREFERRED);
- $mockConfig->getCollectionForCBD('tripod_php_testing', 'CBD_testing', ReadPreference::RP_SECONDARY_PREFERRED);
- $mockConfig->getCollectionForCBD('tripod_php_testing', 'CBD_testing', ReadPreference::RP_NEAREST);
+ $mockConfig->getDatabase('tripod_php_testing', 'rs1', ReadPreference::SECONDARY_PREFERRED);
+ $mockConfig->getCollectionForCBD('tripod_php_testing', 'CBD_testing', ReadPreference::SECONDARY_PREFERRED);
+ $mockConfig->getCollectionForCBD('tripod_php_testing', 'CBD_testing', ReadPreference::NEAREST);
}
}
diff --git a/test/unit/mongo/MongoTripodDriverTest.php b/test/unit/mongo/MongoTripodDriverTest.php
index c141be4f..f0a02599 100755
--- a/test/unit/mongo/MongoTripodDriverTest.php
+++ b/test/unit/mongo/MongoTripodDriverTest.php
@@ -685,7 +685,7 @@ public function testReadPreferencesOverMultipleSaves(): void
->setConstructorArgs([
'CBD_testing',
'tripod_php_testing',
- ['defaultContext' => 'http://talisaspire.com/', 'readPreference' => ReadPreference::RP_SECONDARY_PREFERRED],
+ ['defaultContext' => 'http://talisaspire.com/', 'readPreference' => ReadPreference::SECONDARY_PREFERRED],
])
->getMock();
@@ -704,7 +704,7 @@ public function testReadPreferencesOverMultipleSaves(): void
->willReturn($tripodUpdate);
$expectedCollectionReadPreference = $tripodMock->getCollectionReadPreference();
- $this->assertEquals(ReadPreference::RP_SECONDARY_PREFERRED, $expectedCollectionReadPreference->getMode());
+ $this->assertEquals(ReadPreference::SECONDARY_PREFERRED, $expectedCollectionReadPreference->getModeString());
// Assert that a simple save results in read preferences being restored
$g = new MongoGraph();
diff --git a/test/unit/mongo/MongoTripodSearchIndexerTest.php b/test/unit/mongo/MongoTripodSearchIndexerTest.php
index c8e444c5..da5f74de 100644
--- a/test/unit/mongo/MongoTripodSearchIndexerTest.php
+++ b/test/unit/mongo/MongoTripodSearchIndexerTest.php
@@ -14,6 +14,7 @@
use Tripod\Mongo\MongoGraph;
use Tripod\Mongo\MongoSearchProvider;
use Tripod\Mongo\Updates;
+use Tripod\Test\Mongo\Mocks\Cursor as FakeCursor;
class MongoTripodSearchIndexerTest extends MongoTripodTestBase
{
@@ -508,7 +509,7 @@ public function testBatchSearchDocumentsGeneration(): void
$docs[] = ['_id' => ['r' => 'tenantLists:batch' . $i, 'c' => 'tenantContexts:DefaultGraph']];
}
- $fakeCursor = new ArrayIterator($docs);
+ $fakeCursor = new FakeCursor($docs);
$configInstance = $this->getMockBuilder(TripodTestConfig::class)
->onlyMethods(['getCollectionForCBD'])
->disableOriginalConstructor()
diff --git a/test/unit/mongo/MongoTripodTablesTest.php b/test/unit/mongo/MongoTripodTablesTest.php
index 3e4ffea5..b00b71d6 100644
--- a/test/unit/mongo/MongoTripodTablesTest.php
+++ b/test/unit/mongo/MongoTripodTablesTest.php
@@ -21,6 +21,7 @@
use Tripod\Mongo\MongoGraph;
use Tripod\Mongo\TransactionLog;
use Tripod\Mongo\Updates;
+use Tripod\Test\Mongo\Mocks\Cursor as FakeCursor;
class MongoTripodTablesTest extends MongoTripodTestBase
{
@@ -338,7 +339,7 @@ public function testBatchTableRowGeneration(): void
$docs[] = ['_id' => ['r' => 'tenantLists:batch' . $i, 'c' => 'tenantContexts:DefaultGraph']];
}
- $fakeCursor = new ArrayIterator($docs);
+ $fakeCursor = new FakeCursor($docs);
$configInstance = $this->getMockBuilder(TripodTestConfig::class)
->onlyMethods(['getCollectionForTable', 'getCollectionForCBD'])
->disableOriginalConstructor()
diff --git a/test/unit/mongo/MongoTripodViewsTest.php b/test/unit/mongo/MongoTripodViewsTest.php
index 12b914f9..0d2f3443 100644
--- a/test/unit/mongo/MongoTripodViewsTest.php
+++ b/test/unit/mongo/MongoTripodViewsTest.php
@@ -19,6 +19,7 @@
use Tripod\Mongo\MongoGraph;
use Tripod\Mongo\TransactionLog;
use Tripod\Mongo\Updates;
+use Tripod\Test\Mongo\Mocks\Cursor as FakeCursor;
class MongoTripodViewsTest extends MongoTripodTestBase
{
@@ -1956,7 +1957,8 @@ public function testCursorNoExceptions(): void
->setConstructorArgs([new Manager(), 'db', 'view'])
->onlyMethods(['find'])
->getMock();
- $mockCursor = $this->getMockBuilder(ArrayIterator::class)
+ $mockCursor = $this->getMockBuilder(FakeCursor::class)
+ ->setConstructorArgs([[]])
->onlyMethods(['rewind'])
->getMock();
@@ -2015,7 +2017,8 @@ public function testCursorExceptionThrown(): void
->setConstructorArgs([new Manager(), 'db', 'view'])
->onlyMethods(['findOne', 'find'])
->getMock();
- $mockCursor = $this->getMockBuilder(ArrayIterator::class)
+ $mockCursor = $this->getMockBuilder(FakeCursor::class)
+ ->setConstructorArgs([[]])
->onlyMethods(['rewind'])
->getMock();
@@ -2075,7 +2078,8 @@ public function testCursorNoExceptionThrownWhenCursorThrowsSomeExceptions(): voi
->setConstructorArgs([new Manager(), 'db', 'view'])
->onlyMethods(['find', 'findOne'])
->getMock();
- $mockCursor = $this->getMockBuilder(ArrayIterator::class)
+ $mockCursor = $this->getMockBuilder(FakeCursor::class)
+ ->setConstructorArgs([[]])
->onlyMethods(['rewind'])
->getMock();
@@ -2320,7 +2324,7 @@ public function testBatchViewGeneration(): void
$docs[] = ['_id' => ['r' => 'tenantLists:batch' . $i, 'c' => 'tenantContexts:DefaultGraph']];
}
- $fakeCursor = new ArrayIterator($docs);
+ $fakeCursor = new FakeCursor($docs);
$configInstance = $this->getMockBuilder(TripodTestConfig::class)
->onlyMethods(['getCollectionForView', 'getCollectionForCBD'])
->disableOriginalConstructor()
diff --git a/test/unit/mongo/ResqueJobTestBase.php b/test/unit/mongo/ResqueJobTestBase.php
index 3d527305..045fe807 100644
--- a/test/unit/mongo/ResqueJobTestBase.php
+++ b/test/unit/mongo/ResqueJobTestBase.php
@@ -2,15 +2,19 @@
declare(strict_types=1);
+use Resque\JobHandler;
use Tripod\Mongo\Jobs\JobBase;
class ResqueJobTestBase extends MongoTripodTestBase
{
protected function performJob(JobBase $job): void
{
- $mockJob = $this->getMockBuilder(Resque_Job::class)
+ $mockJob = $this->getMockBuilder(JobHandler::class)
->onlyMethods(['getInstance', 'getArguments'])
- ->setConstructorArgs(['test', get_class($job), $job->args])
+ ->setConstructorArgs(['test', [
+ 'class' => get_class($job),
+ 'args' => [$job->args],
+ ]])
->getMock();
$mockJob->expects($this->atLeastOnce())
->method('getInstance')
diff --git a/test/unit/mongo/mocks/Cursor.php b/test/unit/mongo/mocks/Cursor.php
new file mode 100644
index 00000000..c933ccd3
--- /dev/null
+++ b/test/unit/mongo/mocks/Cursor.php
@@ -0,0 +1,11 @@
+= 80000) {
+ require_once __DIR__ . '/CursorPhp80.php';
+ class Cursor extends CursorPhp80 {}
+} else {
+ require_once __DIR__ . '/CursorPhp74.php';
+ class Cursor extends CursorPhp74 {}
+}
diff --git a/test/unit/mongo/mocks/CursorPhp74.php b/test/unit/mongo/mocks/CursorPhp74.php
new file mode 100644
index 00000000..53191b74
--- /dev/null
+++ b/test/unit/mongo/mocks/CursorPhp74.php
@@ -0,0 +1,5 @@
+array = $array;
+ }
+
+ #[\ReturnTypeWillChange] // in ext-mongodb <1.20.0 returns MongoDB\Driver\CursorId
+ public function getId(): Int64
+ {
+ return new Int64(0);
+ }
+
+ public function getServer(): Server
+ {
+ return (new Manager())->getServers()[0];
+ }
+
+ public function isDead(): bool
+ {
+ return false;
+ }
+
+ public function setTypeMap(array $typemap): void
+ {
+ // noop
+ }
+
+ public function toArray(): array
+ {
+ return $this->array;
+ }
+
+ public function key(): ?int
+ {
+ return parent::key();
+ }
+
+ public function current(): array|object|null
+ {
+ return parent::current();
+ }
+}