Skip to content

Commit

Permalink
Run the full test suite with proxy manager
Browse files Browse the repository at this point in the history
  • Loading branch information
GromNaN committed Nov 23, 2024
1 parent 8742c51 commit a81c08c
Show file tree
Hide file tree
Showing 21 changed files with 109 additions and 56 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ jobs:
- "highest"
symfony-version:
- "stable"
proxy:
- "lazy-ghost"
include:
# Test against lowest dependencies
- dependencies: "lowest"
Expand All @@ -42,20 +44,30 @@ jobs:
driver-version: "1.17.0"
topology: "server"
symfony-version: "stable"
proxy: "lazy-ghost"
# Test with highest dependencies
- topology: "server"
php-version: "8.2"
mongodb-version: "7.0"
driver-version: "stable"
dependencies: "highest"
symfony-version: "7"
proxy: "lazy-ghost"
# Test with a 5.0 replica set
- topology: "replica_set"
php-version: "8.2"
mongodb-version: "5.0"
driver-version: "stable"
dependencies: "highest"
symfony-version: "stable"
proxy: "lazy-ghost"
# Test with ProxyManager
- php-version: "8.2"
mongodb-version: "5.0"
driver-version: "stable"
dependencies: "highest"
symfony-version: "stable"
proxy: "proxy-manager"
# Test with a 5.0 sharded cluster
# Currently disabled due to a bug where MongoDB reports "sharding status unknown"
# - topology: "sharded_cluster"
Expand All @@ -64,6 +76,7 @@ jobs:
# driver-version: "stable"
# dependencies: "highest"
# symfony-version: "stable"
# proxy: "lazy-ghost"

steps:
- name: "Checkout"
Expand Down Expand Up @@ -118,6 +131,13 @@ jobs:
# https://github.com/vimeo/psalm/pull/10928
composer remove --no-update --dev vimeo/psalm
- name: "Remove proxy-manager-lts"
if: "${{ matrix.proxy != 'proxy-manager' }}"
run: |
# proxy-manager-lts is not installed by default and must not be used
# unless explicitly requested
composer remove --no-update --dev friendsofphp/proxy-manager-lts
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v3"
with:
Expand All @@ -134,3 +154,4 @@ jobs:
run: "vendor/bin/phpunit"
env:
DOCTRINE_MONGODB_SERVER: ${{ steps.setup-mongodb.outputs.cluster-uri }}
USE_LAZY_GHOST_OBJECTS: ${{ matrix.proxy == 'lazy-ghost' && '1' || '0' }}"
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@
"doctrine/event-manager": "^1.0 || ^2.0",
"doctrine/instantiator": "^1.1 || ^2",
"doctrine/persistence": "^3.2",
"friendsofphp/proxy-manager-lts": "^1.0",
"jean85/pretty-package-versions": "^1.3.0 || ^2.0.1",
"mongodb/mongodb": "^1.17.0",
"psr/cache": "^1.0 || ^2.0 || ^3.0",
"symfony/console": "^5.4 || ^6.0 || ^7.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0",
"symfony/var-dumper": "^5.4 || ^6.0 || ^7.0",
"symfony/var-exporter": "^5.4 || ^6.0 || ^7.0"
"symfony/var-exporter": "^6.2 || ^7.0"
},
"require-dev": {
"ext-bcmath": "*",
"doctrine/annotations": "^1.12 || ^2.0",
"doctrine/coding-standard": "^12.0",
"doctrine/orm": "^3.2",
"friendsofphp/proxy-manager-lts": "^1.0",
"jmikola/geojson": "^1.0",
"phpbench/phpbench": "^1.0.0",
"phpstan/phpstan": "~1.10.67",
Expand Down
30 changes: 30 additions & 0 deletions lib/Doctrine/ODM/MongoDB/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
use Doctrine\Persistence\ObjectRepository;
use InvalidArgumentException;
use LogicException;
use MongoDB\Driver\WriteConcern;
use ProxyManager\Configuration as ProxyManagerConfiguration;
use ProxyManager\Factory\LazyLoadingGhostFactory;
Expand All @@ -33,6 +34,7 @@
use ReflectionClass;

use function array_key_exists;
use function class_exists;
use function interface_exists;
use function trigger_deprecation;
use function trim;
Expand Down Expand Up @@ -128,6 +130,8 @@ class Configuration

private bool $useTransactionalFlush = false;

private bool $useLazyGhostObject = true;

/**
* Adds a namespace under a certain alias.
*/
Expand Down Expand Up @@ -613,6 +617,32 @@ public function isTransactionalFlushEnabled(): bool
{
return $this->useTransactionalFlush;
}

/**
* Generate proxy classes using Symfony VarExporter's LazyGhostTrait if true.
* Otherwise, use ProxyManager's LazyLoadingGhostFactory (deprecated)
*/
public function setUseLazyGhostObject(bool $flag): void
{
if ($flag === false) {
if (! class_exists(ProxyManagerConfiguration::class)) {
throw new LogicException('Package "friendsofphp/proxy-manager-lts" is required to disable LazyGhostObject.');
}

trigger_deprecation(
'doctrine/mongodb-odm',
'2.6',
'Using "friendsofphp/proxy-manager-lts" is deprecated. Use "symfony/var-exporter" LazyGhostObjects instead.',
);
}

$this->useLazyGhostObject = $flag;
}

public function isLazyGhostObjectEnabled(): bool
{
return $this->useLazyGhostObject ?? true;
}
}

