Commit graph

31 commits

Author SHA1 Message Date
Timo Tijhof
b7b84d55d4 resourceloader: Embed 'mediawiki' directly in startup response
Embed the essential files to define mw.loader directly as part of
the startup module.

* This means the internal 'mediawiki' module no longer exists.
  This is safe to remove because:
  1) While registered server-side for loading from startup.js, a PHPUnit
     structure test disallowed being specified as a dependency.
  2) Anything that attempted to load it client-side failed because the
     module was marked in the registry as 'raw', thereby excluding it
     from the data sent to the client-side. As such, it was seen as an
     unknown module that the client refused to fetch from the server.

* Deprecate getStartupModules() and getLegacyModules().
  These are no longer needed. There are no known callers anywhere in
  Wikimedia Git or elsewhere indexed by Codesearch, but easy enough
  to leave as no-op for one release.

* Remove ResourceLoaderRawFileModule class.
  No longer needed. Was created as a hack specifically for the 'mediawiki'
  module so that it would not leak global variables in debug mode.
  It has no usage anywhere in Wikimedia Git, nor elsewhere in Codesearch.
  Remove without deprecation given this was meant to be a 'private' class.

* Introduce (private) getBaseModules(). Previously, this list only existed
  locally in getStartupModulesUrl() by merging getStartupModules() and
  getLegacyModules(). This value was factored out into its own method.

* Make getStartupModulesUrl() private and rename to getBaseModulesUrl().
  It is only used internally to export the 'baseModulesUri' value.
  Its name was already confusing before, but it would've been even more
  confusing now given it doesn't even call getStartupModules() any more.

Bug: T192623
Change-Id: I14ba282d7b65e99ca54b7c2f77ba6e1adaddd11c
2018-06-27 17:06:35 +00:00
Kunal Mehta
4acb7ed51c Add @coversNothing to tests that don't cover specific PHP classes
Change-Id: Idbd364561bc28547e9fac20d7a80b9a44edf14a9
2018-06-12 13:27:40 -07:00
mainframe98
70e92cdad5 Fix additional usage of incorrect case
Courtesy of the PhpStorm inspection Case mismatch in method call or
class usage.

Bug: T166759
Change-Id: I27c53658b99048fa0dd8f9d6ef1398620386e1cc
2017-12-15 11:58:11 +01:00
Timo Tijhof
d4a17a10a5 phpunit: Include all raw modules in detection of illegal dependencies
* Use getStartupModules() instead of hardcoding these two module names.
* Also collect any other module that is registered with raw=>true.

Change-Id: I5f75cc8f99b90f58d76b7e87f068f50f9f608ed0
2017-10-03 18:13:20 +01:00
Thiemo Mättig
00c3f09566 Remove empty lines from PHP and JavaScript comment blocks
This is a pure documentation change. It mostly removes empty lines from
comments (and entirely empty comments), as well as adds a few missing
documentation blocks and fixes a minor mistake. I hope it's ok to have
this in one patch. I can split it, please tell me.

Change-Id: I9668338602ac77b903ab6b02ff56bd52743c37c4
2016-12-09 09:01:06 +00:00
Leszek Manicki
d5a12f954b Remove not used variables in ResourcesTest
Change-Id: I45f531e66545175c689b8f6a62a5c3ed62ea5a9a
2016-11-05 20:28:32 +00:00
Timo Tijhof
39a00e2ea0 resourceloader: Add structure unit test to confirm messages exist
Bug: T129976
Change-Id: I5333523efe3e7b9191e871d67d9eb650002c7784
2016-08-17 20:07:43 +00:00
Ori Livneh
dfd046412f resourceloader: Replace SHA1 with 32-bit FNV-1 as hash function
SHA-1 is not secure enough to be used as a cryptographic hash function, and its
implementation in JavaScript is too long and too slow for it to be a good
general-purpose hash function. And we currently throw away most of the work:
SHA-1 produces 160-bit hash values, of which we keep 48.

