Commit graph

173 commits

Author SHA1 Message Date
Tim Starling
e582572622 Improve ObjectCache integration tests
* Add BagOStuffTest subclasses for all core BagOStuff subclasses,
  replacing PHPUNIT_USE_BAGOSTUFF, as suggested in a todo comment.
* Add config $wgEnableRemoteBagOStuffTests which causes all tests
  enabled by $wgObjectCache to execute, which means that the memcached
  tests are executed by default.

I have verified all except RESTBagOStuff and WinCacheBagOStuff. The
memcached tests fail against memcached 1.5.x but pass against memcached
1.6.x.

Bug: T90875
Change-Id: Id74b5226669f8cb857f859fbc35bc58ab001e873
2022-02-11 10:20:33 +11:00
Aaron Schulz
8f6d05e62c objectcache: add watchErrors() to BagOStuff/WANObjectCache
The new style of checking for the last error during a section of
calls is more robust since it allows nesting of callers. Typically,
an external caller will want to watch a section of code that will
involve zero or more internally watched sections. Errors that are
seen internally (leading to a failing response) should also be
visible externally.

Replace internal BagOStuff clearLastError() calls.

Replace WANObjectCache clearLastError() calls. Such a class should not
clear the error codes since the class is effectively "internal". Callers
that are more meaningfully "external" might want to check the errors.

Cleanup "last" error handling for proxy backends.

Change-Id: I281817a85602967c0ec2bdd23a5d8be101680b64
2021-11-10 00:38:27 +00:00
Aaron Schulz
2947b099db objectcache: make use of new modtoken field in SqlBagOStuff (ii)
Add a multi-primary mode option that supports MySQL DB setups
that use circular replication with STATEMENT formatted binlogs.
The `modtoken` column is only used when multi-primary mode is
explicitly enabled in configuration. The column is used by write
queries to determine the "winning" version of keys, with the goal
of approximating "Last-Write-Wins" eventual consistency.

Writes with different timestamps can be handled by picking the
one with the highest timestamp as the "winner". Writes with the
same timestamp, from different primary DBs, can be handled by
picking the one from the primary DB with the highest server_id.
Writes with the same token timestamp from the same primary DB can
be handled by picking the last write to appear in the binlog.
The delete() operation uses tombstones in multi-primary mode,
since there must be a key version to actually compare with the
versions from other operations.

Also:
* Remove "LOCK IN SHARE MODE" that was made obsolete by the
  CONN_TRX_AUTOCOMMIT flag. For the SQLite transaction case,
  it is serializable anyway.
* Simplified handleWriteError() to match handleReadError()
  and merged them into handleDBError().

Changes from d56a686f83:
* Keep using replace() for set() in non-multi-primary mode.
* Fix old encoding issues when incrementing keys with postgres.

Bug: T274174
Change-Id: I25b1278586f99fdace8f2a081f6f460f734e5d83
2021-08-20 19:23:39 -07:00
jenkins-bot
81c6f56c43 Merge "Revert "objectcache: make use of new modtoken field in SqlBagOStuff"" 2021-08-17 16:30:31 +00:00
Ladsgroup
0bd5cf3910 Revert "objectcache: make use of new modtoken field in SqlBagOStuff"
This reverts commit d56a686f83.

Reason for revert: T288998#7287717

Bug: T288998
Change-Id: Ia05b00a345335fe8bdd6041323c3abfa79ded169
2021-08-17 15:29:32 +00:00
jenkins-bot
372f4218b9 Merge "objectcache: BagOStuff::genericKeyFromComponents() empty component fix" 2021-08-12 01:45:25 +00:00
Aaron Schulz
f27367af09 objectcache: BagOStuff::genericKeyFromComponents() empty component fix
Empty leading components should still be colon separated. Although the
keyspace and collection should never be empty strings, it does not hurt
to handle that case anyway for safety.

Change-Id: Ic89acaf1fe5c34e58323b2913a9a26f973868590
2021-08-11 17:57:59 -07:00
Aaron Schulz
d56a686f83 objectcache: make use of new modtoken field in SqlBagOStuff
Add a multi-primary mode option that supports MySQL DB setups
that use circular replication with STATEMENT formatted binlogs.
The `modtoken` column is only used when multi-primary mode is
explicitly enabled in configuration. The column is used by write
queries to determine the "winning" version of keys, with the goal
of approximating "Last-Write-Wins" eventual consistency.

