1 | <?php |
||||
2 | |||||
3 | namespace SilverStripe\FullTextSearch\Tests; |
||||
4 | |||||
5 | use SilverStripe\Core\Config\Config; |
||||
6 | use SilverStripe\Core\Injector\Injector; |
||||
7 | use SilverStripe\Dev\SapphireTest; |
||||
8 | use SilverStripe\FullTextSearch\Search\FullTextSearch; |
||||
9 | use SilverStripe\FullTextSearch\Solr\Reindex\Handlers\SolrReindexHandler; |
||||
10 | use SilverStripe\FullTextSearch\Solr\Reindex\Handlers\SolrReindexQueuedHandler; |
||||
11 | use SilverStripe\FullTextSearch\Solr\Reindex\Jobs\SolrReindexGroupQueuedJob; |
||||
12 | use SilverStripe\FullTextSearch\Solr\Reindex\Jobs\SolrReindexQueuedJob; |
||||
13 | use SilverStripe\FullTextSearch\Solr\Services\Solr4Service; |
||||
14 | use SilverStripe\FullTextSearch\Solr\Services\SolrService; |
||||
15 | use SilverStripe\FullTextSearch\Tests\SolrReindexQueuedTest\SolrReindexQueuedTest_Service; |
||||
16 | use SilverStripe\FullTextSearch\Tests\SolrReindexTest\SolrReindexTest_Index; |
||||
17 | use SilverStripe\FullTextSearch\Tests\SolrReindexTest\SolrReindexTest_Item; |
||||
18 | use SilverStripe\FullTextSearch\Tests\SolrReindexTest\SolrReindexTest_RecordingLogger; |
||||
19 | use SilverStripe\FullTextSearch\Tests\SolrReindexTest\SolrReindexTest_Variant; |
||||
20 | use Symbiote\QueuedJobs\Services\QueuedJob; |
||||
21 | |||||
22 | /** |
||||
23 | * Additional tests of solr reindexing processes when run with queuedjobs |
||||
24 | */ |
||||
25 | class SolrReindexQueuedTest extends SapphireTest |
||||
26 | { |
||||
27 | protected $usesDatabase = true; |
||||
28 | |||||
29 | protected static $extra_dataobjects = array( |
||||
30 | SolrReindexTest_Item::class |
||||
31 | ); |
||||
32 | |||||
33 | /** |
||||
34 | * Forced index for testing |
||||
35 | * |
||||
36 | * @var SolrReindexTest_Index |
||||
37 | */ |
||||
38 | protected $index = null; |
||||
39 | |||||
40 | /** |
||||
41 | * Mock service |
||||
42 | * |
||||
43 | * @var SolrService |
||||
44 | */ |
||||
45 | protected $service = null; |
||||
46 | |||||
47 | protected function setUp() |
||||
48 | { |
||||
49 | parent::setUp(); |
||||
50 | |||||
51 | if (!interface_exists(QueuedJob::class)) { |
||||
52 | $this->skipTest = true; |
||||
53 | return $this->markTestSkipped("These tests need the QueuedJobs module installed to run"); |
||||
54 | } |
||||
55 | |||||
56 | // Set queued handler for reindex |
||||
57 | Config::modify()->set(Injector::class, SolrReindexHandler::class, array( |
||||
58 | 'class' => SolrReindexQueuedHandler::class |
||||
59 | )); |
||||
60 | Injector::inst()->registerService(new SolrReindexQueuedHandler(), SolrReindexHandler::class); |
||||
61 | |||||
62 | // Set test variant |
||||
63 | SolrReindexTest_Variant::enable(); |
||||
64 | |||||
65 | // Set index list |
||||
66 | $this->service = $this->serviceMock(); |
||||
67 | $this->index = singleton(SolrReindexTest_Index::class); |
||||
68 | $this->index->setService($this->service); |
||||
69 | FullTextSearch::force_index_list($this->index); |
||||
70 | } |
||||
71 | |||||
72 | /** |
||||
73 | * Populate database with dummy dataset |
||||
74 | * |
||||
75 | * @param int $number Number of records to create in each variant |
||||
76 | */ |
||||
77 | protected function createDummyData($number) |
||||
78 | { |
||||
79 | // Note that we don't create any records in variant = 2, to represent a variant |
||||
80 | // that should be cleared without any re-indexes performed |
||||
81 | foreach ([0, 1] as $variant) { |
||||
82 | for ($i = 1; $i <= $number; $i++) { |
||||
83 | $item = new SolrReindexTest_Item(); |
||||
84 | $item->Variant = $variant; |
||||
85 | $item->Title = "Item $variant / $i"; |
||||
86 | $item->write(); |
||||
87 | } |
||||
88 | } |
||||
89 | } |
||||
90 | |||||
91 | /** |
||||
92 | * Mock service |
||||
93 | * |
||||
94 | * @return SolrService |
||||
95 | */ |
||||
96 | protected function serviceMock() |
||||
97 | { |
||||
98 | // Setup mock |
||||
99 | /** @var Solr4Service $serviceMock */ |
||||
100 | $serviceMock = $this->getMockBuilder(Solr4Service::class) |
||||
101 | ->setMethods(['deleteByQuery', 'addDocument']) |
||||
102 | ->getMock(); |
||||
103 | |||||
104 | return $serviceMock; |
||||
105 | } |
||||
106 | |||||
107 | protected function tearDown() |
||||
108 | { |
||||
109 | FullTextSearch::force_index_list(); |
||||
110 | SolrReindexTest_Variant::disable(); |
||||
111 | parent::tearDown(); |
||||
112 | } |
||||
113 | |||||
114 | /** |
||||
115 | * Get the reindex handler |
||||
116 | * |
||||
117 | * @return SolrReindexHandler |
||||
118 | */ |
||||
119 | protected function getHandler() |
||||
120 | { |
||||
121 | return Injector::inst()->get(SolrReindexHandler::class); |
||||
122 | } |
||||
123 | |||||
124 | /** |
||||
125 | * @return SolrReindexQueuedTest_Service |
||||
126 | */ |
||||
127 | protected function getQueuedJobService() |
||||
128 | { |
||||
129 | return Injector::inst()->get(SolrReindexQueuedTest_Service::class); |
||||
130 | } |
||||
131 | |||||
132 | /** |
||||
133 | * Test that reindex will generate a top top level queued job, and executing this will perform |
||||
134 | * the necessary initialisation of the grouped queued jobs |
||||
135 | */ |
||||
136 | public function testReindexSegmentsGroups() |
||||
137 | { |
||||
138 | $this->createDummyData(18); |
||||
139 | |||||
140 | // Deletes are performed in the main task prior to individual groups being processed |
||||
141 | // 18 records means 3 groups of 6 in each variant (6 total) |
||||
142 | // Ensure correct call is made to Solr |
||||
143 | $this->service->expects($this->exactly(2)) |
||||
0 ignored issues
–
show
|
|||||
144 | ->method('deleteByQuery') |
||||
145 | ->withConsecutive( |
||||
146 | [ |
||||
147 | $this->equalTo('-(ClassHierarchy:' . SolrReindexTest_Item::class . ')') |
||||
148 | ], |
||||
149 | [ |
||||
150 | $this->equalTo('+(ClassHierarchy:' . SolrReindexTest_Item::class . ') +(_testvariant:"2")') |
||||
151 | ] |
||||
152 | ); |
||||
153 | |||||
154 | // Create pre-existing jobs |
||||
155 | $this->getQueuedJobService()->queueJob(new SolrReindexQueuedJob()); |
||||
156 | $this->getQueuedJobService()->queueJob(new SolrReindexGroupQueuedJob()); |
||||
157 | $this->getQueuedJobService()->queueJob(new SolrReindexGroupQueuedJob()); |
||||
158 | |||||
159 | // Initiate re-index |
||||
160 | $logger = new SolrReindexTest_RecordingLogger(); |
||||
161 | $this->getHandler()->triggerReindex($logger, 6, 'Solr_Reindex'); |
||||
162 | |||||
163 | // Old jobs should be cancelled |
||||
164 | $this->assertEquals(1, $logger->countMessages('Cancelled 1 re-index tasks and 2 re-index groups')); |
||||
165 | $this->assertEquals(1, $logger->countMessages('Queued Solr Reindex Job')); |
||||
166 | |||||
167 | // Next job should be queue job |
||||
168 | $job = $this->getQueuedJobService()->getNextJob(); |
||||
169 | $this->assertInstanceOf(SolrReindexQueuedJob::class, $job); |
||||
170 | $this->assertEquals(6, $job->getBatchSize()); |
||||
171 | |||||
172 | // Test that necessary items are created |
||||
173 | $logger->clear(); |
||||
174 | $job->setLogger($logger); |
||||
175 | $job->process(); |
||||
176 | |||||
177 | $this->assertEquals(1, $logger->countMessages('Beginning init of reindex')); |
||||
178 | $this->assertEquals(6, $logger->countMessages('Queued Solr Reindex Group ')); |
||||
179 | $this->assertEquals(3, $logger->countMessages(' of ' . SolrReindexTest_Item::class . ' in {' . json_encode(SolrReindexTest_Variant::class) . ':"0"}')); |
||||
180 | $this->assertEquals(3, $logger->countMessages(' of ' . SolrReindexTest_Item::class . ' in {' . json_encode(SolrReindexTest_Variant::class) . ':"1"}')); |
||||
181 | $this->assertEquals(1, $logger->countMessages('Completed init of reindex')); |
||||
182 | |||||
183 | // Test that invalid classes are removed |
||||
184 | $this->assertNotEmpty($logger->getMessages('Clearing obsolete classes from ' . SolrReindexTest_Index::class)); |
||||
0 ignored issues
–
show
The call to
SilverStripe\FullTextSea...ngLogger::getMessages() has too many arguments starting with 'Clearing obsolete class...eindexTest_Index::class .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.
Loading history...
|
|||||
185 | |||||
186 | // Test that valid classes in invalid variants are removed |
||||
187 | $this->assertNotEmpty($logger->getMessages( |
||||
188 | 'Clearing all records of type ' . SolrReindexTest_Item::class . ' in the current state: {"' . SolrReindexTest_Variant::class . '":"2"}' |
||||
189 | )); |
||||
190 | } |
||||
191 | |||||
192 | /** |
||||
193 | * Test index processing on individual groups |
||||
194 | */ |
||||
195 | public function testRunGroup() |
||||
196 | { |
||||
197 | $this->createDummyData(18); |
||||
198 | |||||
199 | // Just do what the SolrReindexQueuedJob would do to create each sub |
||||
200 | $logger = new SolrReindexTest_RecordingLogger(); |
||||
201 | $this->getHandler()->runReindex($logger, 6, 'Solr_Reindex'); |
||||
202 | |||||
203 | // Assert jobs are created |
||||
204 | $this->assertEquals(6, $logger->countMessages('Queued Solr Reindex Group')); |
||||
205 | |||||
206 | // Check next job is a group queued job |
||||
207 | /** @var SolrReindexGroupQueuedJob $job */ |
||||
208 | $job = $this->getQueuedJobService()->getNextJob(); |
||||
209 | $this->assertInstanceOf(SolrReindexGroupQueuedJob::class, $job); |
||||
210 | $this->assertEquals( |
||||
211 | 'Solr Reindex Group (1/3) of ' . SolrReindexTest_Item::class . ' in {' . json_encode(SolrReindexTest_Variant::class) . ':"0"}', |
||||
212 | $job->getTitle() |
||||
213 | ); |
||||
214 | |||||
215 | // Running this job performs the necessary reindex |
||||
216 | $logger->clear(); |
||||
217 | $job->setLogger($logger); |
||||
218 | $job->process(); |
||||
219 | |||||
220 | // Check tasks completed (as per non-queuedjob version) |
||||
221 | $this->assertEquals(1, $logger->countMessages('Beginning reindex group')); |
||||
222 | $this->assertEquals(1, $logger->countMessages('Adding ' . SolrReindexTest_Item::class . '')); |
||||
223 | $this->assertEquals(1, $logger->countMessages('Queuing commit on all changes')); |
||||
224 | $this->assertEquals(1, $logger->countMessages('Completed reindex group')); |
||||
225 | |||||
226 | // Check IDs |
||||
227 | $idMessage = $logger->filterMessages('Updated '); |
||||
228 | $this->assertNotEmpty(preg_match('/^Updated (?<ids>[,\d]+)/i', $idMessage[0], $matches)); |
||||
229 | $ids = array_unique(explode(',', $matches['ids'])); |
||||
230 | $this->assertEquals(6, count($ids)); |
||||
231 | foreach ($ids as $id) { |
||||
232 | // Each id should be % 3 == 0 |
||||
233 | $this->assertEquals(0, $id % 3, "ID $id Should match pattern ID % 3 = 0"); |
||||
234 | } |
||||
235 | } |
||||
236 | } |
||||
237 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.