The class PHPMaintClass is meant to be loaded when running phpunit.php
which is only done when running tests with it. When running tests by
using the bootstrap file only, e.g. in an IDE, this class will not be
available. Relying on it in other classes will therefore break them.
Moving the required parts to another outside class and add it to the
test autoloader. My feeling says, that adding the PHPMaintClass to the
autoloader says "NOOOO", that's why I added a new one.
There also seems to be some CI builds failing because of that:
https://integration.wikimedia.org/ci/hob/quibble-vendor-mysql-php72-docker/30642/console
Bug: T151101
Change-Id: I33e27009657a951173694fc847973560a1ce967b
This is moved out of the main PHPUnit upgrade commit to allow
extensions to silence their warnings beforehand, to avoid breaking
their tests.
Bug: T192167
Change-Id: I60379a933a3a1b018d9f5ef6b51019002389dda3
These were made final in PHPUnit8. Since there seems to be no easy way
to work around that, partially revert
Ibcaf9ca81c8dc63cce6dc6f6fb1fffee19f8804e and start using static
properties again (cfr. T192167#5550034).
Split from Ic14f5debc53e55d67146dc96279d26dfd52b4000.
Bug: T192167
Change-Id: I3fe163738662ae41eb275a0327cb33187290a70f
These are static methods that have to do with processing language names
and codes. I didn't include fallback behavior, because that would mean a
circular dependency with LocalisationCache.
In the new class, I renamed AS_AUTONYMS to AUTONYMS, and added a class
constant DEFINED for 'mw' to match the existing SUPPORTED and ALL. I
also renamed fetchLanguageName(s) to getLanguageName(s).
There is 100% test coverage for the code in the new class.
This was previously committed as 2e52f48c2e and reverted because it
depended on e4468a1d6b, which had to be reverted for performance
issues. There should be no changes other than rebasing.
Bug: T201405
Change-Id: Ifa346c8a92bf1eb57dc5e79458b32b7b26f1ee8a
This removes Language::$dataCache without deprecation, because 1) I
don't know of a way to properly simulate it in the new paradigm, and 2)
I found no direct access to the member outside of the Language and
LanguageTest classes.
An earlier version of this patch (e4468a1d6b) had to be reverted
because of a massive slowdown on test runs. Based on some local testing,
this should fix the problem. Running all tests in languages is slowed
down by only around 20% instead of a factor of five, and memory usage is
actually reduced greatly (~350 MB -> ~200 MB). The slowdown is still not
great, but I assume it's par for the course for converting things to
services and is acceptable. If not, I can try to optimize further.
Bug: T231220
Bug: T231198
Bug: T231200
Bug: T201405
Change-Id: Ieadbd820379a006d8ad2d2e4a1e96241e172ec5a
This code didn't work because the $GLOBALS array is exposed by reference.
Once this reference was broken by unset(), the rest just manipulated a
local array that happens to be called "GLOBALS". It must not be unset or
re-assigned. It can only be changed in-place.
Before this, the execution of a MediaWikiUnitTestCase test stored a
copy of GLOBALS in unitGlobals, then lost the GLOBALS pointer and
created a new variable called "GLOBALS". As such, the tearDown() function
didn't do what it meant to do, either – which then results in odd
failures like T230023
Rewrite it as follows:
* In setup, store the current GLOBALS keys and values, then reduce
GLOBALS to only the whitelisted keys and values.
* In teardown, restore the original state.
* As optimisation, do this from setUpBeforeClass as well, so that
there are relatively few globals to reset between tests.
(Thanks @Simetrical!)
The following tests were previously passing by accident under
MediaWikiUnitTestCase but actually did depend on global config.
* MainSlotRoleHandlerTest (…, ContentHandler, $wgContentHandlers)
* SlotRecordTest (…, ContentHandler, $wgContentHandlers)
* WikiReferenceTest (wfParseUrl, $wgUrlProtocols)
* DifferenceEngineSlotDiffRendererTest (DifferenceEngine, wfDebug, …)
* SlotDiffRendererTest (…, ContentHandler, $wgContentHandlers)
* FileBackendDBRepoWrapperTest (wfWikiID, "Backend domain ID not provided")
* JpegMetadataExtractorTest (…, wfDebug, …, LoggerFactory, …)
* ParserFactoryTest (…, wfDebug, …, LoggerFactory, InvalidArgumentException)
* MediaWikiPageNameNormalizerTest (…, wfDebug, …, LoggerFactory, …)
* SiteExporterTest (SiteImporter, wfLogWarning, …)
* SiteImporterTest (Site::newForType, $wgSiteTypes)
* ZipDirectoryReaderTest (…, wfDebug, …, LoggerFactory, …)
Bug: T230023
Change-Id: Ic22075bb5e81b7c2c4c1b8647547aa55306a10a7
100% coverage except for one bit of the code that I didn't understand.
Unit tests to come, together with rewrite as a service.
Change-Id: Ib01758d994a9e5587a4fcb5edc3d80010ef05615
These are static methods that have to do with processing language names
and codes. I didn't include fallback behavior, because that would mean a
circular dependency with LocalisationCache.
In the new class, I renamed AS_AUTONYMS to AUTONYMS, and added a class
constant DEFINED for 'mw' to match the existing SUPPORTED and ALL. I
also renamed fetchLanguageName(s) to getLanguageName(s).
There is 100% test coverage for the code in the new class.
Change-Id: I245ae94bfc1f62b6af75ea57525139adf2539fe6
I think this probably shouldn't be directly in the MediaWiki namespace,
but I don't know where is a better place to put it.
In order to avoid gratuitous use of TitleFormatter, I changed the cache
format -- the old implementation used getPrefixedDBkey() and I switched
to an ns/dbkey pair. I also changed the cache keys to use SHA1 instead
of MD5, by Daniel's request.
The previous implementation cached the parsed blacklist for one minute
without invalidation, so it could return slightly stale results, but it
didn't retrieve the bad image list message on a cache hit. The new
implementation unconditionally retrieves the bad image list message, but
uses a hash of it in the cache key and caches for one day. The new
behavior happens to be more cleanly implementable in a service.
Bug: T200882
Bug: T139216
Change-Id: I69fed1b1f3cfc1aa149e0739780e67f6de01609d
These are in preparation for making a TempFSFileFactory service, thus
the odd break-up into two files. I split it into a separate commit so
that we could verify that the same tests pass before and after the
conversion to service.
Tests cover everything except getUsableTempDirectory() (which I don't
see how to test), and register_shutdown_function()-related stuff (which
seems actually impossible to test without starting a new PHP process).
Change-Id: If61b7ea3e332adc2bceefc8e6879a9e9443c99dd
Classes that use ServiceOptions need to declare a list of keys that they
use, typically in self::$constructorOptions. If keys are missing from
that list that are supposed to be present, an exception will be thrown
when someone tries to access them. If keys are present on the list that
are never used, no error is flagged. This means if a dependency on a
given configuration option is removed and nobody updates the list, the
service will keep thinking it depends on that option when it doesn't.
This is messy at best, like an unused variable.
A new and easy-to-use TestAllServiceOptionsUsed trait fixes that
problem. It will log all the ServiceOptions accesses while the test
class runs and raise an error if there are any keys that were never
accessed.
In retrospect, it was probably not worth the time to write this, but
it's a sunk cost now.
Change-Id: Idcaf9a0e2f687069869e6f8057908ffee7dd5f11
This will help make MovePage more testable.
In the course of abstracting the logic out of ParserFactoryTest to
FactoryArgTestTrait so it could be used in MovePageFactoryTest, I made
them all unit tests instead of integration. This required some
modification to the Parser constructor so that it didn't access
MediaWikiServices unnecessarily.
Change-Id: Idaa1633f32dfedfa37516bb9180cfcfbe7ca31aa
This changeset resumes work on T89432 and related tickets
by porting an initial set of tests to the new unit test suite
separated out in I69b92db3e70093570e05cc0a64c7780a278b321a.
The tests were only ported if they worked immediately without
requiring any changes other than changing the test case class
to MediaWikiUnitTestCase and moving the test to the new suite.
If a test failed for any reason (even trivial misconfiguration),
it was NOT ported.
With this change, the unit tests suite now consits of a total
of 455 tests. As before, you can run these tests via the following
command:
$ composer phpunit:unit
Bug: T84948
Bug: T89432
Bug: T87781
Change-Id: Ibb8175981092d7f41864e641cc3c118af70a5c76
Following discussion in Ibb8175981092d7f41864e641cc3c118af70a5c76, this patch
proposes to further reduce the scope of what unit tests may access, by removing
the loading of DefaultSettings and GlobalFunctions.php. This also has the
implied effect of disabling the storage backend, as well as the global service
locator.
MediaWikiTestCase is renamed to MediaWikiIntegrationTestCase so it's scope and
purpose is more clear. Whether we still need to keep `@group Database`
annotation around is debatable, as it's unclear to me what the performance costs
are of implying database access for all tests which extend IntegrationTestCase.
As far as I can tell, `@group Database` is primarily used in CI to run faster
tests before slower ones, and with the new UnitTestCase the annotation seems
redundant.
To run all testsuites, use `composer phpunit`. Other composer scripts:
- `composer phpunit:unit` to run unit tests
- `composer phpunit:integration` to run integration tests
- `composer phpunit:coverage` to generate code coverage reports from unit
tests (requires XDebug).
Note that you can pass arguments to composer scripts with `--`, e.g. `composer
phpunit:integration --exclude-group Dump`.
Other changes:
- Rename bootstrap.php to bootstrap.maintenance.php so it's clear it's part of
the legacy PHPUnit-as-maintenance-class setup
- Create new bootstrap.php which loads the minimal configuration necessary for
the tests, and do additional setup in the run() method of the unit/integration
test case classes
- Move the unit-tests.xml file to phpunit.xml.dist in preparation for this being
the default test configuration
For a follow-up patch:
- Find unit/integration tests for extensions/skins
- Migrate other test suites from suite.xml
- Support running all tests via vendor/bin/phpunit
Bug: T84948
Bug: T89432
Bug: T87781
Change-Id: Ie717b0ecf4fcfd089d46248f14853c80b7ef4a76
With the introduction of a REST API into MediaWiki core, we're going to
want to share parameter validation logic rather than having similar code
in both the Action API and the REST API. This abstracts out parameter
validation logic as a library.
There will be at least two follow-up patches:
* One to add calls in the REST API, plus the interface for the REST API
to do body validation. Should be reasonably straightforward.
* One to adjust the Action API to use this. That'll be much less
straightforward, as the Action API needs some MediaWiki-specific types
(which the REST API might use too in the future) and needs to override
the defaults on some of the library's checks (to maintain back-compat).
Bug: T142080
Bug: T223239
Change-Id: I5c0cc3a8d686ace97596df5832c450a6a50f902c
Depends-On: Iea05dc439688871c574c639e617765ae88a75ff7
This changeset lays down the basic groundwork required to implement
T89432 and related tickets and is based on exploration done
at the Prague Hackathon. The goal is to identify tests in MediaWiki core
that can be run without having to install & configure MediaWiki and its dependencies,
and provide a way to execute these tests via the standard phpunit entry point,
allowing for faster development and integration with existing tooling like IDEs.
This changeset creates a new subdirectory under phpunit/ and organizes it
into a separate test suite. The environment for this suite is set up
via a PHPUnit bootstrap file without a custom entry point. For B/C, this
directory is also registered in suite.xml, to ensure that existing CI jobs
still pick up tests in the new suite.
For initial testing, a single test class, PasswordFactoryTest, was moved
to this new suite.
You can run the new suite using the follwoing command:
$ vendor/bin/phpunit -d memory_limit=512M -c tests/phpunit/unit-tests.xml
Bug: T84948
Bug: T89432
Bug: T87781
Change-Id: I69b92db3e70093570e05cc0a64c7780a278b321a
This changeset implements T89432 and related tickets and is based on exploration
done at the Prague Hackathon. The goal is to identify tests in MediaWiki core
that can be run without having to install & configure MediaWiki and its dependencies,
and provide a way to execute these tests via the standard phpunit entry point,
allowing for faster development and integration with existing tooling like IDEs.
The initial set of tests that met these criteria were identified using the work Amir did in
I88822667693d9e00ac3d4639c87bc24e5083e5e8. These tests were then moved into a new subdirectory
under phpunit/ and organized into a separate test suite. The environment for this suite
is set up via a PHPUnit bootstrap file without a custom entry point.
You can execute these tests by running:
$ vendor/bin/phpunit -d memory_limit=512M -c tests/phpunit/unit-tests.xml
Bug: T89432
Bug: T87781
Bug: T84948
Change-Id: Iad01033a0548afd4d2a6f2c1ef6fcc9debf72c0d
This introduces XML schema validation into the unit tests for
the backup dump scripts. This is intended to ensure that the
output keeps conforming to the schema when updating XmlDumpWriter
and friends to support newer schema versions.
Bug: T174031
Change-Id: Iafa8cb8ba5b3684a08172e92974edaf0482f19b7
Created class RevisionStoreCacheRecord to avoid returning stale
cached revision visibility and actor data when changes were
made after the cache was populated for that revision.
Bug: T216159
Change-Id: Iabed80e06a08ff0793dfe64db881cbcd535cb13f
Update the default implementation of FormSpecialPage::checkExecutePermissions()
so that a Special page is only blocked if the user has a sitewide block.
This change allows the user to continue performing critical functions (like
resetting their password) even if they are partially blocked.
Bug: T209097
Change-Id: I5190297b7b235b6ebbdfa522323ce9bbd46b6729
When a unit test fails it is possible, perhaps even likely in some
cases, that some code that was run logged useful information about
how that failure came to be.
Help people out, tell them what happened!
Change-Id: I30bbc31799a65024868678d052fec9aafacc1aff
Remex is pure PHP so there is no reason to use an external tidy any
more. Configuration variables and implementation classes were
deprecated in 1.32 or earlier. We've kept only $wgTidyConfig
which can be used for experimental features or debugging Remex.
Bug: T198214
Change-Id: I99d48f858d97b6e1d1e6cd76a42c960cc2c61f9f
Partial blocks logic will be used in multiple places. This
classes will group block restriction functionality to avoid
code duplication
Bug: T202036
Change-Id: I675316dddf272fd0d6172ecad3882160752bf780
During development a lot of classes were placed in MediaWiki\Storage\.
The precedent set would mean that every class relating to something
stored in a database table, plus all related value classes and such,
would go into that namespace.
Let's put them into MediaWiki\Revision\ instead. Then future classes
related to the 'page' table can go into MediaWiki\Page\, future classes
related to the 'user' table can go into MediaWiki\User\, and so on.
Note I didn't move DerivedPageDataUpdater, PageUpdateException,
PageUpdater, or RevisionSlotsUpdate in this patch. If these are kept
long-term, they probably belong in MediaWiki\Page\ or MediaWiki\Edit\
instead.
Bug: T204158
Change-Id: I16bea8927566a3c73c07e4f4afb3537e05aa04a5
Otherwise I get errors every time I try to run PHPUnit on includes/ or
includes/parser, because it tries to run ParserIntegrationTest.php and
fails. Apparently the <exclude> in suite.xml doesn't work if PHPUnit is
invoked on a directory.
Bug: T201278
Change-Id: I7d09576bee2705d8516152e8fa671da8dac40233
* Instead of rewriting $argv, add a Command subclass called
MediaWikiPHPUnitCommand which overrides the configuration using the
stub functions in Command which were provided for that purpose.
* Revert c804a0b5b9, which added redundant debug output to tests,
and instead install the MediaWikiPHPUnitTestListener listener
unconditionally. Deprecate and make non-functional the --debug-tests
option. If you don't want tests to produce debug output, you can
always turn the channel off.
* Because I added our listener to the listener array instead of making
it override the printer, it's no longer necessary to derive from
PHPUnit\TextUI\ResultPrinter. Instead we derive from BaseTestListener.
So we don't need to call the (empty) parent methods.
* Remove the --with-phpunitclass feature since it doesn't work with this
scheme.
* Instead of passing CLI args to MediaWikiTestCase via a public static
variable, inject it non-statically by overriding the TestRunner and
TestResult.
* Remove --file, which has been non-functional since my 2016 refactor.
Change-Id: Ibcaf9ca81c8dc63cce6dc6f6fb1fffee19f8804e
Trying to avoid resetting services introduces a lot of complexity and
several bugs. We were doing a reset for 70% of @group Database tests
anyway.
Instead:
* Reset services at the start of MediaWikiTestCase::run().
* Capture the actual original service container instead of making a
special shared service container.
* The test-isolated local service container can now only be initialised
non-statically. Revert the recent conversion of overrideMwServices()
to static.
* Store a reference to the local service container in the test case
object. In MediaWikiTestCase, always use the original or local service
container directly, to avoid confusion about which one is active at
the time.
* Remove a lot of unnecessary teardown
* Always call ServiceContainer::destroy() before forceGlobalInstance()
since the memory is not otherwise freed.
Change-Id: I4a17c1c7ec92c14e3bc471f0216473ebe19477b9
Move logic for rendering a diff between two content objects out of
DifferenceEngine, into a new SlotDiffRenderer class. Make
DifferenceEngine use multiple SlotDiffRenderers, one per slot.
This separates the class tree for changing high-level diff properties
such as the header or the revision selection method (same as before:
subclass DifferenceEngine and override ContentHandler::getDiffEngineClass
or implement GetDifferenceEngine) and the one for changing the actual
diff rendering for a given content type (subclass SlotDiffRenderer and
override ContentHandler::getSlotDiffRenderer or implement
GetSlotDiffRenderer). To keep B/C, when SlotDiffRenderer is not overridden
for a given content type but DifferenceEngine is, that DifferenceEngine
will be used instead.
The weak point of the scheme is overriding the DifferenceEngine methods
passing control to the SlotDiffRenderers (the ones calling
getDifferenceEngines), without calling the parent. These are:
showDiffStyle, getDiffBody, getDiffBodyCacheKeyParams. Extensions doing
that will probably break in unpredictable ways (most likely, only
showing the main slot diff). Nothing in gerrit does it, at least.
A new GetSlotDiffRenderer hook is added to modify rendering for content
models not owned by the extension, much like how GetDifferenceEngine
works.
Also deprecates public access to mNewRev/mOldRev and creates public
getters instead. DifferenceEngine never supported external changes to
those properties, this just acknowledges it.
Bug: T194731
Change-Id: I2f8a9dbebd2290b7feafb20e2bb2a2693e18ba11
Depends-On: I04e885a33bfce5bccc807b9bcfe1eaa577a9fd47
Depends-On: I203d8895bf436b7fee53fe4718dede8a3b1768bc
NOTE: this changes the numeric values of the MIGRATION_XXX constants!
Order is preserved.
Bug: T197619
Change-Id: I16db7dd5799ab98c1cb12e7cd1e0b2da83b366fc
Enable inserts to the new MCR db schema in single slot mode only.
TODO:
- RELEASE NOTES
Notes:
- When in MIGRATION_WRITE_NEW or greater, deleting and then
restoring a page will result in different data in the revision table.
For example, if you delete a page that has text_ids present in the
revision table and restore it, the text_ids will be blank after.
- When in MIGRATION_WRITE_BOTH or greater the archive table will
start to ar_content_model entries where previously it would have been
given NULL. This is due to the old content schema having NULL in the db
when the default content model is used, but the new schema will always
have a value, taken from the content_models table
Note: If259b1e1c49ce was squashed into this change.
Bug: T183488
Bug: T174024
Change-Id: Ic2221da30c8f6ac2ba42720fcd568f2d0ed70534