Failed Conditions
Pull Request — master (#7046)
by Gabriel
14:57
created

SecondLevelCacheTest::testPostUpdateFailure()   B

Complexity

Conditions 2
Paths 3

Size

Total Lines 46
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 27
nc 3
nop 0
dl 0
loc 46
rs 8.9411
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Functional;
6
7
use Doctrine\ORM\Events;
8
use Doctrine\Tests\Models\Cache\Country;
9
use Doctrine\Tests\Models\Cache\State;
10
11
/**
12
 * @group DDC-2183
13
 */
14
class SecondLevelCacheTest extends SecondLevelCacheAbstractTest
15
{
16
    public function testPutOnPersist()
17
    {
18
        $this->loadFixturesCountries();
19
        $this->em->clear();
20
21
        self::assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
22
        self::assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
23
        self::assertEquals(2, $this->secondLevelCacheLogger->getPutCount());
24
        self::assertEquals(2, $this->secondLevelCacheLogger->getRegionPutCount($this->getEntityRegion(Country::class)));
25
    }
26
27
    public function testPutAndLoadEntities()
28
    {
29
        $this->loadFixturesCountries();
30
        $this->em->clear();
31
32
        self::assertEquals(2, $this->secondLevelCacheLogger->getPutCount());
33
        self::assertEquals(2, $this->secondLevelCacheLogger->getRegionPutCount($this->getEntityRegion(Country::class)));
34
35
        $this->cache->evictEntityRegion(Country::class);
36
37
        self::assertFalse($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
38
        self::assertFalse($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
39
40
        $c1 = $this->em->find(Country::class, $this->countries[0]->getId());
41
        $c2 = $this->em->find(Country::class, $this->countries[1]->getId());
42
43
        self::assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
44
        self::assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
45
46
        self::assertInstanceOf(Country::class, $c1);
47
        self::assertInstanceOf(Country::class, $c2);
48
49
        self::assertEquals($this->countries[0]->getId(), $c1->getId());
50
        self::assertEquals($this->countries[0]->getName(), $c1->getName());
51
52
        self::assertEquals($this->countries[1]->getId(), $c2->getId());
53
        self::assertEquals($this->countries[1]->getName(), $c2->getName());
54
55
        $this->em->clear();
56
57
        $queryCount = $this->getCurrentQueryCount();
58
59
        $c3 = $this->em->find(Country::class, $this->countries[0]->getId());
60
        $c4 = $this->em->find(Country::class, $this->countries[1]->getId());
61
62
        self::assertEquals($queryCount, $this->getCurrentQueryCount());
63
        self::assertEquals(2, $this->secondLevelCacheLogger->getHitCount());
64
        self::assertEquals(2, $this->secondLevelCacheLogger->getRegionHitCount($this->getEntityRegion(Country::class)));
65
66
        self::assertInstanceOf(Country::class, $c3);
67
        self::assertInstanceOf(Country::class, $c4);
68
69
        self::assertEquals($c1->getId(), $c3->getId());
70
        self::assertEquals($c1->getName(), $c3->getName());
71
72
        self::assertEquals($c2->getId(), $c4->getId());
73
        self::assertEquals($c2->getName(), $c4->getName());
74
    }
75
76
    public function testRemoveEntities()
77
    {
78
        $this->loadFixturesCountries();
79
        $this->em->clear();
80
81
        self::assertEquals(2, $this->secondLevelCacheLogger->getPutCount());
82
83
        $this->cache->evictEntityRegion(Country::class);
84
        $this->secondLevelCacheLogger->clearRegionStats($this->getEntityRegion(Country::class));
85
86
        self::assertFalse($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
87
        self::assertFalse($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
88
89
        $c1 = $this->em->find(Country::class, $this->countries[0]->getId());
90
        $c2 = $this->em->find(Country::class, $this->countries[1]->getId());
91
92
        self::assertEquals(2, $this->secondLevelCacheLogger->getPutCount());
93
        self::assertEquals(2, $this->secondLevelCacheLogger->getMissCount());
94
95
        self::assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
96
        self::assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
97
98
        self::assertInstanceOf(Country::class, $c1);
99
        self::assertInstanceOf(Country::class, $c2);
100
101
        self::assertEquals($this->countries[0]->getId(), $c1->getId());
102
        self::assertEquals($this->countries[0]->getName(), $c1->getName());
103
104
        self::assertEquals($this->countries[1]->getId(), $c2->getId());
105
        self::assertEquals($this->countries[1]->getName(), $c2->getName());
106
107
        $this->em->remove($c1);
108
        $this->em->remove($c2);
109
        $this->em->flush();
110
        $this->em->clear();
111
112
        self::assertFalse($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
113
        self::assertFalse($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
114
115
        self::assertNull($this->em->find(Country::class, $this->countries[0]->getId()));
116
        self::assertNull($this->em->find(Country::class, $this->countries[1]->getId()));
117
118
        self::assertEquals(2, $this->secondLevelCacheLogger->getPutCount());
119
        self::assertEquals(2, $this->secondLevelCacheLogger->getMissCount());
120
    }
121
122
    public function testUpdateEntities()
123
    {
124
        $this->loadFixturesCountries();
125
        $this->loadFixturesStates();
126
        $this->em->clear();
127
128
        self::assertEquals(6, $this->secondLevelCacheLogger->getPutCount());
129
        self::assertEquals(2, $this->secondLevelCacheLogger->getRegionPutCount($this->getEntityRegion(Country::class)));
130
        self::assertEquals(4, $this->secondLevelCacheLogger->getRegionPutCount($this->getEntityRegion(State::class)));
131
132
        $this->cache->evictEntityRegion(State::class);
133
        $this->secondLevelCacheLogger->clearRegionStats($this->getEntityRegion(State::class));
134
135
        self::assertFalse($this->cache->containsEntity(State::class, $this->states[0]->getId()));
136
        self::assertFalse($this->cache->containsEntity(State::class, $this->states[1]->getId()));
137
138
        $s1 = $this->em->find(State::class, $this->states[0]->getId());
139
        $s2 = $this->em->find(State::class, $this->states[1]->getId());
140
141
        self::assertEquals(4, $this->secondLevelCacheLogger->getPutCount());
142
        self::assertEquals(2, $this->secondLevelCacheLogger->getRegionPutCount($this->getEntityRegion(Country::class)));
143
        self::assertEquals(2, $this->secondLevelCacheLogger->getRegionPutCount($this->getEntityRegion(State::class)));
144
145
        self::assertTrue($this->cache->containsEntity(State::class, $this->states[0]->getId()));
146
        self::assertTrue($this->cache->containsEntity(State::class, $this->states[1]->getId()));
147
148
        self::assertInstanceOf(State::class, $s1);
149
        self::assertInstanceOf(State::class, $s2);
150
151
        self::assertEquals($this->states[0]->getId(), $s1->getId());
152
        self::assertEquals($this->states[0]->getName(), $s1->getName());
153
154
        self::assertEquals($this->states[1]->getId(), $s2->getId());
155
        self::assertEquals($this->states[1]->getName(), $s2->getName());
156
157
        $s1->setName('NEW NAME 1');
158
        $s2->setName('NEW NAME 2');
159
160
        $this->em->persist($s1);
161
        $this->em->persist($s2);
162
        $this->em->flush();
163
        $this->em->clear();
164
165
        self::assertTrue($this->cache->containsEntity(State::class, $this->states[0]->getId()));
166
        self::assertTrue($this->cache->containsEntity(State::class, $this->states[1]->getId()));
167
168
        self::assertEquals(6, $this->secondLevelCacheLogger->getPutCount());
169
        self::assertEquals(2, $this->secondLevelCacheLogger->getRegionPutCount($this->getEntityRegion(Country::class)));
170
        self::assertEquals(4, $this->secondLevelCacheLogger->getRegionPutCount($this->getEntityRegion(State::class)));
171
172
        $queryCount = $this->getCurrentQueryCount();
173
174
        $c3 = $this->em->find(State::class, $this->states[0]->getId());
175
        $c4 = $this->em->find(State::class, $this->states[1]->getId());
176
177
        self::assertEquals(2, $this->secondLevelCacheLogger->getHitCount());
178
        self::assertEquals(2, $this->secondLevelCacheLogger->getRegionHitCount($this->getEntityRegion(State::class)));
179
180
        self::assertEquals($queryCount, $this->getCurrentQueryCount());
181
182
        self::assertTrue($this->cache->containsEntity(State::class, $this->states[0]->getId()));
183
        self::assertTrue($this->cache->containsEntity(State::class, $this->states[1]->getId()));
184
185
        self::assertInstanceOf(State::class, $c3);
186
        self::assertInstanceOf(State::class, $c4);
187
188
        self::assertEquals($s1->getId(), $c3->getId());
189
        self::assertEquals('NEW NAME 1', $c3->getName());
190
191
        self::assertEquals($s2->getId(), $c4->getId());
192
        self::assertEquals('NEW NAME 2', $c4->getName());
193
194
        self::assertEquals(2, $this->secondLevelCacheLogger->getHitCount());
195
        self::assertEquals(2, $this->secondLevelCacheLogger->getRegionHitCount($this->getEntityRegion(State::class)));
196
    }
197
198
    public function testPostFlushFailure()
199
    {
200
        $listener = new ListenerSecondLevelCacheTest(
201
            [
202
                Events::postFlush => function () {
203
                    throw new \RuntimeException('post flush failure');
204
                },
205
            ]
206
        );
207
208
        $this->em->getEventManager()
209
            ->addEventListener(Events::postFlush, $listener);
210
211
        $country = new Country('Brazil');
212
213
        $this->cache->evictEntityRegion(Country::class);
214
215
        try {
216
            $this->em->persist($country);
217
            $this->em->flush();
218
            $this->fail('Should throw exception');
219
        } catch (\RuntimeException $exc) {
220
            self::assertNotNull($country->getId());
221
            self::assertEquals('post flush failure', $exc->getMessage());
222
            self::assertTrue($this->cache->containsEntity(Country::class, $country->getId()));
223
        }
224
    }
225
226
    public function testPostUpdateFailure()
227
    {
228
        $this->loadFixturesCountries();
229
        $this->loadFixturesStates();
230
        $this->em->clear();
231
232
        $listener = new ListenerSecondLevelCacheTest(
233
            [
234
                Events::postUpdate => function () {
235
                    throw new \RuntimeException('post update failure');
236
                },
237
            ]
238
        );
239
240
        $this->em->getEventManager()
241
            ->addEventListener(Events::postUpdate, $listener);
242
243
        $this->cache->evictEntityRegion(State::class);
244
245
        $stateId   = $this->states[0]->getId();
246
        $stateName = $this->states[0]->getName();
247
        $state     = $this->em->find(State::class, $stateId);
248
249
        self::assertTrue($this->cache->containsEntity(State::class, $stateId));
250
        self::assertInstanceOf(State::class, $state);
251
        self::assertEquals($stateName, $state->getName());
252
253
        $state->setName($stateName . uniqid());
254
255
        $this->em->persist($state);
256
257
        try {
258
            $this->em->flush();
259
            $this->fail('Should throw exception');
260
        } catch (\Exception $exc) {
261
            self::assertEquals('post update failure', $exc->getMessage());
262
        }
263
264
        $this->em->clear();
265
266
        self::assertTrue($this->cache->containsEntity(State::class, $stateId));
267
268
        $state = $this->em->find(State::class, $stateId);
269
270
        self::assertInstanceOf(State::class, $state);
271
        self::assertEquals($stateName, $state->getName());
272
    }
273
274
    public function testPostRemoveFailure()
275
    {
276
        $this->loadFixturesCountries();
277
        $this->em->clear();
278
279
        $listener = new ListenerSecondLevelCacheTest([
280
            Events::postRemove => function () {
281
                throw new \RuntimeException('post remove failure');
282
            },
283
        ]);
284
285
        $this->em
286
            ->getEventManager()
287
            ->addEventListener(Events::postRemove, $listener);
288
289
        $this->cache->evictEntityRegion(Country::class);
290
291
        $countryId = $this->countries[0]->getId();
292
        $country   = $this->em->find(Country::class, $countryId);
293
294
        self::assertTrue($this->cache->containsEntity(Country::class, $countryId));
295
        self::assertInstanceOf(Country::class, $country);
296
297
        $this->em->remove($country);
298
299
        try {
300
            $this->em->flush();
301
            $this->fail('Should throw exception');
302
        } catch (\Exception $exc) {
303
            self::assertEquals('post remove failure', $exc->getMessage());
304
        }
305
306
        $this->em->clear();
307
308
        self::assertFalse(
309
            $this->cache->containsEntity(Country::class, $countryId),
310
            'Removal attempts should clear the cache entry corresponding to the entity'
311
        );
312
313
        self::assertInstanceOf(Country::class, $this->em->find(Country::class, $countryId));
314
    }
315
316
    public function testCachedNewEntityExists()
317
    {
318
        $this->loadFixturesCountries();
319
320
        $persister  = $this->em->getUnitOfWork()->getEntityPersister(Country::class);
321
        $queryCount = $this->getCurrentQueryCount();
322
323
        self::assertTrue($persister->exists($this->countries[0]));
324
325
        self::assertEquals($queryCount, $this->getCurrentQueryCount());
326
327
        self::assertFalse($persister->exists(new Country('Foo')));
328
    }
329
}
330
331
332
class ListenerSecondLevelCacheTest
333
{
334
    public $callbacks;
335
336
    public function __construct(array $callbacks = [])
337
    {
338
        $this->callbacks = $callbacks;
339
    }
340
341
    private function dispatch($eventName, $args)
342
    {
343
        if (isset($this->callbacks[$eventName])) {
344
            call_user_func($this->callbacks[$eventName], $args);
345
        }
346
    }
347
348
    public function postFlush($args)
349
    {
350
        $this->dispatch(__FUNCTION__, $args);
351
    }
352
353
    public function postUpdate($args)
354
    {
355
        $this->dispatch(__FUNCTION__, $args);
356
    }
357
358
    public function postRemove($args)
359
    {
360
        $this->dispatch(__FUNCTION__, $args);
361
    }
362
}
363