- Removed space after casts
- Removed spaces in array index
- Added spaces around string concat
- Added space after words: switch, foreach
- else if -> elseif
- Removed parentheses around require_once, because it is not a function
- Added newline at end of file
- Removed double spaces
- Added spaces around operations
- Removed repeated newlines
Bug: T102609
Change-Id: Ib860222b24f8ad8e9062cd4dc42ec88dc63fb49e
wfSuppressWarnings() and wfRestoreWarnings() were split out into a
separate library. All usages in core were replaced with the new
functions, and the wf* global functions are marked as deprecated.
Additionally, some uses of @ were replaced due to composer's autoloader
being loaded even earlier.
Ie1234f8c12693408de9b94bf6f84480a90bd4f8e adds the library to
mediawiki/vendor.
Bug: T100923
Change-Id: I5c35079a0a656180852be0ae6b1262d40f6534c4
Implementation written by Fred Emmott of Facebook. Quoting Fred:
As well as array access being faster, the main advantage is actually
that this significantly reduces the use of unserialize(), which does a
lot of memcpys when making the strings.
Benchmarks compared to LCStoreCDB:
* HHVM (no repo-auth): ~7% improvement
* HHVM (with repo-auth): ~12% improvement
* PHP7: ~1% improvement
My (Legoktm) brief testing noted that the generated PHP files were
noticiably larger than the CDB ones:
* 1.5M en.l10n.php
* 932K l10n_cache-en.cdb
Bug: T99740
Change-Id: Ib2c5856d40cd928cab4a79cb935b3ce08c598300
* This should not be used, and load() does not see them.
If the content language is 'de', then message overrides
will not include MediaWiki:<key>/de pages.
Change-Id: Ie4b6b356bd309814dd4a88040a29a7ebd509712a
* The cache has to reload and *after* locking to avoid
losing any concurrent changes.
* Also fixed incorrect assumption in MessageCacheTest.
Message overrides for the content language do not use
the language suffix.
Change-Id: I98ff158a1575330bc59efe6badb27f8de8717951
This allows us to continue to use MessageBlobStore::get() as a way
to pre-fetch messages in batches for multiple modules while also
allowing individual modules to retrieve their messages in a convenient
way.
This is in preparation for implementing ResourceLoaderModule::buildContents
and using it in ResourceLoaderModule::getVersionHash.
ResourceLoader::respond() already fetches message blobs in batches for the
actual response, but it also needs getVersionHash(), which would otherwise
fetch the same messages a second time.
Change-Id: I7e4c8b65765b54807123e85cfbb7eb2e5b2f39bd
Modules now track their version via getVersionHash() instead of getModifiedTime().
== Background ==
While some resources have observeable timestamps (e.g. files stored on disk),
many other resources do not. E.g. config variables, and module definitions.
For static file modules, one can e.g. revert one of more files in a module to a
previous version and not affect the max timestamp.
Wiki modules include pages only if they exist. The user module supports common.js
and skin.js. By default neither exists. If a user has both, and then the
less-recently modified one is deleted, the max-timestamp remains unchanged.
For client-side caching, batch requests use "Math.max" on the relevant timestamps.
Again, if a module changes but another module is more recent (e.g. out-of-order
deployment, or out-of-order discovery), the change would not result in a cache miss.
More scenarios can be found in the associated Phabricator tasks.
== Version hash ==
Previously we virtually mapped these variables to a timestamp by storing the current
time alongside a hash of the value in ObjectCache. Considering the number of
possible request contexts (wikis * modules * users * skins * languages) this doesn't
work well. It results in needless cache invalidation when the first time observation
is purged due to LRU algorithms. It also has other minor bugs leading to fewer
cache hits.
All modules automatically get the benefits of version hashing with this change.
The old getDefinitionMtime() and getHashMtime() have been replaced with dummies
that return 1. These functions are often called from getModifiedTime() in subclasses.
For backward-compatibility, their respective values (definition summary and hash)
are now included in getVersionHash directly.
As examples, the following modules have been updated to use getVersionHash directly.
Other modules still work fine and can be updated later.
* ResourceLoaderFileModule
* ResourceLoaderEditToolbarModule
* ResourceLoaderStartUpModule
* ResourceLoaderWikiModule
The presence of hashes in place of timestamps increases the startup module size on
a default MediaWiki install from 4.4k to 5.8k (after gzip and minification).
== ETag ==
Since timestamps are no longer tracked, we need a different way to implement caching
for cache proxies (e.g. Varnish) and web browsers. Previously we used the
Last-Modified header (in combination with Cache-Control and Expires).
Instead of Last-Modified (and If-Modified-Since), we use ETag (and If-None-Match).
Entity tags (new in HTTP/1.1) are much stricter than Last-Modified by default.
They instruct browsers to allow usage of partial Range requests. Since our responses
are dynamically generated, we need to use the Weak version of ETag.
While this sounds bad, it's no different than Last-Modified. As reassured by
RFC 2616 <http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.3> the
specified behaviour behind Last-Modified follows the same "Weak" caching logic as
Entity tags. It's just that entity tags are capable of a stricter mode (whereas
Last-Modified is inherently weak).
== File cache ==
If $wgUseFileCache is enabled, ResourceLoader uses ResourceFileCache to cache
load.php responses. While the blind TTL handling (during the allowed expiry period)
is still maxage/timestamp based, tryRespondNotModified() now requires the caller to
know the expected ETag.
For this to work, the FileCache handling had to be moved from the top of
ResoureLoader::respond() to after the expected ETag is computed.
This also allows us to remove the duplicate tryRespondNotModified() handling since
that's is already handled by ResourceLoader::respond() meanwhile.
== Misc ==
* Remove redundant modifiedTime cache in ResourceLoaderFileModule.
* Change bugzilla references to Phabricator.
* Centralised inclusion of wgCacheEpoch using getDefinitionSummary. Previously this
logic was duplicated in each place the modified timestamp was used.
* It's easy to forget calling the parent class in getDefinitionSummary().
Previously this method only tracked 'class' by default. As such, various
extensions hardcoded that one value instead of calling the parent and extending
the array. To better prevent this in the future, getVersionHash() now asserts
that the '_cacheEpoch' property made it through.
* tests: Don't use getDefinitionSummary() as an API.
Fix ResourceLoaderWikiModuleTest to call getPages properly.
* In tests, the default timestamp used to be 1388534400000 (which is the unix time
of 20140101000000; the unit tests' CacheEpoch). The new version hash of these
modules is "XyCC+PSK", which is the base64 encoded prefix of the SHA1 digest of:
'{"_class":"ResourceLoaderTestModule","_cacheEpoch":"20140101000000"}'
* Add sha1.js library for client-side hash generation.
Compared various different implementations for code size (after minfication/gzip),
and speed (when used for short hexidecimal strings).
https://jsperf.com/sha1-implementations
- CryptoJS <https://code.google.com/p/crypto-js/#SHA-1> (min+gzip: 2.5k)
http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js
Chrome: 45k, Firefox: 89k, Safari: 92k
- jsSHA <https://github.com/Caligatio/jsSHA>
https://github.com/Caligatio/jsSHA/blob/3c1d4f2e/src/sha1.js (min+gzip: 1.8k)
Chrome: 65k, Firefox: 53k, Safari: 69k
- phpjs-sha1 <https://github.com/kvz/phpjs> (RL min+gzip: 0.8k)
https://github.com/kvz/phpjs/blob/1eaab15d/functions/strings/sha1.js
Chrome: 200k, Firefox: 280k, Safari: 78k
Modern browsers implement the HTML5 Crypto API. However, this API is asynchronous,
only enabled when on HTTPS in Chromium, and is quite low-level. It requires boilerplate
code to actually use with TextEncoder, ArrayBuffer and Uint32Array. Due this being
needed in the module loader, we'd have to load the fallback regardless. Considering
this is not used in a critical path for performance, it's not worth shipping two
implementations for this optimisation.
May also resolve:
* T44094
* T90411
* T94810
Bug: T94074
Change-Id: Ibb292d2416839327d1807a66c78fd96dac0637d0
Seriously, the ops team spent some time trying to find that page during an outage,
while in fact it's an obscure Tolkien reference - better be clear.
Also, set the other dummy titles to something very clearly explaining what's
going on and where.
Change-Id: I6f33a2ea5030f22a258830a33f7bcefa7f0acd85
* This ends up being more complex than its worth
and even more so for multi-DC support
Bug: T93006
Change-Id: Iaa774fe69061e42955b11dc82d30dba93208e606
The test for OutputPage::makeResourceLoaderLink was triggering database
queries through MessageBlobStore even though it doesn't use any
messages.
In bb03d1a8e0 I had made MessageBlobStore a singleton instead of static
functions, however there's no need for it to be one since the class is
stateless. Callers can just create a new MessageBlobStore instance and
call functions upon it. Using getInstance() is now deprecated.
ResourceLoader now has a setMessageBlobStore setter to allow overriding
which MessageBlobStore instance will be used. OutputPageTest uses this
to set a NullMessageBlobStore, which makes no database queries.
Change-Id: Ica7436fb6f1ea59bd445b02527829ab0742c0842
We review documentation all the time. Even if this was a big, notable
review, it was 5 years ago. It's probably outdated again, e.g. because
methods changed but the corresponting documentaion did not. In my
opinion the fact that a review happened 5 years ago is not useful any
more.
Change-Id: I6f4fb88ea790520bf2443aae4144cdde394b5e78
* Use special prioritized refreshLinksJobs instead, which triggers when
transcluded pages are changed
* Also added a triggerOpportunisticLinksUpdate() method to handle
dynamic transcludes
bug: T89389
Change-Id: Iea952d4d2e660b7957eafb5f73fc87fab347dbe7
Xhprof generates this data now. Custom profiling of various
sub-function units are kept.
Calls to profiler represented about 3% of page execution
time on Special:BlankPage (1.5% in/out); after this change
it's down to about 0.98% of page execution time.
Change-Id: Id9a1dc9d8f80bbd52e42226b724a1e1213d07af7
DOMDocument::load fails to load the plurals data during the import
process.
This is a work-around for https://bugs.php.net/bug.php?id=64938. This
bug only rears its head when using Special:Import, because that is
essentially the only place in MediaWiki where we fiddle with
libxml_disable_entity_loader.
Bug: T58439
Change-Id: Idcb4ab1cef2a7b080543e7cc1cee5464fc476456
ResourceLoaderImageModule needs a set of SVG files and some data in
the module definition, and produces styles for a set of CSS classes,
one for each image, optionally with differently colored variants,
generated in SVG and PNG, data-URI-embedded if possible, compatible
with all browsers, and generally slick.
The intended usage is to ship icon libraries with MediaWiki that can
be used throughout the pages with no additional code.
* ResourceLoaderImageModule implements all of the logic for data
parsing and CSS generation.
* ResourceLoaderImage implements the logic for SVG image colorization
(for variants) and rasterization.
* ResourceLoader and ResourceLoaderContext were extended to serve a
new kind of load.php request that delivers a single image file. This
is used for fallback PNG images served to browsers that don't
understand SVG.
See change Ic6a76bfb for a demo.
Bug: T76473
Co-Authored-By: Trevor Parscal <trevorparscal@gmail.com>
Co-Authored-By: Bartosz Dziewoński <matma.rex@gmail.com>
Change-Id: Idf6ff4eb8e94f45946f15d283d34108b881fae6e
- Added/removed spaces around parenthesis
- Added newline in empty blocks
- Added space after switch/foreach/function
- Use tabs at begin of line
- Add newline at end of file
Change-Id: I244cdb2c333489e1020931bf4ac5266a87439f0d
If $wgMessagesDirs is initially empty, we can optimize when batch loading
extensions:
if ( !$wgMessagesDirs ) {
$wgMessagesDirs = $cache['MessagesDirs'];
}
With APC, this should be O(1) CPU time.
This was suggested by Tim in the code review of I7074b65d07c5.
Change-Id: I66fa907cdaafe18b74b5b9afaa8b6b1db069bea3
The new cdb library is pulled in via composer. Since the
library uses namespaces, a backwards-compatability layer
is provided for the old class names:
* CdbReader
* CdbWriter
* CdbException
The PHP/DBA-specific classes should never have been used directly.
Depends on I98302bdf1 in mediawiki/vendor
Change-Id: I39549ac8540b262cf91f7d1830d36327afb3033d
It's a very hot code path, so it makes sense to be able to dive into it in
detail, and having a discrete log bucket makes that easier to do.
Change-Id: I4b547e97711b9e45a99f7b747d785690c70883ec
- Added newline at end of file
- Removed double spaces/newlines
- Added space after if/function and parentheses/brackets
- Removed space before comma/cast
- Fixed indent of some lines
Change-Id: I29867ffdffdfb7d2b56997e9393497c7dc12f7d3
Needed for MobileFrontend on third-party sites that use this feature.
Ideally, there should be a way to cache mobile requests too, but that's
a different issue requiring much more effort to do properly.
Bug: 68106
Change-Id: I01a76c571d9186b325f19a00cec136459707c791
* Since individual message keys can expire, this can cause broken
messages when such a key is needed (the message is treated as if
it did not exist). The base class clearly documents a need for
more atomicity (only top level keys can fall it separately).
Change-Id: I992bba77a0afdeeeade8be013708277b79f22314
Currently LocalisationCache merges the core data for all languages in
the fallback chain, then the extension data, then merges those two, and
then gives extensions like LocalisationUpdate a chance to make final
overrides with the LocalisationCacheRecache hook.
But if LocalisationUpdate doesn't want to locally duplicate all the
messages for every language (e.g. r104041), LocalisationCacheRecache is
too late: the information as to whether a message came from the primary
language or a fallback has been lost, so when LU itself has an override
for a fallback language it can't know whether or not the existing
message should be overridden or not.
The solution is for LocalisationCache to gather the data for each
fallback language separately, call a new hook for LU to affect just that
language (LocalisationCacheRecacheFallback), and only then merge the
fallback languages together.
Bug: 68781
Change-Id: Iacfe96063fcc66c1f97ca5e5292a8fc70af988cf
* Implemented a version of BloomCache using Redis
* Added a BloomCheckTitleHasLogs handler class for avoiding
slow logging table queries when large amounts of 404 pages
are viewed (by various web crawlers at the moment).
bug: 67439
Change-Id: I26e5034755e3a7208a45991b1cf2f12467679cc1
For easier testability and other things. There are no uses
of this class in any extensions in gerrit.
Change-Id: I606de4259239e128ed7e0477fc98b84c647430c4
* Previously the cache size was unbounded and leaky
* Also made MapCacheLRU handle null values properly
Change-Id: Ia02258cf051e1ccf11457c758741b8c7922afe89
Also don't cast $model to int in LinkCache::addGoodLinkObj(); content
model IDs are non-numeric strings, not integers, so that field was
always populated with the value 0. Because 0 is a falsy value, this
caused subsequent calls to Title::getContentModel() to return the
default model rather than the correct one.
Also (hopefully) fixed every single query that could cause a
LinkCache entry to be added without the content model.
Bug: 69789
Change-Id: I94f06baf406afa538cd2b10139598442f9fc6759
- Swap "$variable type" to "type $variable"
- Added missing types
- Fixed spacing inside docs
- Makes beginning of @param/@return/@var/@throws in capital
- Changed some types to match the more common spelling
Change-Id: I7b65fe04db431342cc58b469dc48f41a50c4e891
* This avoids breaking the main transaction in finishWrite().
* Also removed an unused variable in SqlBagOStuff.
Change-Id: Ia330ac362b080c1338616d95b793032c4752dc23
* Only do the DB inserts in finishWrite(). Previously this would
COMMIT there but would spread out queries throughout the set()
calls. This pushes all the contention down to the last step.
Change-Id: Ia8afb79a8328c18a7d8a386bcd15a5074007d52e
Change-Id I427c6de5a0a29b43cff755db0eb8a750db620173 increases the
probability that a null byte will attempt to be stored in the
lc_value column. PostgreSQL does not allow that byte in a text
column, so convert the column to bytea.
If the column already contains corrupted data, the upgrade routine
might fail. To prevent this, delete the contents of the table before
changing the type.
Bug: 62098
Change-Id: Ie8368bde398b2ae4d3cfc9ee7bf35874bd2ded68
These files have all had treatment before, and these occurrences have either
been missed or have been introduced after.
Change-Id: I06cdab4616b5bff47c85152df28f18c861730a23
Swapped some "$var type" to "type $var" or added missing types
before the $var. Changed some other types to match the more common
spelling. Makes beginning of some text in captial.
Also added some missing @param.
Change-Id: I86fd10e3f2d4bb80e7432533038d124693acfb3c
For now, non-message data (e.g. special page aliases, magic words) belong
in separate files having their own keys in $wgExtensionMessagesFiles. It
is unnecessary to read any PHP files listed under keys that exist in
$wgMessagesDirs; they are merely compatibility shims.
Bug: 63926
Change-Id: I92013d0a45e83ad0f5ac483a3db867806eb71f8a
Statistics are now showing always no messages since languages.inc
does not manage to load the JSON messages.
Had to make LocalisationCache::readJSONFile() public so that it can
be used in languages.inc; since all methods from LocalisationCache
return localisations merged with fallbacks, which is not what we
want here.
Fix for I918cfdc46c (0dd91d5).
Change-Id: Ib52287db618b9d072e847130070d165a3e7ae44b
LocalisationCache and Language have to take the JSON files into account
in deciding if a language is present or not.
Standardizing language validity checking with isSupportedLanguage
and isValidBuiltInCode.
Co-Authored-By: Niklas Laxström <niklas.laxstrom@gmail.com>
Co-Authored-By: Siebrand Mazeland <siebrand@kitano.nl>
Change-Id: I35bbb3a7a145fc48d14fff620407dff5ecfdd4fc
Rationale is the same as for Ifb6dc2666f (96b04ce): ability to
separate it form the main log group, as it always has a predicitible
value.
Change-Id: I0ac5baf5ab8fbe4d2025ccf6439b883dc82e9d5b
Also removed true as second parameter to it from CloneDatabase.php
since it is the default value of that parameter.
Change-Id: I727ebae2bd4df0e26019985ce8c7ce73381c5642
Example usage:
$wgHooks['MessageCache::get'][] = function( &$key ) {
static $keys = null;
if ( $keys === null ) {
global $wgExtensionMessagesFiles;
require( $wgExtensionMessagesFiles['OverrideMessages'] );
$keys = array_flip( array_keys( $messages['en'] ) );
}
if ( isset( $keys["myprefix-$key"] ) ) {
$key = "myprefix-$key";
}
return true;
}
Pros:
* Easy way to override standard core and extension messages without
any changes to them
* Messages can be stored in a standard i18n file
* Messages can be translated easily with Translate
* Messages can be shared accross multiple wikis easily
* Takes advantage of the normal message cache behavior unlike the
MessagePreLoad hook
* Missing translations fallback to the override, not to the
uncustomized standard translation
* Do not need to handle conflicting message keys at translatewiki.net
if adopted by WMF
Cons:
* This method is called often, so there will be small performance
impact if no hooks are registered. Impact can be big if the
implementation of hook subscriber is inefficient.
This can help with bugs like 36149. It doesn't remove the manual work
needed to detect those messages and adding them to the i18n file.
I have been using this patch in a wiki farm for months.
Change-Id: Ib39937a440e71ae7292cf992ab37a569189741e4
- The parameter is now a string, making is more understandable than
boolean values
- It takes the same values in both wfDebug() and wfDebugLog() (except
for 'private' which is only used in the latter)
- This adds a new possibility to wfDebugLog() to log the message either
on the specific log or the general one, but not to the debug toolbar
- Old boolean values are still recognised for backward compatibility
- Also send the messages passed to wfDebugLog() to the debug toolbar
when they are written to a specific log and not restricted to logs
- Updated the calls of and wfDebug() and wfDebugLog() with the last
parameter to change it into a string
- Renamed MWDebug::sendWarning() to MWDebug::sendMessage() and added
$group parameter to it; will not break anything since that method
is marked as private
- Changed the call to wfDebug() from MWDebug::sendMessage() to use
wfDebugLog() with 'log' as thrid parameter, so that those messages
can be logged separately from the main log and they don't show up
a second time on the "debug log" tab of the debug toolbar
Change-Id: I1be09d4c1d3408ed5b26a5db02691c17c0ec0926
Added wfSuppressWarnings and wfRestoreWarnings before and after the
ini_set call to apc cache by default to suppress errors if ini_set is
disabled.
Change-Id: If91e99c30fce3af14e69acd35112af188e62b6ac
Implementation for https://www.mediawiki.org/wiki/Requests_for_comment/Localisation_format
Add $wgExtensionMessagesDirs, which tracks the directory
(or directories) where each extension stores it's JSON i18n files.
In this commit only support for messages is implemented, but adding
support for other i18n variables (e.g. magic words) is easy to do later.
To be backwards compatible, an extension can specify both
$wgExtensionMessagesFiles and $wgExtensionMessagesDirs. Older versions
of MediaWiki will just work, and newer versions will use the JSON files
while ignoring the PHP file (except if the PHP file contains non-message
data like magic words).
Misc changes:
* Updated mergeMessageFileList.php to output both
$wgExtensionMessagesFiles and $wgExtensionMessagesDirs
Change-Id: I8d137e15e1670880a9847263e6ce796c62a4670d
* New operands i, v, w, f, t
* New operators =, !=, %
* Ignore "samples", which are basically unit tests embedded in rule
specifications
* Ignore the new "other" rules, which have an empty condition. It
doesn't really makes sense to parse them, since the empty condition
means special handling should be done in the caller, it is not
equivalent to an unconditional true or false.
* Trailing zero support requires that the input number be a string.
Documented this.
* Fixed some comments
* Added test cases for new features
Bug: 56931
Change-Id: I96986c0c664f785e75b0a4ced2ec9e37b72681c1
- Place commas correct
- Moved comments
- Add space after if/foreach/catch
- Reformat some conditions
- Removed trailing spaces/tabs
Change-Id: I40ccda72c418c4a33fcd675773cb08d971510cdb
Classes TitleListDependency and TitleDependency that are currently not
used. Searched core and extensions in Gerrit.
Change-Id: I51404ce36c4ef55393588817d1673fd17c81b4a2
Update the defaults for $revision and $model from bool to int, making it
consistent with the documented input. Also update docs and line length.
Change "inval( $x )" to preferred "(int) $x" while changing the method.
Change-Id: Ic19a408aa7c50fb03e2c3aca8df3fa7cedc2420b
Set visibility to private for properties that are not referenced outside
of the class itself, and when the class is not currently being subclassed.
Change-Id: I427c6de5a0a29b43cff755db0eb8a750db620173
No direct references found in core or extensions outside of the classes
themselves. None of these are subclassed, so set all of them to private.
Change-Id: Id599c0830c1e6d3679c7ae55147f4444f8252987
Mark all private, except the one that's being used in subclass. Checked
core and extension for direct uses. None found.
Change-Id: If73d65ca094ff56deb19d3b6f3ef99892654726d
iPart of program to remove underscores from class names. Checked core and
600+ extensions for occurrences. All uses are in core, and are updated in
this change.
Change-Id: I432dc249d22053728013ae7d0d56c3c398021c5e
Part of program to remove underscores from class names. Checked core and
600+ extensions for occurrences. All uses are in core, and are updated in
this change.
Change-Id: Ib157c3cf209677718ff184552cf872b1d3f4e969
* In partition(), avoid doing the JOIN since it is not needed and prevents
index-only queries.
* Made numLinks() wrap partition when no $max is specified.
* Also fixed some docs
Change-Id: I05a83f71efb4c6e99e40883d7fa53da59184b13c
The grouping makes at least as much sense as job/, and certainly makes
more sense than cache/. With directories named after base classes, it is
fairly easy to tell what should go where. The grouping of
DeferredUpdates, DataUpdate and CallableUpdate would surely be
uncontroversial.
The move of SearchUpdate out of search/ demonstrates the conflict between
arrangement by module versus arrangement by type, which is the most
difficult design question here. I think arrangement by type is more
consistent with e.g. the arrangement of the core root, i.e. tests/,
resources/, maintenance/, etc. where a given feature will have its files
split up into a mostly type-based hierarchy.
I also tidied up AutoLoader.php by moving includes/content to the correct
location, sorted alphabetically by subdirectory.
Verified with AutoLoaderTest.
Change-Id: Ib369411d0caca38e72978084aa57348f1b892ed0
The existing "linkprefix" message is unlikely to be accurately
customized by message translators (as shown by the fact that, of the 10
distinct customizations prior to Iaa7eaa44 (which made them even more
complicated), 3 were broken or entirely ineffective, 1 was half
ineffective, and 2 more seem to have included the Latin-1 Supplement by
accident) or by local wiki admins. So, like linktrail before it, let's
move it out of the system messages and into a separate language
variable.
At the same time, let's make it a simple character set (like
$wgLegalTitleChars) rather than a complicated regular expression. The
complicated regex now lives in the parser.
This also adjusts the output of the API's action=query&meta=siteinfo and
adds an accessor parallel to the linkTrail accessor to Language.
Note the following changes that are not simply extracting the existing
charset from the linkprefix message for $linkPrefixCharset:
* The En message matched all non-ASCII UTF-8 characters by matching the
component bytes (\\x80-\\xff). The new character set is equivalent.
* Various languages were identical to En and so have no $linkPrefixCharset
set. These are: Ary Az Ce Ga Id Ka Kiu Km Ltg Mk Ms Ne Nn Ro Roa_tara Sc Si
Sr_ec Sr_el Tl Tt_cyrl Tt_latn Ug_arab War
* Cu, Uk, and Udm are changed to match any number of „ or « in the prefix.
* Cv tried to include "«" that was redundant to the range \\x80-\\xff
(see En comment). This was removed.
* Diq was entirely bogus, and so was removed.
* Gu included many additional UTF-8 characters that are redundant to the
range \\x80-\\xff (see En comment). These were removed, and the
resulting character set is equivalent to En.
* Mt has been broken since it was introduced in r37242. The charset used is
equivalent to the broken regex.
Bug: 56031
Change-Id: I3369851b33113fc118a1bace38f3ac310cdd9725
It's elitist mathematical jargon. In all cases dealt with here, it adds
no additional meaning compared to "if", beyond what was already obvious
from context. Thus, its only purpose is to smugly demonstrate that the
author attended their second-year mathematics classes, at the expense of
causing confusion for everyone who doesn't have such a background.
If you really think you need to convey extra information beyond what
"if" gives you, the English language contains plenty of devices for doing
so, without resorting to neologisms.
Change-Id: Iae21095d02ec2935c10e94f532235c2671c115b1
Also removed some unnecessary ones. I think I've caught them all.
The spaceless version already appears in core ~300 times (after
accounting for false positives when grepping). Some consistency would
be nice.
Change-Id: I607655b5f4366e66dc78730d5fd2f57ed8776cae
This patch does two things:
A) rename $wgHTCPMulticastRouting to $wgHTCPRouting since you can have
MediaWiki send purge packets over unicast.
B) add support for multi hosts purge in the few cases one want to split
the multicast groups per cache role but still want to purge more than
one cache group.
A) rename
The rename adds deprecation notices in the comments and adds a back
compatibility layer in the case someone is already using this feature.
Given Wikimedia Foundation is not even using it, it is very unlikely,
but yet: better safe than sorry.
My logic is flawed sometime, so that needs a bit of review :) There is
two levels of deprecations to watch for:
- pre mw1.20 which useds $wgHTCPMulticastAddress and
$wgHTCPMulticastPort
- pre mw1.22 (aka before this patch) that used $wgHTCPMulticastRouting
The resulting configuration should be properly loaded in $wgHTCPRouting.
B) multi hosts
The HTCP routing let you split purges to different hosts according to
the URL. In some case, we want to be able to purge an URL from more
than one multicast group. A Wikimedia example would be to send text
related purges to the text and mobiles caches while upload purges are
sent to the upload caches.
An abstracted example would be:
$wgHTCPRouting = array(
// upload URLs to upload caches
'/(upload|thumbs)/' => array(
'host' => '<ip for upload caches>'
),
// Everything else to text & mobile
'' => array(
array( 'host' => '<ip for text caches>' ),
array( 'host' => '<ip for mobile caches>' ),
),
);
Change-Id: Ie87f6b81007f47f9cb439371743f3ad9a4b0c774
I tend to dislike code style such as:
if( $ok ) {
// lot of code
} else {
return false;
}
The SquidUpdate::HTCPPurge() used that pattern to handle a
socket_create() issue. I have simply moved the block above and inverted
the condition. Ie:
if( ! $ok ) {
return false;
}
// lot of code
That saves a level of indentation and makes the code a bit easier to
follow IMHO.
Change-Id: Ic3c6e22bbb637352fef740a0c1663a4b6f5a2b6a
When a language code is unloaded, it also needs to clear the
shallowFallbacks entry. Otherwise the next time that language is used it
will incorrectly think that the other setup done by initShallowFallbacks
is still set up, leading to warnings.
Change-Id: Idf6a78f56a3bb864cc921427ac82972594610047
To debug purging issues in beta, it would be useful to have all squid
related messages grouped at the same place. wfDebug() is logged on beta
but it has a good amount of spam which is not that useful. Regrouping
all squid operations under the debug log group 'squid' will make it
easier to investigate.
Change-Id: I11112585f38307ae56ec3e05e7a8d6d9dab31bfa
Using the following command line, I have found doc comments mentioning
"1.21" when they should mention "1.22" instead, which I have fixed
manually:
git diff REL1_21 | grep --color=always -C 10 -iE \
'^\+.*(since|deprecated).*1\.21(\D|$)' | aha > oldver.html
I also moved the release notes for I1987190f ("Combine JavaScript and
JSON encoding logic") from RELEASE-NOTES-1.21 to RELEASE-NOTES-1.22
because I had reverted the commit on REL1_21 only (see Id3b88102 and
bug 47431 for the rationale).
Change-Id: I11b917a371e07267dfa98b8449776d0c1cb29b15
Follows-Up: I25cf5a94f6e47f85a9d0b80cc1c9c9f957288478
Follows-Up: I3d72e4105f6244b0695116940e62a2ddef66eb66
Follows-Up: I3faa9c3e8107c6e46cdf21f8c18adda1f42890d7
Follows-Up: I6aab19c8d68bf47beddad42632b0360a7b12f251
Follows-Up: I86368821fc2cd0729df5342b8572eb470c0f77a0
Follows-Up: Id3b88102e768318e3605a19e9952121091a40915
Follows-Up: Ie667088010e24eb6cb569f9e8e8e2553005223eb
Functions expect the message cache to return a string if a message
exists, even empty, and false if it does not exist. This adds casting
to the substr() function, which would return false for existing
messages that were just blank.
Bug: 14176
Change-Id: Id91914a3701fe53f1e2e894824512489392c628b
This patch adds the ability to destroy the LinkCache singleton or to
replace the instance with a different object. Note the $instance static
variable is now at the class level instead of at the method level.
Change-Id: Ib110ad061868834a52a6bac651976b3ffab4a6ce
The core function behind wfMessage() (MessageCache->get()) did not
apply the language fallback chain to on-wiki messages.
This patch has changed the behavior to iterate over all possible
languages, first checking on-wiki and then checking the CDB cache,
until it finds the message. Note that fallback languages never
take precedence over the actual requested language.
This patch was taken from the following changes and then
adjusted to fix issues that caused bug 46579.
* Change-Id: Iaaf6ccebd8c40c9602748c58c3a5c73c29e7aa4d
- Author: Matthew Walker <mwalker@wikimedia.org>
- (cherry picked from commit d434bfcf3b)
* Change-Id: Ib607a446d3499a3c042dce408db5cbaf12fa9e3d
- Author: Mormegil <mormegil@centrum.cz>
- (cherry picked from commit 1b8cb8dc31)
Bug: 1495
Bug: 46579
Change-Id: I420457863eeb79824698d06abc7784032b267af2
[includes/cache/MessageCache.php]
- internal constants
- constructor
- a few missing @var
[includes/clientpool/RedisConnectionPool.php]
- group internal settings applying to the pool
- misc protected members updates
[includes/debug/Debug.php]
- missing parameter name in @var statements
Change-Id: I6ff0a68d659529d128f40f32b0fd1c1d39af952f
Added spaces after/before parenthesis
Removed unneeded parenthesis around some statements
Broke a long line
Change-Id: I7fbe129f7bbf524dd0598ece2a9708643f08453b
Squiz.WhiteSpace.LanguageConstructSpacing:
Language constructs must be followed by a single space;
expected "require_once expression" but found
"require_once(expression)"
It is a keyword (e.g. like `new`, `return` and `print`). As
such the parentheses don't make sense.
Per our code conventions, we use a space after keywords like
these. We appeared to have an unwritten exception for `require`
that doesn't make sense. About 60% of require/include usage
was missing the space and/or had superfluous parentheses.
It is as silly as print("foo") or return("foo"), it works
because keywords have no significance for whitespace between
it and the expression that follows, and since experessions can
be wrapped in parentheses for clarity (e.g. when doing string
concatenation or mathematical operations) the parenthesis
before and after basiclaly just ignored.
Change-Id: I2df2f80b8123714bea7e0771bf94b51ad5bb4b87
Disable of MessageBlobStore clear
Reset $wgAutopromote (should be moved to a config change!!)
Disable setting of wgStyleSheetPath
Throttle page_touched
Add apc htcp packet numbers to SquidUpdate
Disable set names binary/utf8
Commment out searchindex table indexes
Was c532e81d583d3d0439fe76eea4d105d675461b56
Original revision Change-Id I42c4f859e55eb198f6c6841e582b3552aad7b31f
https://gerrit.wikimedia.org/r/#/c/7606
Change-Id: I5ec8dd53188e9e4128f99ceaff38ebf9dcf570bb
I noticed on special:listfiles/username, UserCache was doing queries
like select user_whatever from user where user_id in ( '1', '1', ...)
with the same user id 50 times (one for each result returned in the
special page). That seemed a little insane, so put the list of
users to query through a array_unique. (Quite likely the db would
optimize that query to not literally look up the same user 50 times,
but nonetheless it seems better to filter the list before then)
Change-Id: I80c8a359d0f7a53b2420ebcda641e594dd3c56e9
* This will do the page_touched UPDATE in autocommit mode to avoid
locking a bunch of titles for some unknown amount of time that
depends on how big the transaction is.
Change-Id: I6ec16a73c11fbf19c24d2b7fe7d01f91b9dcf33a
And added/removed spaces around some other tokens,
like +, -, *, /, <, >, =, !
Fixed windows newline style
Change-Id: I0b9c8c408f3f6bfc0d685a074d7ec468fb848fc8
Remove some trailing whitespace, break long lines, make PHPDoc consistent
and update it in places.
Change-Id: I340b43a47e121a44ebd4aaa2a45dff12e945e645
* Use the stale message cache while the new one is being generated
* Revert I811755d4 (make message cache load failure fatal). This
escalated several very plausible temporary site issues from barely
noticeable to complete downtime -- for example, memcached being down
on a site with only one memcached server.
* Remove $wgLocalMessageCacheSerialized, it's always been pointless
* Clarify a couple of comments.
* Increased lock wait timeout to 30s
* Make lock() fail immediately on memcached connection refused
Tests done:
* With local cache enabled: normal cold refill; refill local from
global cache; use stale local cache during remote refill; use stale
global cache during remote refill; cold cache wait for remote refill;
saveToCaches() failure; memcached connection refused.
* With local cache disabled: saveToCaches() failure; cache disabled due
to "error" status key; memcached connection refused.
Setting a 1-day expiry in memcached, with a ~10s CPU cost to replace, is
not the best idea since it inevitably leads to a cache stampede. Dealing
with the stampede by waiting for a lock is not ideal, even if it were
implemented properly, since it's not necessary to deliver perfectly
fresh message cache data to all clients.
This is especially obvious when you note that barring bugs, expiry and
regeneration always gives you back the exact same data, because we have
incremental updates (MessageCache::replace()). Keeping all clients
waiting for 10s just to give them the data they have already is pretty
pointless.
So, continue to serve the site from the stale message cache while the
new one is being generated.
One caveat: if local caching enabled, when the message cache becomes
stale, a sudden spike in network bandwidth may result due to the full
array (also typically stale) being fetched from the shared cache.
Bug: 43516
Change-Id: Ia145fd90da33956d8aac127634606aaecfaa176b
Follow up Ib94a8c18c4e270a7bd46faa17eb27a22ff950f75
Moved some empty lines to match the places of other profile calls in the
file.
Change-Id: I6616b18027cdb9e70b43948aaff999a2e25b07e0
* Batch the queries to get the partitions.
* Improved caching of getNumLinks() with $max.
* Added a TTL to the ProcessCacheLRU use for sanity.
* Some small logic cleanups in partitionResult().
* Also cleaned up some code duplication.
Bug: 43452
Change-Id: I0b9710fe222b3d2cb4dc9ab2eeb0758873a8066c
This patch set reverts the following:
* Iaaf6ccebd8c40c9602748c58c3a5c73c29e7aa4d
* Ib607a446d3499a3c042dce408db5cbaf12fa9e3d
* Ic59fd20856eb0489d70f3469a56ebce0efb3db13 (partially)
Bug 46579 comment 17 describes a desired solution. In
If88923119179924a5ec091394ccab000ade16b3e we are working on a fix, but it is
taking longer than we anticipated. There was a deployment window planned
about now, but we didn't make it. It makes sense to revert for now, and commit
a proper solution somewhere next week.
Bug: 46579
Bug: 1495
Change-Id: Iac7ac4357dd80e8cdb238a6a207393f0712b3fe5
After Iaaf6cceb, MessageCache::get() goes through the fallback chain,
which is unwanted for conversion tables (for example, we don't want
zh-hans table for zh, where zh means "no conversion"). Since the only
needed feature is to fetch text from MediaWiki namespace (conversion
tables in PHP are stored somewhere else), it is now changed to use
MessageCache::getMsgFromNamespace() instead to avoid fallbacks.
Change-Id: I46e0be31c9c0fe0a6e4923fc1aff0fbbadbf1d67
* Removed spaces around array index
* Removed double spaces or added spaces to begin or end of function
calls, method signature, conditions or foreachs
* Added braces to one-line ifs
* Changed multi line conditions to one line conditions
* Realigned some arrays
Change-Id: Ia04d2a99d663b07101013c2d53b3b2e872fd9cc3
For example, find out which rule type should be applied for 5 items
in Arabic. The result would be 'few'.
This implementation should be non-disruptive and completely backwards
compatible (which is the main reason it isn't a lot simpler).
Change-Id: I3d72e4105f6244b0695116940e62a2ddef66eb66
Doxygen expects parameter types to come before the
parameter name in @param tags. Used a quick regex
to switch everything around where possible. This
only fixes cases where a primitve variable (or a
primitive followed by other types) is the variable
type. Other cases will need to be fixed manually.
Change-Id: Ic59fd20856eb0489d70f3469a56ebce0efb3db13
Added/removed spaces around logical/arithmetic operator
Reduced multiple empty lines to one empty line
Removed wrong tabs before comments at end of line
Removed too many spaces in assigments
Change-Id: I2bba4e72f9b5f88c53324d7b70e6042f1aad8f6b
The core function behind wfMessage() (MessageCache->get()) did not
apply the language fallback chain to on-wiki messages.
This patch has changed the behavior to iterate over all possible
on-wiki fallbacks (starting with the user's language) before
using the built-in language cache (CDB files). Previously we only looked
for the existence of an on-wiki message in the users's language.
Performance wise, using the 'ab' language ('ru', 'en' fallbacks)
MessageCache::get (Averaged over runs and calls)
New Code: ~8.5% TET (110us/call)
Old Code: ~6.5% TET ( 90us/call)
TET: Total Execution Time
Change-Id: Iaaf6ccebd8c40c9602748c58c3a5c73c29e7aa4d
Also make the IS NULL in upper case, looks better and sql reservered
words often written in upper case
Change-Id: I844ec37bbf3fb00d95a43dfd6f58db1e67724d53
Added/removed spaces after opening/before closing parentheses
Added a space after a comma
Removed unneeded parentheses in condition
Change-Id: I306091347ccaaf11dee0cdfda3019cb0c12be51b
Disable of MessageBlobStore clear
Reset $wgAutopromote (should be moved to a config change!!)
Disable setting of wgStyleSheetPath
Disable squid updates in HTMLCacaheUpdate invalidateTitles
Throttle page_touched
Add apc htcp packet numbers to SquidUpdate
Disable set names binary/utf8
Commment out searchindex table indexes
Was c532e81d583d3d0439fe76eea4d105d675461b56
Original revision Change-Id I42c4f859e55eb198f6c6841e582b3552aad7b31f
https://gerrit.wikimedia.org/r/#/c/7606
Change-Id: I5ec8dd53188e9e4128f99ceaff38ebf9dcf570bb
I suspect this is the primary cause we occasionally have
* Sidebar stuck in default values
* No gadgets at all
* Main page full of <int:custom-message> occurances
Change-Id: I811755d4c250800177c4ea9e509bf6e1d13443a0
* Added JobQueue::deduplicateRootJob() function which uses cache
records of the last time a "root" job was initiated for a task
in order to invalidate prior jobs for that task. For refreshLinks,
the "task" is basically "enqueueing the refresh jobs for title X".
* (bug 27914) Also added new Job::getDeduplicationFields() function
and made use of it with refreshLinks to exclude things like 'masterPos'
from duplicate job check comparisons for refreshLinks.
* (bug 27914) Always resolve refreshLinks2 jobs down to refreshLinks jobs.
For each affected pages, one of them will get their job popped
first, which will remove the duplicates for that page unless
one page is in a refreshLinks2 jobs and the other in refreshLinks.
* (bug 37731) Made LinksUpdate/HTMLCacheUpdate defer the large
backlinks query by doing it in an outer job.
* (bug 42065) HTMLCacheUpdate will no longer purge pages that were
already purged since the job was added.
Change-Id: I71b743e0a38e60a874ca856e80cb761bea06b689
* This way, we can actually get persistent cache hits for
the HTMLCacheUpdate queries rather than always hitting a DB.
* Also moved BacklinkCache under the /cache directory.
Change-Id: I0666ee575fb42675f1a7dd9cb52665f0a12a66a9
Callers often tend to end up calling getFileStat(), at least indirectly,
or in various successive function on the same path. This created RTTs
when the file didn't exist since negatives were not cached. This change
does the following:
* Cache definitive negatives (404s) in the process cache.
Nothing is cached on failure (like network problems).
* Ignore process cache entries after a brief time period
so long running scripts do not have overly stale entries.
Change-Id: I356bd9f48281e3c7e7a273778b2aca59c521a0c7
This was developed for translatewiki.net, which has but
millions of messages in MediaWiki namespace. To avoid
exploding the message cache, not all of them can be
loaded. Instead of logging what messages have been
requested, now it uses the fact that if the
message has not been customised in the
site language, there is most likely
no reason to load it in any other
language either.
Change-Id: I6dd81b3858acfd2b73332e46668d46015e99c748
* @licence -> @license
* Protects inline HTML by using double quotes, our inline comments uses
elements such as <h1> or <firstnameLastname@gmail.com>
* Commands in lowercase (@TODO -> @todo, @NOTE -> @note)
* removes @abstract and @static since doxygen detects them from PHP
code.
* various undocumented function parameters
* typos in parameters declarations
Change-Id: I62ad6fc124c355bf31acc780b9614a59cf79a421
Was accidentally broken in Ie38ae198, where the request URL was compared
against the final target title, not the title of the redirect. Also
tested squid purges of redirects, since that code presumably hasn't been
tested for a while, and committed my very advanced testing framework.
Change-Id: Ib2ffe8e109bcc4859e22df5470bddfdb09e67afa
Factor out duplicated code into the new ProcessCacheLRU. It is a fixed
size an per process cache which invalidate the least recently used cache
key.
Change-Id: Ib4475f21879ef6286ce2a28f248acd296fdbd45d
The content model is stored as a varbinary(32), the format
as varbinary(64).
If the standard model resp. format is used, null is written
to the database instead of the actual id, saving space.
Change-Id: I32659b49a9ad3cb8ecae9019562cff7de42b65f9
the queries for title and pageids are own queries created by the api,
which does not use the GenderCache, that can produce a query per row
Change-Id: I932f8d9d1cfa751dbb6f5237e2de325527d3ff53
Disable of MessageBlobStore clear
Reset $wgAutopromote (should be moved to a config change!!)
Disable setting of wgStyleSheetPath
Disable squid updates in HTMLCacaheUpdate invalidateTitles
Throttle page_touched
Add apc htcp packet numbers to SquidUpdate
Disable set names binary/utf8
Commment out searchindex table indexes
Was c532e81d583d3d0439fe76eea4d105d675461b56
Change-Id: I42c4f859e55eb198f6c6841e582b3552aad7b31f
LinkBatch can also give subpages to the GenderCache and therefor it is
easier to do it always in GenderCache, than in LinkBatch and Title
Add unit tests for GenderCache
Change-Id: Ia936ff8bb639a197b0b3a8e07c97a66edd57dd10
This reused the gender state of a user on a page. This is helpful for
special pages which shows the group name, because the each group name
used gender, which result in often use.
Change-Id: I8e816f54aaa100c3333e84e19299fd194323341d
This allows HTCP purges for different domains to be sent to different
multicast groups, based on regexes. Mark requested this so we could
separate the multicast groups for upload caches and text caches.
This code is UNTESTED, I'm mostly submitting this as a proof of concept
and to invite review by other core devs (specifically Tim).
Change-Id: Ie333a04131d6ca8394884ed1054f2baff55ab2d1
This has to be done in 3 places, because there are 3 public entry
points.
I originally submitted this to fight duplicates I thought I was seeing
in production, but it turns out I'm blind and the URLs weren't
duplicates after all. Nevertheless, preventing duplicate purges in the
SquidUpdate class is a good idea.
Change-Id: Idc21dd7d0b3b79572853b787fac746454d9178ea
* Tweaked filecache fallback in fileCachedPage() to try the raw title param. If the DB is down, we can get most views of titles with colons in them to work this way. Previously, it could fail on an interwiki lookup.
* Use default .cache extension for ResourceFileCache. No need for js/css extension, and makes extension sanity check in prune script simpler.
* Removed redundant setting of mExt in ObjectFileCache
* Added FileCacheBase::*MissesRecent() functions for counting cache misses from different visitors.
* Made ObjectFileCache more generic.
* Cleaned up FileCacheBase::checkCacheDirs().
* Added FileCacheBase::typeSubdirectory() function and overwrote in HTMLFileCache. Fixes r98405 invalidating all existing cache due to directory change.
* Simplified FileCacheBase::checkCacheDirs() a bit
ResourceLoader:
* Use ResourceFileCache to handle load() requests, if $wgUseFileCache. Only caches requests for default language and skins. Single modules requests are always cached, whereas others require a certain threshold of traffic.
* Added ResourceFileCache class (functionality was initially to be in ObjectFileCache).
* Rewrote class and split into three classes: a base class, and html cache and a more generic cache to be used later.
* The new classes now use RequestContext.
* Renamed fetchPageText() -> fetchText().
* Split out new saveText() function from saveToFileCache().
* Various other cleanups and fixes.
Also fixed backwards setting of $wgDisableCounters in rebuildFileCache.php.
This may be related to things failing on load from External Storage; however we have not yet been able to verify this.
Tweaks MessageCache::loadFromDB() and MessageCache::getMsgFromNamespace() to avoid storing empty cache entries when loading text fails.
When building initial cache if we get a failure we'll log and store a '!TOO BIG' message which requests on-demand load later.
If an on-demand load failures, we'll log and return the false through but won't update the cache with the bad value.
To enable the logging in production, set up a $wgDebugLogFiles entry for 'MessageCache'.
Note that MessageCache::loadFromDB() bypasses Revision's text entry memcaching and may cause a lot of ES fetches at once.
However any ES failures *should* already be logged in the 'ExternalStoreDB' log file.
$wgDeferredUpdateList[] = new HTMLCacheUpdate( $title, "sometable" );
I kept b/c with $wgDeferredUpdateList for now, but seeing as only 3 exts in svn use it (FileSearch, FlaggedRevs and WikiScripts), I'd like to deprecate it pretty soon :)
$wgContLang in CategoryPage was probably removed with the better directionality improvements.
$wgServer, $wgRequest in getFullUrl() unused since r94375
Other variables added in r95396 iwtransclusion merge.
Breaks unit tests as below, not going to be able to fix them before I disappear for the evening, so might aswell leave trunk clean
ArticleTablesTest testbug14404
Error:
ArticleTablesTest::testbug14404
Undefined offset: 0
/home/ci/cruisecontrol-bin-2.8.3/projects/mw/source/tests/phpunit/includes/ArticleTablesTest.php:31
/home/ci/cruisecontrol-bin-2.8.3/projects/mw/source/tests/phpunit/MediaWikiTestCase.php:60
/home/ci/cruisecontrol-bin-2.8.3/projects/mw/source/tests/phpunit/MediaWikiPHPUnitCommand.php:20
/home/ci/cruisecontrol-bin-2.8.3/projects/mw/source/tests/phpunit/phpunit.php:60
ParserTests testParserTest #552 - testParserTest with data set #551
Failure:
ParserTests::testParserTest with data set #551 ('RAW magic word', '{{RAW:QUERTY}}', '<p><a href="/index.php?title=Template:QUERTY&action=edit&redlink=1" class="new" title="Template:QUERTY (page does not exist)">Template:QUERTY</a>
</p>', '', '')
RAW magic word
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-<p><a href="/index.php?title=Template:QUERTY&action=edit&redlink=1" class="new" title="Template:QUERTY (page does not exist)">Template:QUERTY</a>
+<p><a href="/index.php?title=Template:RAW:QUERTY&action=edit&redlink=1" class="new" title="Template:RAW:QUERTY (page does not exist)">Template:RAW:QUERTY</a>
</p>
/home/ci/cruisecontrol-bin-2.8.3/projects/mw/source/tests/phpunit/includes/parser/NewParserTest.php:545
/home/ci/cruisecontrol-bin-2.8.3/projects/mw/source/tests/phpunit/MediaWikiTestCase.php:60
/home/ci/cruisecontrol-bin-2.8.3/projects/mw/source/tests/phpunit/MediaWikiPHPUnitCommand.php:20
/home/ci/cruisecontrol-bin-2.8.3/projects/mw/source/tests/phpunit/phpunit.php:60
** Tweaked addAutopromoteOnceGroups() calls for performance
** Some doc tweaks and fixes
* Added NS_SPECIAL short-circuit on $wgTitle for file cache and removed unnecessary "is null" check
* Pushed "$action != 'raw'" check into HTMLFileCache
* Removed useless return value from performRequest()
* Added type hint to performAction()