%PDF- %PDF-
Direktori : /www/varak.net/wiki.varak.net/extensions/CirrusSearch/tests/unit/ |
Current File : /www/varak.net/wiki.varak.net/extensions/CirrusSearch/tests/unit/UserTestingTest.php |
<?php namespace CirrusSearch; /** * Make sure cirrus doens't break any hooks. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * http://www.gnu.org/copyleft/gpl.html */ class UserTestingTest extends \MediaWikiTestCase { public function setUp() { parent::setUp(); ElasticsearchIntermediary::resetExecutionId(); UserTesting::resetInstance(); } public function testPartitipcationInTest() { $config = $this->config( 'test' ); $ut = $this->ut( $config, true ); $this->assertEquals( true, $ut->isParticipatingIn( 'test' ) ); $ut = $this->ut( $config, false ); $this->assertEquals( false, $ut->isParticipatingIn( 'test' ) ); } // There is no way to run this test correctly...random values mean // best we can do is measure distribution over a decent sample size public function testSamplesFairlyWithDefaultCallback() { $mockReq = $this->getMockBuilder( 'WebRequest' ) ->disableOriginalConstructor() ->getMock(); $mockReq->expects( $this->any() ) ->method( 'getIP' ) ->will( $this->returnCallback( function () { return mt_rand(); } ) ); $mockReq->expects( $this->any() ) ->method( 'getHeader' ) ->will( $this->returnCallback( function () { return mt_rand(); } ) ); \RequestContext::getMain()->setRequest( $mockReq ); $config = $this->config( 'test', 3 ); $samples = 3000; $expected = $samples / $config['test']['sampleRate']; $expectedPerBucket = $expected / count( $config['test']['buckets'] ); $allowedError = .25; $buckets = []; for ( $i = 0; $i < $samples; ++$i ) { $ut = new UserTesting( $config ); if ( $ut->isParticipatingIn( 'test' ) ) { $bucket = $ut->getBucket( 'test' ); if ( isset( $buckets[$bucket] ) ) { $buckets[$bucket]++; } else { $buckets[$bucket] = 1; } } } unset( $buckets[''] ); $participants = array_sum( $buckets ); $this->assertGreaterThan( $expected * ( 1 - $allowedError ), $participants ); $this->assertLessThan( $expected * ( 1 + $allowedError ), $participants ); foreach ( $buckets as $bucket => $participants ) { $this->assertGreaterThan( $expectedPerBucket * ( 1 - $allowedError ), $participants ); $this->assertLessThan( $expectedPerBucket * ( 1 + $allowedError ), $participants ); } } public function testListsTestsCurrentlyParticipatingIn() { $config = $this->config( [ 'test', 'foo', 'bar' ] ); $ut = $this->ut( $config, true); $this->assertEquals( [ 'test', 'foo', 'bar' ], $ut->getActiveTestNames() ); $ut = $this->ut( $config, [ false, true, true ] ); $this->assertEquals( [ 'foo', 'bar' ], $ut->getActiveTestNames() ); } public function testActiveTestOverridesGlobalVariables() { $config = $this->config( 'test', 10, [ 'wgCirrusSearchBoostLinks' => true, 'dontsetthisvariable' => true, ] ); $this->setMwGlobals( 'wgCirrusSearchBoostLinks', false ); $ut = $this->ut( $config, true ); $this->assertEquals( true, $GLOBALS['wgCirrusSearchBoostLinks'] ); $this->assertArrayNotHasKey( 'dontsetthisvariable', $GLOBALS ); $this->setMwGlobals( 'wgCirrusSearchBoostLinks', false ); $ut = $this->ut( $config, false ); $this->assertEquals( false, $GLOBALS['wgCirrusSearchBoostLinks'] ); } public function testDoesNotReinitializeFromGetInstance() { $this->setMwGlobals( [ 'wgCirrusSearchUserTesting' => $this->config( 'test', 10, [ 'wgCirrusSearchBoostLinks' => true, ] ), 'wgCirrusSearchBoostLinks' => false, ] ); $ut = UserTesting::getInstance( function () { return true; } ); $this->assertEquals( true, $GLOBALS['wgCirrusSearchBoostLinks'] ); $GLOBALS['wgCirrusSearchBoostLinks'] = false; $ut = UserTesting::getInstance( function () { return true; } ); $this->assertEquals( false, $GLOBALS['wgCirrusSearchBoostLinks'] ); } public function testPerBucketGlobalsOverridePerTestGlobals() { $this->setMwGlobals( 'wgCirrusSearchBoostLinks', false ); $config = $this->config( 'test', 10, [ 'wgCirrusSearchBoostLinks' => 'test', ] ); $config['test']['buckets']['a']['globals']['wgCirrusSearchBoostLinks'] = 'bucket'; $config['test']['buckets']['b']['globals']['wgCirrusSearchBoostLinks'] = 'bucket'; $ut = $this->ut( $config, true ); $this->assertEquals( 'bucket', $GLOBALS['wgCirrusSearchBoostLinks'] ); } public function providerChooseBucket() { return [ [ 'a', 0, [ 'a', 'b', 'c' ] ], [ 'a', 0, [ 'a', 'b', 'c', 'd' ] ], [ 'a', 0.24, [ 'a', 'b', 'c', 'd' ] ], [ 'a', 0.25, [ 'a', 'b', 'c', 'd' ] ], [ 'b', 0.26, [ 'a', 'b', 'c', 'd' ] ], [ 'b', 0.49, [ 'a', 'b', 'c', 'd' ] ], [ 'b', 0.50, [ 'a', 'b', 'c', 'd' ] ], [ 'c', 0.51, [ 'a', 'b', 'c', 'd' ] ], [ 'd', 1, [ 'a', 'b', 'c', 'd' ] ], ]; } /** * @dataProvider providerChooseBucket */ public function testChooseBucket( $expect, $probability, array $buckets ) { $this->assertEquals( $expect, UserTesting::chooseBucket( $probability, $buckets ) ); } public function testTrigger() { $config = [ 'someTest' => [ 'buckets' => [ 'a' => [ 'trigger' => 'hi there', ], 'b' => [ 'trigger' => 'or this one', ], ], ], ]; $req = new \FauxRequest( [ 'cirrusUserTesting' => 'hi there' ] ); $this->setMwGlobals( 'wgCirrusSearchUserTesting', $config ); \RequestContext::getMain()->setRequest( $req ); $this->assertEquals( [ 'someTest:a' ], UserTesting::getInstance()->getActiveTestNamesWithBucket() ); $ut = new UserTesting( $config, null, 'hi there' ); $this->assertEquals( [ 'someTest:a' ], $ut->getActiveTestNamesWithBucket() ); $ut = new UserTesting( $config, null, 'or this one' ); $this->assertEquals( [ 'someTest:b' ], $ut->getActiveTestNamesWithBucket() ); } protected function config( $testNames, $sampleRate = 10, $globals = [] ) { if ( $globals ) { $globals = [ 'globals' => $globals ]; } $config = []; foreach ( (array)$testNames as $name ) { $config[$name] = $globals + [ 'sampleRate' => $sampleRate, 'buckets' => [ 'a' => [], 'b' => [], ], ]; } return $config; } protected function ut( $config, $callback ) { if ( is_array( $callback ) ) { // reverse so pop in reverse order $retvals = array_reverse( $callback ); $callback = function () use ( &$retvals ) { $retval = array_pop( $retvals ); return $retval ? mt_rand( 0, mt_getrandmax() ) / mt_getrandmax() : 0; }; } elseif ( is_bool( $callback ) ) { $retval = $callback; $callback = function () use ( $retval ) { return $retval ? mt_rand( 0, mt_getrandmax() ) / mt_getrandmax() : 0; }; } return new UserTesting( $config, $callback ); } }