interface_exists(MappingDriver::class);
10 changes: 8 additions & 2 deletions lib/Doctrine/ODM/MongoDB/DocumentManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
use Doctrine\ODM\MongoDB\Mapping\MappingException;
use Doctrine\ODM\MongoDB\Proxy\Factory\LazyGhostProxyFactory;
use Doctrine\ODM\MongoDB\Proxy\Factory\ProxyFactory;
use Doctrine\ODM\MongoDB\Proxy\Factory\StaticProxyFactory;
use Doctrine\ODM\MongoDB\Proxy\Resolver\CachingClassNameResolver;
use Doctrine\ODM\MongoDB\Proxy\Resolver\ClassNameResolver;
use Doctrine\ODM\MongoDB\Proxy\Resolver\LazyGhostProxyClassNameResolver;
use Doctrine\ODM\MongoDB\Proxy\Resolver\ProxyManagerClassNameResolver;
use Doctrine\ODM\MongoDB\Query\FilterCollection;
use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
use Doctrine\ODM\MongoDB\Repository\GridFSRepository;
Expand Down Expand Up @@ -156,7 +158,9 @@ protected function __construct(?Client $client = null, ?Configuration $config =
],
);

$this->classNameResolver = new CachingClassNameResolver(new LazyGhostProxyClassNameResolver());
$this->classNameResolver = $config->isLazyGhostObjectEnabled()
? new CachingClassNameResolver(new LazyGhostProxyClassNameResolver())
: new CachingClassNameResolver(new ProxyManagerClassNameResolver($this->config));

