Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.73% covered (success)
97.73%
86 / 88
81.82% covered (warning)
81.82%
9 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
phpbb_cache_file_driver_test
97.73% covered (success)
97.73%
86 / 88
81.82% covered (warning)
81.82%
9 / 11
17
0.00% covered (danger)
0.00%
0 / 1
 getDataSet
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setUp
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
2.01
 tearDown
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 test_read_not_readable
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
2.00
 test_read_data_global_invalid
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 test_read_data_global_zero_bytes
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 test_read_data_global_hex_bytes
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 test_read_data_global_expired
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 test_read_data_global
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
1
 create_cache_dir
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 remove_cache_dir
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2/**
3*
4* This file is part of the phpBB Forum Software package.
5*
6* @copyright (c) phpBB Limited <https://www.phpbb.com>
7* @license GNU General Public License, version 2 (GPL-2.0)
8*
9* For full copyright and license information, please see
10* the docs/CREDITS.txt file.
11*
12*/
13
14require_once __DIR__ . '/common_test_case.php';
15
16class phpbb_cache_file_driver_test extends phpbb_cache_common_test_case
17{
18    private $cache_dir;
19
20    /** @var \phpbb\cache\driver\file */
21    private  $cache_file;
22
23    public function getDataSet()
24    {
25        return $this->createXMLDataSet(__DIR__ . '/fixtures/config.xml');
26    }
27
28    protected function setUp(): void
29    {
30        parent::setUp();
31
32        $this->cache_dir = __DIR__ . '/../tmp/cache/';
33
34        if (file_exists($this->cache_dir))
35        {
36            // cache directory possibly left after aborted
37            // or failed run earlier
38            $this->remove_cache_dir();
39        }
40        $this->create_cache_dir();
41
42        $this->cache_file = new \phpbb\cache\driver\file($this->cache_dir);
43        $this->driver = $this->cache_file;
44    }
45
46    protected function tearDown(): void
47    {
48        if (file_exists($this->cache_dir))
49        {
50            $this->remove_cache_dir();
51        }
52
53        parent::tearDown();
54    }
55
56    public function test_read_not_readable()
57    {
58        if (strtolower(substr(PHP_OS, 0, 3)) === 'win')
59        {
60            $this->markTestSkipped('Unable to test unreadable files on Windows');
61        }
62
63        global $phpEx;
64
65        // Create file that is not readable
66        $this->assertTrue($this->cache_file->_write('unreadable', 'foo', time() + 86400));
67
68        $filename = "{$this->cache_dir}unreadable.$phpEx";
69        @chmod($filename, 0000);
70        $readReflection = new \ReflectionMethod($this->cache_file, '_read');
71        $this->assertFalse($readReflection->invoke($this->cache_file, 'unreadable'));
72        @chmod($filename, 0600);
73        $this->assertNotFalse($readReflection->invoke($this->cache_file, 'unreadable'));
74    }
75
76    public function test_read_data_global_invalid()
77    {
78        global $phpEx;
79
80        $reflectionCacheVars = new \ReflectionProperty($this->cache_file, 'vars');
81        $reflectionCacheVars->setValue($this->cache_file, ['foo' => 'bar']);
82
83        $reflectionCacheVarExpires = new \ReflectionProperty($this->cache_file, 'var_expires');
84        $reflectionCacheVarExpires->setValue($this->cache_file, ['foo' => time() + 86400]);
85
86        // Create file in invalid format
87        $this->assertTrue($this->cache_file->_write('data_global'));
88        $filename = "{$this->cache_dir}data_global.$phpEx";
89        $cache_data = file_get_contents($filename);
90        // Force negative read when retrieving data_global
91        $cache_data = str_replace("\n13\n", "\n1\n", $cache_data);
92        file_put_contents($filename, $cache_data);
93
94        $readReflection = new \ReflectionMethod($this->cache_file, '_read');
95        $this->assertFalse($readReflection->invoke($this->cache_file, 'data_global'));
96    }
97
98    public function test_read_data_global_zero_bytes()
99    {
100        global $phpEx;
101
102        $reflectionCacheVars = new \ReflectionProperty($this->cache_file, 'vars');
103        $reflectionCacheVars->setValue($this->cache_file, ['foo' => 'bar']);
104
105        $reflectionCacheVarExpires = new \ReflectionProperty($this->cache_file, 'var_expires');
106        $reflectionCacheVarExpires->setValue($this->cache_file, ['foo' => time() + 86400]);
107
108        // Create file in invalid format
109        $this->assertTrue($this->cache_file->_write('data_global'));
110        $filename = "{$this->cache_dir}data_global.$phpEx";
111        $cache_data = file_get_contents($filename);
112        // Force negative read when retrieving data_global
113        $cache_data = str_replace("\n13\n", "\n0\n", $cache_data);
114        file_put_contents($filename, $cache_data);
115
116        $readReflection = new \ReflectionMethod($this->cache_file, '_read');
117        $this->assertFalse($readReflection->invoke($this->cache_file, 'data_global'));
118    }
119
120    public function test_read_data_global_hex_bytes()
121    {
122        global $phpEx;
123
124        $reflectionCacheVars = new \ReflectionProperty($this->cache_file, 'vars');
125        $reflectionCacheVars->setValue($this->cache_file, ['foo' => 'bar']);
126
127        $reflectionCacheVarExpires = new \ReflectionProperty($this->cache_file, 'var_expires');
128        $reflectionCacheVarExpires->setValue($this->cache_file, ['foo' => time() + 86400]);
129
130        // Create file in invalid format
131        $this->assertTrue($this->cache_file->_write('data_global'));
132        $filename = "{$this->cache_dir}data_global.$phpEx";
133        $cache_data = file_get_contents($filename);
134        // Force negative read when retrieving data_global
135        $cache_data = str_replace("\n13\n", "\nA\n", $cache_data);
136        file_put_contents($filename, $cache_data);
137
138        $readReflection = new \ReflectionMethod($this->cache_file, '_read');
139        $this->assertFalse($readReflection->invoke($this->cache_file, 'data_global'));
140    }
141
142    public function test_read_data_global_expired()
143    {
144        $reflectionCacheVars = new \ReflectionProperty($this->cache_file, 'vars');
145        $reflectionCacheVars->setValue($this->cache_file, ['foo' => 'bar']);
146
147        $reflectionCacheVarExpires = new \ReflectionProperty($this->cache_file, 'var_expires');
148        $reflectionCacheVarExpires->setValue($this->cache_file, ['foo' => time() - 86400]);
149
150        // Create file in invalid format
151        $this->assertTrue($this->cache_file->_write('data_global'));
152
153        // Clear data
154        $reflectionCacheVars->setValue($this->cache_file, []);
155        $reflectionCacheVarExpires->setValue($this->cache_file, []);
156
157        $readReflection = new \ReflectionMethod($this->cache_file, '_read');
158        $this->assertTrue($readReflection->invoke($this->cache_file, 'data_global'));
159
160        // Check data, should be empty
161        $this->assertEquals([], $reflectionCacheVars->getValue($this->cache_file));
162    }
163
164    public function test_read_data_global()
165    {
166        $reflectionCacheVars = new \ReflectionProperty($this->cache_file, 'vars');
167        $expectedVars = ['foo' => 'bar'];
168        $reflectionCacheVars->setValue($this->cache_file, $expectedVars);
169
170        $reflectionCacheVarExpires = new \ReflectionProperty($this->cache_file, 'var_expires');
171        $expectedVarExpires = ['foo' => time() + 86400];
172        $reflectionCacheVarExpires->setValue($this->cache_file, $expectedVarExpires);
173
174        // Create file in invalid format
175        $this->assertTrue($this->cache_file->_write('data_global'));
176
177        // Clear data
178        $reflectionCacheVars->setValue($this->cache_file, []);
179        $reflectionCacheVarExpires->setValue($this->cache_file, []);
180        $this->assertEquals([], $reflectionCacheVars->getValue($this->cache_file));
181        $this->assertEquals([], $reflectionCacheVarExpires->getValue($this->cache_file));
182
183        $readReflection = new \ReflectionMethod($this->cache_file, '_read');
184        $this->assertTrue($readReflection->invoke($this->cache_file, 'data_global'));
185
186        // Check data, should be empty
187        $this->assertEquals($expectedVars, $reflectionCacheVars->getValue($this->cache_file));
188        $this->assertEquals($expectedVarExpires, $reflectionCacheVarExpires->getValue($this->cache_file));
189    }
190
191    private function create_cache_dir()
192    {
193        $this->get_test_case_helpers()->makedirs($this->cache_dir);
194    }
195
196    private function remove_cache_dir()
197    {
198        $iterator = new DirectoryIterator($this->cache_dir);
199        foreach ($iterator as $file)
200        {
201            if ($file != '.' && $file != '..')
202            {
203                unlink($this->cache_dir . '/' . $file);
204            }
205        }
206        rmdir($this->cache_dir);
207    }
208}