Although the JavaScript implementation is not exported, SHA-1 is a well-known
hash function, and I'm willing to bet that sooner or later someone will move to
make it accessible to other modules, at which point usage will start to spread.

For ResourceLoader, the qualities we're looking for in a hash function are:

* Already implemented in PHP
* Easy to implement in JavaScript
* Fast
* Collision-resistant

The requirement that hashes be cheap to compute in JavaScript narrows the field
to 32-bit hash functions, because in JavaScript bitwise operators treat their
operands as 32 bits, and arithmetic uses double-precision floats, which have a
total precision of 53 bits. It's possible to work around these limitations, but
it's a lot of extra work.

The best match I found is the 32-bit variant of FNV-1, which is available in
PHP as of version 5.4 (as 'fnv1a32'). The fnv132 JavaScript function is
around ten times faster and eight times shorter than sha1.

Change-Id: I1e4fb08d17948538d96f241b2464d594fdc14578
2016-07-05 21:14:03 +00:00
Timo Tijhof
98911418c2 CSSMin: Remove file-existance filter in getLocalFileReferences()
Follows-up 8f5cd11d82.

The old getLocalFileReferences() method is no longer used anywhere.
Remove it and rename getAllLocalFileReferences back to it.

Change-Id: I864258aad128ba9b54464c7bc854543f2937f977
2016-03-03 00:16:13 +00:00
Kunal Mehta
6e9b4f0e9c Convert all array() syntax to []
Per wikitech-l consensus:
 https://lists.wikimedia.org/pipermail/wikitech-l/2016-February/084821.html

Notes:
* Disabled CallTimePassByReference due to false positives (T127163)

Change-Id: I2c8ce713ce6600a0bb7bf67537c87044c7a45c4b
2016-02-17 01:33:00 -08:00
Timo Tijhof
a0809dfa5a resourceloader: Remove 'loaderScripts' option from FileModule
Not used in any of our public repositories.

Bug: T65240
Change-Id: I1e9f741c3ef0f922129ecd10039228b58565bf62
2015-10-28 02:53:16 +00:00
Amir E. Aharoni
9f5c3c1520 Make lines short to pass phpcs in ResourcesTest.php
Bug: T102614
Change-Id: I3c5df376dbfc6cbb114b59202ee9d68d4d850746
2015-09-30 15:40:39 +00:00
Ori Livneh
3f1e9fa268 resourceloader: Tidy up RL to simplify ResourceLoaderEditToolbarModule
* Remove ResourceLoaderFileModule::getLessCompiler(). There is no reason for a
  module to need to get a compiler in a different manner than
  ResourceLoader::getLessCompiler().
* Add ResourceLoaderModule::getLessVars(). This method provides a means for
  subclasses to easily inject custom LESS variables. The default implementation
  simply returns an empty array.
* Make the $context parameter for ResourceLoaderFileModule::readStyleFiles()
  non-optional (via graceful deprecation). The only callers I found were either
  already calling it with a ResourceLoader context, or had a perfectly usable
  ResourceLoaderContext in local scope.
* Make ResourceLoaderFileModule::{readStyleFile,getLessCompiler} require a
  context. These methods are protected, so I didn't bother with a deprecation.
* Call ksort() on the LESS variables array in the only place it matters -- when
  hashing its serialized representation to construct a cache lookup key. This
  relieves getLessVars() subclasses from having to remember to re-sort the
  variables array if they modify it.
* These changes make it possible to substantially simplify
  ResourceLoaderEditToolbarModule, because the only thing it needs to do now is
  implement its own getLessVars() method.
* This also allows it to be versioned like any other ResourceLoaderFileModule,
  rather than having to use enableModuleContentVersion().

