- Issue created by @tedbow
- @tedbow opened merge request.
- Issue was unassigned.
- Status changed to Needs review
over 1 year ago 1:57pm 23 February 2023 - πΊπΈUnited States tedbow Ithaca, NY, USA
Results
Basically I set up a 2 tests that do the same thing in a loop- Add a package
- Get the installed packages
- Remove the package
AddPackageBenchMarkTest
does with the fixture manipulator plus$composerUtility->getInstalledPackages();
which uses composer php api
ComposerRequireBenchMarkTest
does with the composer command plus$this->container->get('package_manager.composer_inspector')->getInstalledPackagesList($active_dir);
which usescomposer show
-
Commit where loop runs 5x and test runs 50x
AddPackageBenchMarkTest
Test run duration: 2 sec
ComposerRequireBenchMarkTest
Test run duration: 4 sec -
Commit where loop runs 2x and test runs 20x
AddPackageBenchMarkTest
Test run duration: 5 sec
ComposerRequireBenchMarkTest
Test run duration: 18 sec
I think this shows our kernel test might run 3x as long or more.
In π Update FixtureManipulator to work with InstalledPackagesList, real composer show command Fixed I showed that we can just update our
FixtureManipulator
class to work with a realcomposer show
and therefore work with$this->container->get('package_manager.composer_inspector')->getInstalledPackagesList($active_dir);
I think means for the means we should keep using the
FixtureManipulator
subclasses. The API we created in those classes I think later could be changed internally to actually do composer installs later if we want to.(new FixtureManipulator()) ->addPackage( [ 'name' => 'drupal/package_project_match', 'type' => 'drupal-module', 'install_path' => "$relative_projects_dir/package_project_match", ] )->commitChanges($fixture);
Doesn't actually tell you how it will be done.
We could even use a flag to use different implementation in some test or test runs if we someday are able to run a subset or all of our tests in test matrix with different versions of Composer
- Assigned to tedbow
- Status changed to Needs work
over 1 year ago 2:40pm 23 February 2023 - π§πͺBelgium wim leers Ghent π§πͺπͺπΊ
(I think you've flipped the links around? π )
I think this shows our kernel test might run 3x as long or more.
Can we really conclude that from this?
Running 50 kernel tests (which is more than we have today, but ballpark similar for sure π) with each of them doing 5
composer require
calls (which is ballpark accurate too I think π).But we're forgetting:
- that a single
composer require
can install multiple packages, so e.g. the 6FixtureManipulator::addPackage()
calls inOverwriteExistingPackagesValidatorTest
(representing >10% of all such calls!) would be replaced by a single call! Same thing for the 6 calls inStagedProjectsValidatorTest::testProjectsRemoved()
. - that
addPackage()
today is incorrect (that's why we have π Update FixtureManipulator to work with InstalledPackagesList, real composer show command Fixed , to fix that), and that fixing it requires performing more I/O, which should decrease the difference.
So I'd like to see at least one more test: a test in which we still execute 50 kernel tests, but call
composer require
only 1 time in each β that should show how NaddPackage()
calls per test compare to a singlecomposer require
per test. So that'd answer that first point I made π€ - that a single
- Issue was unassigned.
- πΊπΈUnited States tedbow Ithaca, NY, USA
While it is good to test this out because we might want to use more real composer calls in our test at sometime I am less convinced we need to do that now because
- π Update FixtureManipulator to work with InstalledPackagesList, real composer show command Fixed seems to be easier than I thought
- π Run `composer validate` after FixtureManipulator commits its changes Fixed will mean that we can be more confident that our manipulation is more realistic and will ensure it stays so
- The test API in FixtureManipulator with methods addPackage, modifyPackage, removePackage could easily be updated later to actually perform real composer calls internally if we need to. So I think if we keep using
FixtureManipulator
we are not tied to just manipulating the composer files manually forever. The tests the useFixtureManipulator
would hopefully have to change very little if we change the internalsFor a test that uses this really doesn't care how that package gets added it just needs the validator to be able to determine that it is installed.
(new ActiveFixtureManipulator()) ->addPackage([ 'name' => "drupal/dependency", 'version' => '9.8.0', 'type' => 'drupal-library', ]) ->commitChanges();
Currently we do this by changing files but we could change it use composer commands or even mock
InstalledPackageList
objects that return back the packages we set up.
For these reasons I bumping this back to normal priority
-
Running 50 kernel tests (which is more than we have today, but ballpark similar for sure π) with each of them doing 5 composer require calls (which is ballpark accurate too I think π).
This probably very low estimate. This test has 1 method. We have 181 test method in our kernel tests. Many of these have data providers so they would called multiple times
UPDATE: Just checked when all kernel test locally for package manager it is 307 , which I think includes data providers. -
that addPackage() today is incorrect (that's why we have π Update FixtureManipulator to work with InstalledPackagesList, real composer show command Fixed , to fix that), and that fixing it requires performing more I/O, which should decrease the difference.
I think most of the new IO is done in that issue I pretty sure it will add very little time.
checked the latest test run in #3343827 vs 3.0.x#3343827 appeared to take 2 minutes longer
but looking at the executions
Kernel tests
#3343827 2 min 22 sec
3.0.x 2 min 18 secFunction tests
#3343827 2 min 7 sec
3.0.x 2 min 4 secOther test don't use the manipulators
So about 30 seconds of the total 2 minutes difference could possibly be because of manipulators
but also #3343827 does change 1 Validators to use the newInstalledPackagesList
which is going to make composer process calls instead of using doing Composer PHP API calls. That process is slower and that updated validator `automatic_updates.staged_projects_validator` is only disabled in 1 test so in every other PreApplyEvent, which it subscribes to, in every other test these newcomposer show
command will be run.So it likely the manipular changes affect the performance very little and much of the 30 seconds difference is just the new composer calls.
Just uploaded a patch to test this out https://www.drupal.org/project/automatic_updates/issues/3343827#comment-... π Update FixtureManipulator to work with InstalledPackagesList, real composer show command FixedAlso test I have just run all package manager kernel tests locally
3.0.x - 7:42
#3343827-without validator change - 7:02π€
So this problem just means something else is going with my composer, if was faster with the manipulation change -
that a single composer require can install multiple packages, so e.g. the 6 FixtureManipulator::addPackage() calls in OverwriteExistingPackagesValidatorTest (representing >10% of all such calls!) would be replaced by a single call! Same thing for the 6 calls in StagedProjectsValidatorTest::testProjectsRemoved().
so that made me realize to figure how composer call we could have it is better to track the calls to \Drupal\fixture_manipulator\FixtureManipulator::doCommitChanges to count 1 potential composer call for each group of calls to addPackage, modifyPackage, and removePackage
will push up a start to this
- πΊπΈUnited States tedbow Ithaca, NY, USA
create branch to 3343768-count-possible-composer-calls to show how could determine about how many real composer calls we would have to make if we wanted to switch to that.
FWIW with just Package Manager kernels testa locally this found 103
- π§πͺBelgium wim leers Ghent π§πͺπͺπΊ
#6:
- Wonderful! π
- Agreed on the importance of π Run `composer validate` after FixtureManipulator commits its changes Fixed β thank you for creating that issue! π
- Agreed that together with the previous point, we have a path forward for the future; we haven't locked ourselves in. π
RE #6's feedback on #5:
-
This probably very low estimate. This test has 1 method. We have 181 test method in our kernel tests.
β¦ but each of those require a setup, and that has overhead too.
- π Those numbers look very convincing! 4 seconds difference for kernel tests on a total of ~140 seconds is basically "noise", not a measurable difference.
π€ But what 2 minute difference are you talking about? DrupalCI run times themselves easily have a variance of multiple minutes! Grep the output forStarting environment
, and you'll see that there's a 1-minute difference just because one env did not need to dodocker pull
and the other did! You showed that the performance difference for Kernel & Functional tests was effectively non-existent β and the same is true for Unit & Build tests. So the only possible conclusion I see: no performance difference.
#7: doesn't that mean that only ~103 times ~1 second would make tests only ~1 minute 40 seconds slower? π€
- πΊπΈUnited States phenaproxima Massachusetts
Do we still need this issue?
FixtureManipulator is now using nearly(?) entirely real Composer commands. As far as I know, this is moot and we did it.
- Assigned to tedbow
- Status changed to RTBC
over 1 year ago 11:53am 11 March 2023 - π§πͺBelgium wim leers Ghent π§πͺπͺπΊ
I was thinking the same.
I'd like @tedbow to take a final look at this before closing it.
- Status changed to Fixed
over 1 year ago 2:56pm 14 March 2023 - πΊπΈUnited States tedbow Ithaca, NY, USA
I think it is a performance hit but trying to update the composer metadata files directly was getting too complicated. If we need to make our test suite to be faster for core inclusion I think we should look elsewhere for improvements. for instance π Optimize Composer calls in FixtureManipulator Closed: works as designed
If we need to find any more improvement tests like
\Drupal\Tests\package_manager\Kernel\ComposerPatchesValidatorTest::testErrorDuringPreCreate
instead of using a data provider could just have a loop resets the active directory to starting state at the start of each iteration and then runs all the different scenariosI am not saying we should change
testErrorDuringPreCreate
I prefer to use the data provider. Just citing a quick example of a change we could make if we get push back on the test duration. While a change like that totestErrorDuringPreCreate
would not be ideal it would much better than going back to editing composer metadata file directly. - Issue was unassigned.
- π§πͺBelgium wim leers Ghent π§πͺπͺπΊ
I think it is a performance hit but trying to update the composer metadata files directly was getting too complicated.
π―
I'm glad and relieved that @phenaproxima, @tedbow and I are all on the same page π
Automatically closed - issue fixed for 2 weeks with no activity.