$metadataFactoryClassName = $this->config->getClassMetadataFactoryName();
$this->metadataFactory = new $metadataFactoryClassName();
Expand All @@ -181,7 +185,9 @@ protected function __construct(?Client $client = null, ?Configuration $config =

$this->unitOfWork = new UnitOfWork($this, $this->eventManager, $this->hydratorFactory);
$this->schemaManager = new SchemaManager($this, $this->metadataFactory);
$this->proxyFactory = new LazyGhostProxyFactory($this, $config->getProxyDir(), $config->getProxyNamespace(), $config->getAutoGenerateProxyClasses());
$this->proxyFactory = $config->isLazyGhostObjectEnabled()
? new LazyGhostProxyFactory($this, $config->getProxyDir(), $config->getProxyNamespace(), $config->getAutoGenerateProxyClasses())
: new StaticProxyFactory($this);
$this->repositoryFactory = $this->config->getRepositoryFactory();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public function __serialize(): array
private readonly UnitOfWork $uow;

/** @var Configuration::AUTOGENERATE_* */
private $autoGenerate;
private int $autoGenerate;

/** @var array<class-string, Closure> */
private array $proxyFactories = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
/**
* This factory is used to create proxy objects for documents at runtime.
*
* @deprecated
* @deprecated since 2.10, use LazyGhostProxyFactory instead
*/
final class StaticProxyFactory implements ProxyFactory
{
Expand Down
1 change: 1 addition & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@
<ini name="error_reporting" value="-1"/>
<const name="DOCTRINE_MONGODB_SERVER" value="mongodb://localhost:27017" />
<const name="DOCTRINE_MONGODB_DATABASE" value="doctrine_odm_tests" />
<env name="USE_LAZY_GHOST_OBJECTS" value="1"/>
</php>
</phpunit>
14 changes: 10 additions & 4 deletions tests/Doctrine/ODM/MongoDB/Tests/BaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Doctrine\ODM\MongoDB\Tests;

use Composer\InstalledVersions;
use Doctrine\ODM\MongoDB\Configuration;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\Driver\AttributeDriver;
Expand Down Expand Up @@ -89,6 +90,7 @@ protected static function getConfiguration(): Configuration
$config->setPersistentCollectionNamespace('PersistentCollections');
$config->setDefaultDB(DOCTRINE_MONGODB_DATABASE);
$config->setMetadataDriverImpl(static::createMetadataDriverImpl());
$config->setUseLazyGhostObject((bool) $_ENV['USE_LAZY_GHOST_OBJECTS']);

$config->addFilter('testFilter', Filter::class);
$config->addFilter('testFilter2', Filter::class);
Expand Down Expand Up @@ -118,10 +120,14 @@ public static function assertArraySubset(array $subset, array $array, bool $chec

public static function assertIsLazyObject(object $document): void
{
self::logicalOr(
self::isInstanceOf(InternalProxy::class),
self::isInstanceOf(LazyLoadingInterface::class),
)->evaluate($document);
if (InstalledVersions::isInstalled('friendsofphp/proxy-manager')) {
self::logicalOr(
self::isInstanceOf(InternalProxy::class),
self::isInstanceOf(LazyLoadingInterface::class),
)->evaluate($document);
} else {
self::assertInstanceOf(InternalProxy::class, $document);
}
}

protected static function createMetadataDriverImpl(): MappingDriver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Doctrine\ODM\MongoDB\Tests\Functional;

use Doctrine\ODM\MongoDB\Proxy\InternalProxy;
use Doctrine\ODM\MongoDB\Tests\BaseTestCase;
use Documents\Event;
use Documents\User;
Expand All @@ -30,7 +29,7 @@ public function testGetIdentifierValue(): void

$userTest = $test->getUser();
self::assertEquals($user->getId(), $userTest->getId());
self::assertInstanceOf(InternalProxy::class, $userTest);
self::assertIsLazyObject($userTest);
self::assertTrue($this->uow->isUninitializedObject($userTest));

$this->dm->clear();
Expand All @@ -42,7 +41,7 @@ public function testGetIdentifierValue(): void
$foundUser = $test->getUser();
self::assertEquals($user->getId(), $class->getIdentifierValue($user));
self::assertEquals($user->getId(), $class->getFieldValue($foundUser, 'id'));
self::assertInstanceOf(InternalProxy::class, $foundUser);
self::assertIsLazyObject($foundUser);
self::assertTrue($this->uow->isUninitializedObject($foundUser));

self::assertEquals('jwage', $foundUser->getUsername());
Expand Down
20 changes: 10 additions & 10 deletions tests/Doctrine/ODM/MongoDB/Tests/Functional/ReferencePrimerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public function testPrimeReferencesWithDBRefObjects(): void
->field('groups')->prime(true);

foreach ($qb->getQuery() as $user) {
self::assertInstanceOf(InternalProxy::class, $user->getAccount());
self::assertIsLazyObject($user->getAccount());
self::assertFalse($this->uow->isUninitializedObject($user->getAccount()));

self::assertCount(2, $user->getGroups());
Expand Down Expand Up @@ -133,7 +133,7 @@ public function testPrimeReferencesWithSimpleReferences(): void
->field('users')->prime(true);

foreach ($qb->getQuery() as $simpleUser) {
self::assertInstanceOf(InternalProxy::class, $simpleUser->getUser());
self::assertIsLazyObject($simpleUser->getUser());
self::assertFalse($this->uow->isUninitializedObject($simpleUser->getUser()));

self::assertCount(2, $simpleUser->getUsers());
Expand Down Expand Up @@ -196,7 +196,7 @@ public function testPrimeReferencesNestedInNamedEmbeddedReference(): void
self::assertNotInstanceOf(InternalProxy::class, $embeddedDoc);
self::assertInstanceOf(EmbeddedWhichReferences::class, $embeddedDoc);

self::assertInstanceOf(InternalProxy::class, $embeddedDoc->referencedDoc);
self::assertIsLazyObject($embeddedDoc->referencedDoc);
self::assertFalse($this->uow->isUninitializedObject($embeddedDoc->referencedDoc));

self::assertCount(2, $embeddedDoc->referencedDocs);
Expand Down Expand Up @@ -252,7 +252,7 @@ public function testPrimeReferencesWithDifferentStoreAsReferences(): void
assert($referenceUser instanceof ReferenceUser);
$user = $referenceUser->getUser();
self::assertInstanceOf(User::class, $user);
self::assertInstanceOf(InternalProxy::class, $user);
self::assertIsLazyObject($user);
self::assertFalse($this->uow->isUninitializedObject($user));

self::assertCount(1, $referenceUser->getUsers());
Expand All @@ -263,7 +263,7 @@ public function testPrimeReferencesWithDifferentStoreAsReferences(): void
}

$parentUser = $referenceUser->getParentUser();
self::assertInstanceOf(InternalProxy::class, $parentUser);
self::assertIsLazyObject($parentUser);
self::assertInstanceOf(User::class, $parentUser);
self::assertFalse($this->uow->isUninitializedObject($parentUser));

Expand All @@ -276,7 +276,7 @@ public function testPrimeReferencesWithDifferentStoreAsReferences(): void

$otherUser = $referenceUser->getOtherUser();
self::assertInstanceOf(User::class, $otherUser);
self::assertInstanceOf(InternalProxy::class, $otherUser);
self::assertIsLazyObject($otherUser);
self::assertFalse($this->uow->isUninitializedObject($otherUser));

self::assertCount(1, $referenceUser->getOtherUsers());
Expand Down Expand Up @@ -331,7 +331,7 @@ public function testPrimeReferencesWithDiscriminatedReferenceOne(): void
->field('server')->prime(true);

foreach ($qb->getQuery() as $agent) {
self::assertInstanceOf(InternalProxy::class, $agent->server);
self::assertIsLazyObject($agent->server);
self::assertFalse($this->uow->isUninitializedObject($agent->server));
}
}
Expand Down Expand Up @@ -523,7 +523,7 @@ public function testPrimeEmbeddedReferenceTwoLevelsDeep(): void

$currency = $money->getCurrency();

self::assertInstanceOf(InternalProxy::class, $currency);
self::assertIsLazyObject($currency);
self::assertInstanceOf(Currency::class, $currency);
self::assertFalse($this->uow->isUninitializedObject($currency));
}
Expand Down Expand Up @@ -551,7 +551,7 @@ public function testPrimeReferencesInReferenceMany(): void
self::assertInstanceOf(BlogPost::class, $post);

$comment = $post->comments->first();
self::assertInstanceOf(InternalProxy::class, $comment->author);
self::assertIsLazyObject($comment->author);
self::assertFalse($this->uow->isUninitializedObject($comment->author));
}

Expand All @@ -578,7 +578,7 @@ public function testPrimeReferencesInReferenceManyWithRepositoryMethodEager(): v
self::assertInstanceOf(BlogPost::class, $post);

$comment = $post->repoCommentsWithPrimer->first();
self::assertInstanceOf(InternalProxy::class, $comment->author);
self::assertIsLazyObject($comment->author);
self::assertFalse($this->uow->isUninitializedObject($comment->author));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use Doctrine\ODM\MongoDB\PersistentCollection;
use Doctrine\ODM\MongoDB\PersistentCollection\PersistentCollectionInterface;
use Doctrine\ODM\MongoDB\Proxy\InternalProxy;
use Doctrine\ODM\MongoDB\Tests\BaseTestCase;
use Documents\Account;
use Documents\Address;
Expand Down Expand Up @@ -81,7 +80,7 @@ public function testLazyLoadReference(): void
assert($profile instanceof Profile);

self::assertInstanceOf(Profile::class, $profile);
self::assertInstanceOf(InternalProxy::class, $profile);
self::assertIsLazyObject($profile);

$profile->getFirstName();

Expand All @@ -103,7 +102,7 @@ public function testLazyLoadedWithNotifyPropertyChanged(): void

$user = $this->dm->find($user::class, $user->getId());
$profile = $user->getProfileNotify();
self::assertInstanceOf(InternalProxy::class, $profile);
self::assertIsLazyObject($profile);
self::assertTrue($this->uow->isUninitializedObject($profile));

$user->getProfileNotify()->setLastName('Malarz');
Expand Down
Loading

0 comments on commit a81c08c

Please sign in to comment.