Writes with different timestamps can be handled by picking the
one with the highest timestamp as the "winner". Writes with the
same timestamp, from different primary DBs, can be handled by
picking the one from the primary DB with the highest server_id.
Writes with the same token timestamp from the same primary DB can
be handled by picking the last write to appear in the binlog.
The delete() operation uses tombstones in multi-primary mode,
since there must be a key version to actually compare with the
versions from other operations.

Also:
* Remove "LOCK IN SHARE MODE" that was made obsolete by the
  CONN_TRX_AUTOCOMMIT flag. For the SQLite transaction case,
  it is serializable anyway.
* Simplified handleWriteError() to match handleReadError()
  and merged them into handleDBError().

Bug: T274174
Change-Id: Icc5eff9a032dd3403b5718058f20e38f8ea84af5
2021-08-05 02:33:00 +01:00
libraryupgrader
5357695270 build: Updating dependencies
composer:
* mediawiki/mediawiki-codesniffer: 36.0.0 → 37.0.0
  The following sniffs now pass and were enabled:
  * Generic.ControlStructures.InlineControlStructure
  * MediaWiki.PHPUnit.AssertCount.NotUsed

npm:
* svgo: 2.3.0 → 2.3.1
  * https://npmjs.com/advisories/1754 (CVE-2021-33587)

Change-Id: I2a9bbee2fecbf7259876d335f565ece4b3622426
2021-07-22 03:36:05 +00:00
James D. Forrester
df5eb22f83 Replace uses of DB_MASTER with DB_PRIMARY
Just an auto-replace from codesniffer for now.

Change-Id: I5240dc9ac5929d291b0ef1c743ea2bfd3f428266
2021-04-29 09:24:31 -07:00
Daimona Eaytoy
535d7abf59 phpunit: Mass-replace setMethods with onlyMethods and adjust
Ended up using
  grep -Prl '\->setMethods\(' . | xargs sed -r -i 's/setMethods\(/onlyMethods\(/g'

special-casing setMethods( null ) -> onlyMethods( [] )

and then manual fix of failing test (from PS2 onwards).

Bug: T278010
Change-Id: I012dca7ae774bb430c1c44d50991ba0b633353f1
2021-04-16 20:15:00 +02:00
Umherirrender
a1de8b8700 Tests: Mark more more closures as static
Result of a new sniff I25a17fb22b6b669e817317a0f45051ae9c608208

Bug: T274036
Change-Id: I695873737167a75f0d94901fa40383a33984ca55
2021-02-09 02:55:57 +00:00
DannyS712
6a93b0ca93 More misc test cleanup
* parent::setUp() should be first, and ::tearDown()
  should be last
* Move tests that directly extend PHPUnit\Framework\TestCase
  to /unit

Change-Id: I1172855c58f4f52a8f624e6d596ec43beb8c93ff
2020-12-24 00:52:06 +00:00
Aaron Schulz
5c335f9d77 objectcache: make BagOStuff key encoding more consistent
Add "generic" key methods for quickly deriving keys from
key component lists in a bijective manor. This is useful
for BagOStuff classes that wrap other BagOStuff instances
or for parsing keys to get stats.

Make the proxy BagOStuff classes (ReplicatedBagOStuff,
MultiWriteBagOStuff, CachedBagOStuff) use "generic" keys
so that they can convert to appropriate keys when making
backing cache instance method calls.

Make EmptyBagOStuff, HashBagOStuff, APCUBagOStuff,
RedisBagOStuff, and RESTBagOStuff use "generic" keys rather
than those of MediumSpecificBagOStuff::makeKeyInternal().
This lets proxy BagOStuff classes bypass key conversions
when used with instances of these classes as backing stores.

Also:
* Fix missing incr(), incrWithInit(), and decr() return
  values in MultiWriteBagOStuff.
* Make MultiWriteBagOfStuff, ReplicatedBagOStuff, and
  CachedBagOStuff use similar backend method forwarding
  styles by using a new BagOStuff method.
* Improved various related bits of documentation.

Bug: T250239
Bug: T235705
Change-Id: I1eb897c2cea3f5b756dd1e3c457b7cbd817599f5
2020-12-02 20:20:42 -08:00
Aaron Schulz
3f64eca5a4 objectcache: fix WANCache getWithSetCallback() when TTL < "lowTTL"
Previously, the refresh probability ramp-up logic assumed that
keys were always assigned logical TTLs >= "lowTTL". Thus, if a
key was saved with a TTL of 3 seconds and "lowTTL" was 10 seconds,
then the probability of a refresh at t=0 seconds would incorrectly
equal the value it should have at t=7.