Change-Id: Ic3eab71691e502bfe19bdf4eb6f82cc679a7782f
2015-09-28 12:18:12 -07:00
Elliott Eggleston
c737e48d7f Strip comments before gathering url(...) refs in CSS
Change I5a3cdeb7d53485f161ccf8133e76850cdf5b4579 introduced tests
for existence of all local files referenced in CSS.  It's currently
failing changes even when the referenced files have been commented
out.  This change ensures that commented-out files are not included
in the testing list.

Change-Id: I2ad74c13a9cf36e96a7d7451bf229856bcd18422
2015-09-19 16:10:53 -04:00
Bartosz Dziewoński
8f5cd11d82 ResourcesTest: Detect missing files in url(...) expressions
The way this is implemented is really dirty... but it found us
a few pre-existing bugs already (T111518, T111519, T111771).
I think it might be worth it.

* CSSMin: Add new method getAllLocalFileReferences() which skips the
  file_exists() check.
* ResourceLoaderModule: Make use of it to track missing files too.
* ResourcesTest: Verify that the missing files are missing.

Change-Id: I5a3cdeb7d53485f161ccf8133e76850cdf5b4579
2015-09-16 00:27:23 +00:00
Andrew Green
1dd6cfdf50 resourceloader: Pass $context to getDependencies() in PHPUnit tests
Send the ResourceLoaderContext param in calls to getDependencies() in
PHPUnit tests for ResourceLoader. (This so an RL module in CentralNotice
can emit a warning when that parameter is not provided, and still pass
tests. Sending the parameter here will also be necessary when the parameter
is made non-optional in the future.)

Change-Id: I6033e03e2d8a46b4bd7f7a04ae13fd9f387ebd10
2015-06-24 20:28:07 +00:00
Timo Tijhof
f37cee996e resourceloader: Replace timestamp system with version hashing
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
2015-05-19 22:28:17 +00:00
Timo Tijhof
b4bac102b6 tests: Clean up file headers
* Remove redundant @licence/@license from test suite files.
  They already have full licence headers. And @licence raises a
  warning in Doxygen.

* Fix weird messes of comments inside comments and other things.

Change-Id: I38da8ca76330f72b8dc22b0ecf1ea69d5ea55ede
2015-04-01 00:17:12 +01:00
umherirrender
0be527177f Skip missed dependencies in ResourcesTest::testUnsatisfiableDependencies
When a dependency is missing the test
ResourcesTest::testUnsatisfiableDependencies gives a error because of
Undefined index and stops further checks. Skip this situation because
the existing test ResourcesTest::testMissingDependencies already gives a
failure with a better explanation in this situation.

Change-Id: I71a88551df67d52ea96bf7283b5de892692f9336
2015-02-21 23:08:00 +00:00
umherirrender
b0cfcd0fcb Add missing @return and @param to doc blocks
Change-Id: I9d99ba1968ed8f97624d957754c8847dfe1b41da
2014-08-27 21:57:45 +02:00
Kunal Mehta
523ba0cf8b ResourcesTest: Add variable type annotations
Change-Id: I07ec986830dcec739b0553395b9a220b44bba77d
2014-08-22 00:32:09 +02:00
Bartosz Dziewoński
3971d0646c resourceloader: Allow skins to provide additional styles for any module
The newly introduced $wgResourceModuleSkinStyles global enables skins to
provide additional stylesheets to existing ResourceLoader module.

This both makes it easier (or at all possible) to override default
styles and lowers the style footprint by making it possible not to
load styles unused on most pages.

----

Example:

Use the file 'foo-styles.css' for the 'mediawiki.foo' module when using
the MySkin skin:

  $wgResourceModuleSkinStyles['myskin'] = array(
    'mediawiki.foo' => 'foo-styles.css',
    'remoteSkinPath' => 'MySkin',
    'localBasePath' => __DIR__,
  );

For detailed documentation, see the doc comment in DefaultSettings.php.
For a practical usage example, see Vector.php.

----

Implementation notes:

* The values defined in $wgResourceModuleSkinStyles are embedded into
  the modules as late as possible (in ResourceLoader::register()).
