Security update for Core, with self-updated composer
[yaffs-website] / vendor / symfony / http-kernel / Tests / Profiler / FileProfilerStorageTest.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\HttpKernel\Tests\Profiler;
13
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\HttpKernel\Profiler\FileProfilerStorage;
16 use Symfony\Component\HttpKernel\Profiler\Profile;
17
18 class FileProfilerStorageTest extends TestCase
19 {
20     private $tmpDir;
21     private $storage;
22
23     protected function setUp()
24     {
25         $this->tmpDir = sys_get_temp_dir().'/sf2_profiler_file_storage';
26         if (is_dir($this->tmpDir)) {
27             self::cleanDir();
28         }
29         $this->storage = new FileProfilerStorage('file:'.$this->tmpDir);
30         $this->storage->purge();
31     }
32
33     protected function tearDown()
34     {
35         self::cleanDir();
36     }
37
38     public function testStore()
39     {
40         for ($i = 0; $i < 10; ++$i) {
41             $profile = new Profile('token_'.$i);
42             $profile->setIp('127.0.0.1');
43             $profile->setUrl('http://foo.bar');
44             $profile->setMethod('GET');
45             $this->storage->write($profile);
46         }
47         $this->assertCount(10, $this->storage->find('127.0.0.1', 'http://foo.bar', 20, 'GET'), '->write() stores data in the storage');
48     }
49
50     public function testChildren()
51     {
52         $parentProfile = new Profile('token_parent');
53         $parentProfile->setIp('127.0.0.1');
54         $parentProfile->setUrl('http://foo.bar/parent');
55
56         $childProfile = new Profile('token_child');
57         $childProfile->setIp('127.0.0.1');
58         $childProfile->setUrl('http://foo.bar/child');
59
60         $parentProfile->addChild($childProfile);
61
62         $this->storage->write($parentProfile);
63         $this->storage->write($childProfile);
64
65         // Load them from storage
66         $parentProfile = $this->storage->read('token_parent');
67         $childProfile = $this->storage->read('token_child');
68
69         // Check child has link to parent
70         $this->assertNotNull($childProfile->getParent());
71         $this->assertEquals($parentProfile->getToken(), $childProfile->getParentToken());
72
73         // Check parent has child
74         $children = $parentProfile->getChildren();
75         $this->assertCount(1, $children);
76         $this->assertEquals($childProfile->getToken(), $children[0]->getToken());
77     }
78
79     public function testStoreSpecialCharsInUrl()
80     {
81         // The storage accepts special characters in URLs (Even though URLs are not
82         // supposed to contain them)
83         $profile = new Profile('simple_quote');
84         $profile->setUrl('http://foo.bar/\'');
85         $this->storage->write($profile);
86         $this->assertTrue(false !== $this->storage->read('simple_quote'), '->write() accepts single quotes in URL');
87
88         $profile = new Profile('double_quote');
89         $profile->setUrl('http://foo.bar/"');
90         $this->storage->write($profile);
91         $this->assertTrue(false !== $this->storage->read('double_quote'), '->write() accepts double quotes in URL');
92
93         $profile = new Profile('backslash');
94         $profile->setUrl('http://foo.bar/\\');
95         $this->storage->write($profile);
96         $this->assertTrue(false !== $this->storage->read('backslash'), '->write() accepts backslash in URL');
97
98         $profile = new Profile('comma');
99         $profile->setUrl('http://foo.bar/,');
100         $this->storage->write($profile);
101         $this->assertTrue(false !== $this->storage->read('comma'), '->write() accepts comma in URL');
102     }
103
104     public function testStoreDuplicateToken()
105     {
106         $profile = new Profile('token');
107         $profile->setUrl('http://example.com/');
108
109         $this->assertTrue($this->storage->write($profile), '->write() returns true when the token is unique');
110
111         $profile->setUrl('http://example.net/');
112
113         $this->assertTrue($this->storage->write($profile), '->write() returns true when the token is already present in the storage');
114         $this->assertEquals('http://example.net/', $this->storage->read('token')->getUrl(), '->write() overwrites the current profile data');
115
116         $this->assertCount(1, $this->storage->find('', '', 1000, ''), '->find() does not return the same profile twice');
117     }
118
119     public function testRetrieveByIp()
120     {
121         $profile = new Profile('token');
122         $profile->setIp('127.0.0.1');
123         $profile->setMethod('GET');
124         $this->storage->write($profile);
125
126         $this->assertCount(1, $this->storage->find('127.0.0.1', '', 10, 'GET'), '->find() retrieve a record by IP');
127         $this->assertCount(0, $this->storage->find('127.0.%.1', '', 10, 'GET'), '->find() does not interpret a "%" as a wildcard in the IP');
128         $this->assertCount(0, $this->storage->find('127.0._.1', '', 10, 'GET'), '->find() does not interpret a "_" as a wildcard in the IP');
129     }
130
131     public function testRetrieveByStatusCode()
132     {
133         $profile200 = new Profile('statuscode200');
134         $profile200->setStatusCode(200);
135         $this->storage->write($profile200);
136
137         $profile404 = new Profile('statuscode404');
138         $profile404->setStatusCode(404);
139         $this->storage->write($profile404);
140
141         $this->assertCount(1, $this->storage->find(null, null, 10, null, null, null, '200'), '->find() retrieve a record by Status code 200');
142         $this->assertCount(1, $this->storage->find(null, null, 10, null, null, null, '404'), '->find() retrieve a record by Status code 404');
143     }
144
145     public function testRetrieveByUrl()
146     {
147         $profile = new Profile('simple_quote');
148         $profile->setIp('127.0.0.1');
149         $profile->setUrl('http://foo.bar/\'');
150         $profile->setMethod('GET');
151         $this->storage->write($profile);
152
153         $profile = new Profile('double_quote');
154         $profile->setIp('127.0.0.1');
155         $profile->setUrl('http://foo.bar/"');
156         $profile->setMethod('GET');
157         $this->storage->write($profile);
158
159         $profile = new Profile('backslash');
160         $profile->setIp('127.0.0.1');
161         $profile->setUrl('http://foo\\bar/');
162         $profile->setMethod('GET');
163         $this->storage->write($profile);
164
165         $profile = new Profile('percent');
166         $profile->setIp('127.0.0.1');
167         $profile->setUrl('http://foo.bar/%');
168         $profile->setMethod('GET');
169         $this->storage->write($profile);
170
171         $profile = new Profile('underscore');
172         $profile->setIp('127.0.0.1');
173         $profile->setUrl('http://foo.bar/_');
174         $profile->setMethod('GET');
175         $this->storage->write($profile);
176
177         $profile = new Profile('semicolon');
178         $profile->setIp('127.0.0.1');
179         $profile->setUrl('http://foo.bar/;');
180         $profile->setMethod('GET');
181         $this->storage->write($profile);
182
183         $this->assertCount(1, $this->storage->find('127.0.0.1', 'http://foo.bar/\'', 10, 'GET'), '->find() accepts single quotes in URLs');
184         $this->assertCount(1, $this->storage->find('127.0.0.1', 'http://foo.bar/"', 10, 'GET'), '->find() accepts double quotes in URLs');
185         $this->assertCount(1, $this->storage->find('127.0.0.1', 'http://foo\\bar/', 10, 'GET'), '->find() accepts backslash in URLs');
186         $this->assertCount(1, $this->storage->find('127.0.0.1', 'http://foo.bar/;', 10, 'GET'), '->find() accepts semicolon in URLs');
187         $this->assertCount(1, $this->storage->find('127.0.0.1', 'http://foo.bar/%', 10, 'GET'), '->find() does not interpret a "%" as a wildcard in the URL');
188         $this->assertCount(1, $this->storage->find('127.0.0.1', 'http://foo.bar/_', 10, 'GET'), '->find() does not interpret a "_" as a wildcard in the URL');
189     }
190
191     public function testStoreTime()
192     {
193         $dt = new \DateTime('now');
194         $start = $dt->getTimestamp();
195
196         for ($i = 0; $i < 3; ++$i) {
197             $dt->modify('+1 minute');
198             $profile = new Profile('time_'.$i);
199             $profile->setIp('127.0.0.1');
200             $profile->setUrl('http://foo.bar');
201             $profile->setTime($dt->getTimestamp());
202             $profile->setMethod('GET');
203             $this->storage->write($profile);
204         }
205
206         $records = $this->storage->find('', '', 3, 'GET', $start, time() + 3 * 60);
207         $this->assertCount(3, $records, '->find() returns all previously added records');
208         $this->assertEquals($records[0]['token'], 'time_2', '->find() returns records ordered by time in descendant order');
209         $this->assertEquals($records[1]['token'], 'time_1', '->find() returns records ordered by time in descendant order');
210         $this->assertEquals($records[2]['token'], 'time_0', '->find() returns records ordered by time in descendant order');
211
212         $records = $this->storage->find('', '', 3, 'GET', $start, time() + 2 * 60);
213         $this->assertCount(2, $records, '->find() should return only first two of the previously added records');
214     }
215
216     public function testRetrieveByEmptyUrlAndIp()
217     {
218         for ($i = 0; $i < 5; ++$i) {
219             $profile = new Profile('token_'.$i);
220             $profile->setMethod('GET');
221             $this->storage->write($profile);
222         }
223         $this->assertCount(5, $this->storage->find('', '', 10, 'GET'), '->find() returns all previously added records');
224         $this->storage->purge();
225     }
226
227     public function testRetrieveByMethodAndLimit()
228     {
229         foreach (array('POST', 'GET') as $method) {
230             for ($i = 0; $i < 5; ++$i) {
231                 $profile = new Profile('token_'.$i.$method);
232                 $profile->setMethod($method);
233                 $this->storage->write($profile);
234             }
235         }
236
237         $this->assertCount(5, $this->storage->find('', '', 5, 'POST'));
238
239         $this->storage->purge();
240     }
241
242     public function testPurge()
243     {
244         $profile = new Profile('token1');
245         $profile->setIp('127.0.0.1');
246         $profile->setUrl('http://example.com/');
247         $profile->setMethod('GET');
248         $this->storage->write($profile);
249
250         $this->assertTrue(false !== $this->storage->read('token1'));
251         $this->assertCount(1, $this->storage->find('127.0.0.1', '', 10, 'GET'));
252
253         $profile = new Profile('token2');
254         $profile->setIp('127.0.0.1');
255         $profile->setUrl('http://example.net/');
256         $profile->setMethod('GET');
257         $this->storage->write($profile);
258
259         $this->assertTrue(false !== $this->storage->read('token2'));
260         $this->assertCount(2, $this->storage->find('127.0.0.1', '', 10, 'GET'));
261
262         $this->storage->purge();
263
264         $this->assertEmpty($this->storage->read('token'), '->purge() removes all data stored by profiler');
265         $this->assertCount(0, $this->storage->find('127.0.0.1', '', 10, 'GET'), '->purge() removes all items from index');
266     }
267
268     public function testDuplicates()
269     {
270         for ($i = 1; $i <= 5; ++$i) {
271             $profile = new Profile('foo'.$i);
272             $profile->setIp('127.0.0.1');
273             $profile->setUrl('http://example.net/');
274             $profile->setMethod('GET');
275
276             ///three duplicates
277             $this->storage->write($profile);
278             $this->storage->write($profile);
279             $this->storage->write($profile);
280         }
281         $this->assertCount(3, $this->storage->find('127.0.0.1', 'http://example.net/', 3, 'GET'), '->find() method returns incorrect number of entries');
282     }
283
284     public function testStatusCode()
285     {
286         $profile = new Profile('token1');
287         $profile->setStatusCode(200);
288         $this->storage->write($profile);
289
290         $profile = new Profile('token2');
291         $profile->setStatusCode(404);
292         $this->storage->write($profile);
293
294         $tokens = $this->storage->find('', '', 10, '');
295         $this->assertCount(2, $tokens);
296         $this->assertContains($tokens[0]['status_code'], array(200, 404));
297         $this->assertContains($tokens[1]['status_code'], array(200, 404));
298     }
299
300     public function testMultiRowIndexFile()
301     {
302         $iteration = 3;
303         for ($i = 0; $i < $iteration; ++$i) {
304             $profile = new Profile('token'.$i);
305             $profile->setIp('127.0.0.'.$i);
306             $profile->setUrl('http://foo.bar/'.$i);
307
308             $this->storage->write($profile);
309             $this->storage->write($profile);
310             $this->storage->write($profile);
311         }
312
313         $handle = fopen($this->tmpDir.'/index.csv', 'r');
314         for ($i = 0; $i < $iteration; ++$i) {
315             $row = fgetcsv($handle);
316             $this->assertEquals('token'.$i, $row[0]);
317             $this->assertEquals('127.0.0.'.$i, $row[1]);
318             $this->assertEquals('http://foo.bar/'.$i, $row[3]);
319         }
320         $this->assertFalse(fgetcsv($handle));
321     }
322
323     public function testReadLineFromFile()
324     {
325         $r = new \ReflectionMethod($this->storage, 'readLineFromFile');
326
327         $r->setAccessible(true);
328
329         $h = tmpfile();
330
331         fwrite($h, "line1\n\n\nline2\n");
332         fseek($h, 0, SEEK_END);
333
334         $this->assertEquals('line2', $r->invoke($this->storage, $h));
335         $this->assertEquals('line1', $r->invoke($this->storage, $h));
336     }
337
338     protected function cleanDir()
339     {
340         $flags = \FilesystemIterator::SKIP_DOTS;
341         $iterator = new \RecursiveDirectoryIterator($this->tmpDir, $flags);
342         $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);
343
344         foreach ($iterator as $file) {
345             if (is_file($file)) {
346                 unlink($file);
347             }
348         }
349     }
350 }