Also:
* Use class constants for key metadata array keys. This makes it
  easy to track the usage of options and is less prone to typos.
* Improve some documentation slightly.

Bug: T264787
Change-Id: I7267e8639617fb8dc0850530465ff9d1b899b592
2020-11-10 17:49:32 -08:00
daniel
d75b45ee2f objectcache: Add QoS flags to HashBagOStuff
Change-Id: I571c860ef9dd32a1eb374d59738f6e9e74b19fc2
2020-09-17 01:25:29 +00:00
daniel
f50240fe76 User: enforce pingLimiter() expiry time
This makes User::pingLimiter() include the expiry time in the payload of
the cache key that holds the current count. This allows us to ignore
stale counts.

Until now, we have been relying on the cache implementation to expire
the relevant keys in time. This however seems to fail sometimes.

Bug: T246991
Change-Id: Ifa3c558b4449f1ca133d0064781f26ac1bf59425
2020-09-03 15:57:01 +00:00
addshore
959bc315f2 MediaWikiTestCase to MediaWikiIntegrationTestCase
The name change happened some time ago, and I think its
about time to start using the name name!
(Done with a find and replace)

My personal motivation for doing this is that I have started
trying out vscode as an IDE for mediawiki development, and
right now it doesn't appear to handle php aliases very well
or at all.

Change-Id: I412235d91ae26e4c1c6a62e0dbb7e7cf3c5ed4a6
2020-06-30 17:02:22 +01:00
Thiemo Kreuz
5f3a92385b Fix visibility of setUp/tearDown
Change-Id: I636be48eb9f713680abac35d46091f7b49374696
2020-06-16 21:02:05 +02:00
Aaron Schulz
55d147e4bb objectcache: Split out BagOStuffTestBase class for easier subclassing
Create a simple APCUBagOStuff subclass and also fix
APCUBagOStuff::incrWithInit() default $init value.

Change-Id: If84963fe7dcfedd6edebfb8785235263e0868ece
2020-06-13 20:15:23 +00:00
Daimona Eaytoy
2b37cfaf18 build: Bump mediawiki-codesniffer to 31.0.0
Done with `composer fix` and suppressing the rest (i.e. sniffs for
global variables, which for core should be suppressed anyway).

Additionally, add `-p` to `phpcbf`, as otherwise it just seems stuck.

Change-Id: Ide8d6cdd083655891b6d654e78440fbda81ab2bc
2020-05-30 14:56:28 +00:00
Reedy
a8b006426e Fix tests/ PSR12.Properties.ConstantVisibility.NotFound
Change-Id: I0beed1a35e046705fb84c9d1f63cf92afd009bb4
2020-05-16 04:30:21 +01:00
Aaron Schulz
c95c6f7470 objectcache: add "non-global" mode to WANObjectCache "coalesceKeys"
This makes it easier to rollout one keyspace/project at a time even
if some keys are shared and receive purges. The shared keys can all
be done as the last step.

Also, simplify getMulti() to no longer need extractBaseKey().
Make the "warm up cache" logic a bit easier to follow and less
likely to copy values around.

Change-Id: I8b602ddf5dd1feaada45fb0af202c5603836a8dd
2020-05-08 17:01:31 +00:00
Aaron Schulz
9ec57d7e5b objectcache: make WANObjectCache::set() handle very slow regeneration
If a key always takes a very long time to regenerate, is popular,
and does not use lockTSE, it still needs to be cacheable. Since a
value cannot be more up-to-date than the time it takes to regenerate
it, take the "lower the TTL" approach for these cases. Use "walltime"
to narrow down the "reject the set()" case based on regeneration time.
This is already provided by getWithSetCallback() automatically.

Bug: T244877
Change-Id: Id43fb02738b28dad3bc922057efb7eee0272d0e1
2020-04-14 22:53:38 +00:00
Thiemo Kreuz
e1dd371e11 Make use of PHPUnit's assertCount feature where possible
… and avoid assertEmpty() on arrays, in favor of a much more strict
assertSame( [] ).

Change-Id: I20266b0b1fc38a3a87666ba1b0793cb2b37d94a9
2020-03-02 15:58:41 +00:00
Aaron Schulz
b9b3f366bb objectcache: fix "coalesceKeys" option name in WANObjectCache
Follow-up to 85bc62c5a8