* Only plain file modules are supported, setting module skin styles
  for other module types has no effect.
* ResourceLoader and ResourceLoaderFileModule now support loading
  files from arbitrary paths to make this possible, defined using
  ResourceLoaderFilePath objects.
  * This required some adjustments in seemingly unrelated places for
    code which didn't handle the paths fully correctly before.
* ResourceLoader and ResourceLoaderFileModule are now a bit more
  tightly coupled than before :(
* Included a tiny example change for the Vector skin, a lot more of
  similar cleanup is possible and planned for the future.
* Many of the non-essential mediawiki.* modules defined in
  Resources.php should be using `'skinStyles' => array( 'default' => … )`
  instead of `'styles' => …` to allow more customizations, this is
  also planned for the future after auditing which ones would actually
  benefit from this.

Change-Id: Ica4ff9696b490e35f60288d7ce1295766c427e87
2014-07-29 00:53:41 +02:00
jenkins-bot
66d3eb56af Merge "ResourceLoader: Test that all module dependencies are satisfiable" 2014-07-27 21:21:41 +00:00
umherirrender
4ee680a8b3 Fixed spacing
- Removed spaces after not operator (!)
- Removed spaces inside array index
- use tab as indent instead of spaces
- Add newline at end of file
- Removed spaces after casts

Change-Id: I9ba17c4385fcb43d38998d45f89cf42952bc791b
2014-07-24 11:53:04 +02:00
Bartosz Dziewoński
278e58bd66 ResourceLoader: Test that all module dependencies are satisfiable
Whenever module A depends on module B, module B must exist.

Whenever module A depends on module B, the possible targets of A must
be a subset of targets of module B.

Bug: 64513
Change-Id: I9de291d20d08df2813eb55be9a1f7e5efd907d6f
2014-06-29 20:28:05 +02:00
Siebrand Mazeland
4ede8c2e9d Pass phpcs-strict on some test files (11/11)
Woo!

Change-Id: I9fc116dfdf18c2772d047adb5bb14535d0bd39ed
2014-04-24 13:51:05 -07:00
Timo Tijhof
330444a4f9 resourceloader: Add unit test to ensure absence of illegal dependencies
Loading these can cause side-effects and is just redundant in
general.

Change-Id: Ic8b4ed45d4d42172a456cc5eaf314c41e4e6fd18
2014-04-08 17:10:34 -07:00
umherirrender
5dbfd5bf80 Fixed spacing
- Removed trailing spaces in comments
- Removed multiple empty lines
- Removed space after object operator

Change-Id: I9fd3256ab490c7cd2034de3fd94e6be6e6d6d8f2
2013-11-21 18:52:25 +00:00
Timo Tijhof
4eb60da520 ResourcesTest: Assert no @media is used inside 'media'-specified resources
Change-Id: I85d652da7c1713d46a5085b9fde7fb24045348be
2013-11-03 23:08:41 +00:00
Antoine Musso
3c8674bdff tests: remove date from @author docs statements
phpunit interprets '@author' documentation statements to generate group.
Appending the year to the author name created duplicates entry:

 $ php phpunit.php --list-groups|grep Antoine
 Antoine Musso
 Antoine Musso, 2012
 $

Removing the date fix the duplication. I have also inserted
corresponding '@copyright' statements.

Change-Id: I65b19adb59c4894314ce68a0c815c5d3e4c30df0
2013-10-03 10:48:12 +02:00
Antoine Musso
67b935edb4 tests: resources tests were not being run
The ResourcesTest class under ./resources/ were not registered anywhere.
This patch move it under the `structure` testsuite and phaseout the, now
empty, `resources` directory.

Change-Id: I53410e1dc83263c4c541f4dc278a9e616265d7b1
2013-05-30 17:17:46 +02:00
Renamed from tests/phpunit/resources/ResourcesTest.php (Browse further)