Fix related unit tests that otherwise break as a result

Change-Id: I28b3a1537d319c68a7c12c578e1acfb916f3ec99
2020-02-13 03:17:34 +00:00
Aaron Schulz
85bc62c5a8 objectcache: add "coalesceKeys" option to WANObjectCache for key grouping
This is useful for grouping related keys on the same servers to reduce
the need for cache server connections and availability. A cache key that
uses "lockTSE" can already involve accessing several keys during the
read/write cache-aside paths:
a) The value key itself
b) The check key (named after the main key, a common pattern)
c) The mutex key (used if the value looks stale)
d) The cool-off key (used if regeneration took a while)

Any problems accessing the first two could cause extra value regenerations.
Problems with the mutex key could lead to stampedes due to threads assuming
another thread was regerating a soon-to-expire value when, in fact, none was.
A similar problem could happen with cool-off keys, with threads assuming
that another saved the newly regenerated value when, in fact, none did.

The use of hash stops puts the tiny related keys on the same server as the
main cache key that they serve. This is only for hash-based routing, and not
route prefix routing (e.g. All*Route still sends the key to multiple child
routes, but the PoolRoute/HashRoute function will hash differently).

The option is not enabled by default yet.

Change-Id: I37e92a88f356ef1e2a2b7728263040e2f6f09a13
2020-02-06 20:27:08 +00:00
jenkins-bot
51280df815 Merge "objectcache: fix cache pollution in WANObectCache Multi* methods" 2020-01-30 18:17:03 +00:00
Aaron Schulz
527fd0109f objectcache: fix cache pollution in WANObectCache Multi* methods
This was triggered by bad reference handling during preemptive refreshes

Bug: T235188
Change-Id: I239a3e1922f478c74c94d8d2debff28f525c7c31
2020-01-29 21:08:39 +00:00
jenkins-bot
0a46bef2db Merge "objectcache: fix storage of null values in WANObjectCache" 2020-01-29 04:14:20 +00:00
Aaron Schulz
4fb5210b62 objectcache: fix storage of null values in WANObjectCache
Bug: T234583
Change-Id: I38a531b9a0acb95d7884519f3381b48cd9d8faa0
2020-01-24 22:49:26 +00:00
James D. Forrester
5e9fca47b9 Coding style: Auto-fix MediaWiki.Usage.PHPUnit*
Change-Id: I86fc55a4fc8ceafe368692173211bbcd6d8581d7
2020-01-10 10:17:12 +00:00
jenkins-bot
f73d62d47d Merge "Add more logging to getWithSetCallback()" 2019-12-20 00:36:31 +00:00
Daimona Eaytoy
e501bb3b50 Manual fix of the remaining assertInternalType & Co.
Bug: T192167
Change-Id: I3b8176745f49b1d4bfe6f36978b7879d546f68a9
2019-12-15 00:20:10 +00:00
Daimona Eaytoy
7c9e3db1e6 Fixes for PHPUnit 8 compatibility
Bug: T192167
Change-Id: Ic14f5debc53e55d67146dc96279d26dfd52b4000
2019-12-10 17:02:06 +00:00
Tim Starling
29e33aa50a Fix random WANObjectCacheTest failures
We're observing WANObjectCacheTest fail sometimes, possibly due to a
1/825 chance of a cache key being counted as "popular" combined with an
mt_srand() call making this more likely. I tweaked the options to
getWithSetCallback() to avoid the affected mt_rand() call altogether.

I also added a lowTTL option to another getWithSetCallback() call,
eliminating a condition with a 3% chance. It didn't appear to matter
which branch the test took, but I'd rather avoid non-deterministic
behaviour.

There are a few remaining coin tosses being logged, but they all occur
with a chance of less than 10^-5.

Bug: T238197
Change-Id: Iadd3dc00d44b8490210fec97fe1f49236326300f
2019-11-20 05:00:48 +00:00
Tim Starling
24812e4096 Add more logging to getWithSetCallback()
To help isolate the referenced bug, which is a sporadic test failure
in testGetWithSetCallback().

Bug: T238197
Change-Id: If35d60340c804b6bfe1e9ddfcf53c76373c794b1
2019-11-18 16:32:47 +11:00
Max Semenik
48a323f702 tests: Add explicit return type void to setUp() and tearDown()
Bug: T192167
Depends-On: I581e54278ac5da3f4e399e33f2c7ad468bae6b43
Change-Id: I3a21fb55db76bac51afdd399cf40ed0760e4f343
2019-10-30 14:31:22 -07:00
James D. Forrester
83d76f4cb5 phpcs: Enable MediaWiki.Commenting.PhpunitAnnotations.ForbiddenExpectedException* and make pass
Change-Id: I63f97497714a32236268be6965c5e181dade6c58
2019-10-14 12:48:48 -07:00
Umherirrender
5bd311b1a2 Add public as visibility in tests folder
Add public, protected or private to function missing a visibility
Enable the tests folder for the phpcs sniff

Change-Id: Ibefce76ea9984c47e08c94889ea2eafca7565e2c
2019-10-10 21:55:37 +02:00
Timo Tijhof
28c470adc7 objectcache: Stricter assertions for WANObjectCache tests
Use the stricter comparisons from assertSame instead of
assertEquals.

In some cases this revealed a test that was asserting a value
different from the one actually returned:

* testSetAndGet:
  The test failed with the test case (null, 3), where it tries
  to store the value `null`, but gets back `false`, which is wrong.
  This appears to be a genuine bug, filed as T234583.

Change-Id: Ic3dcc7fa2e8749b0f2d68917a8ac728dda26b6ca
2019-10-06 02:10:24 +00:00
Max Semenik
bc3878e33a Begin cleaning up PHPUnit 4 code from tests
This process will be broken up into several parts for reviewability.

Bug: T192167
Change-Id: Ie415fd3308384a5ca2b3de24ba037785f8a3a714
2019-10-04 14:19:05 -07:00
Thiemo Kreuz
e4272518f7 tests: Replace PHPUnit's loose assertEquals(false) with assertFalse()
assertEquals( false, … ) still succeeds when the actual value is 0, null,
an empty string, even an empty array. All these should be reported as a
failure, I would argue.

Note this patch previously also touched assertSame( false ). I reverted
these. The only benefit would have been consistency within this codebase,
but there is no strict reason to prefer one over the other. assertFalse()
and assertSame( false ) are functionally identical.

Change-Id: Ic5f1c7d504e7249002d3184520012e03313137b4
2019-10-04 00:30:36 +00:00
Daimona Eaytoy
c12b32c9a3 HHVM removal: Kill HHVM_VERSION checks in PHPUnit tests
Change-Id: I1d18b2d6956d326e5f9e50cd01ce2bb683a5b653
2019-10-03 15:35:21 +00:00
Thiemo Kreuz
cff596804a tests: Replace assertions on count() == 0 with strict === []
The benefit of using count() is that the test would still succeed if
the return vfalue is not an array, but an iterable object. It seems
this is not needed.

Change-Id: I23529f6990aebe0cce86e236a21820fe74993204
2019-09-30 16:20:34 +02:00
jenkins-bot
864c4df8b9 Merge "tests: Replace PHPUnit's loose assertEquals(null) with assertNull()" 2019-09-27 22:43:09 +00:00
Thiemo Kreuz
c2211946f7 tests: Replace PHPUnit's loose assertEquals(null) with assertNull()
assertEquals( null, … ) still succeeds when the actual value is 0, false,
an empty string, even an empty array. All these should be reported as a
failure, I would argue.

Note this patch previously also touched assertSame( null ). I reverted
these. The only benefit would have been consistency within this codebase,
but there is no strict reason to prefer one over the other. assertNull()
and assertSame( null ) are functionally identical.

Change-Id: I92102e833a8bc6af90b9516826abf111e2b79aac
2019-09-27 19:15:38 +00:00
Aaron Schulz
223b7a3717 objectcache: fully respect "pcTTL" in WANObjectCache instead of using INF when >= 0
This was broken since 611e2d5596

Change-Id: I612eaf211ff698d5ab1c911aa58195b7bc44f00c
2019-09-24 02:56:39 -07:00
jenkins-bot
095c50ade1 Merge "tests: Prefer assertSame() when comparing the integer 0" 2019-09-20 15:33:02 +00:00
Thiemo Kreuz
32a429e8c4 tests: Prefer assertSame() when comparing the integer 0
assertSame() is guaranteed to not do any type conversion. This can be
critical when acciden tially comparing, for example, 0 to 0.0.

Change-Id: Iffcc9bda69573623ba14af655dcd697d0fcce525
2019-09-19 15:35:23 +00:00