Update copyright
[friendica.git/.git] / tests / src / Util / ProfilerTest.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2021, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Test\src\Util;
23
24 use Friendica\Core\Config\Cache;
25 use Friendica\Core\Config\IConfig;
26 use Friendica\Test\MockedTest;
27 use Friendica\Util\Profiler;
28 use Mockery\MockInterface;
29 use Psr\Log\LoggerInterface;
30
31 class ProfilerTest extends MockedTest
32 {
33         /**
34          * @var LoggerInterface|MockInterface
35          */
36         private $logger;
37
38         protected function setUp()
39         {
40                 parent::setUp();
41
42                 $this->logger = \Mockery::mock(LoggerInterface::class);
43         }
44
45         /**
46          * Test the Profiler setup
47          */
48         public function testSetUp()
49         {
50                 $configCache = \Mockery::mock(Cache::class);
51                 $configCache->shouldReceive('get')
52                             ->withAnyArgs()
53                             ->andReturn(true)
54                             ->twice();
55                 $profiler = new Profiler($configCache);
56
57                 self::assertInstanceOf(Profiler::class, $profiler);
58         }
59
60         /**
61          * A dataset for different profiling settings
62          * @return array
63          */
64         public function dataPerformance()
65         {
66                 return [
67                         'database' => [
68                                 'timestamp' => time(),
69                                 'name' => 'database',
70                                 'functions' => ['test', 'it'],
71                         ],
72                         'database_write' => [
73                                 'timestamp' => time(),
74                                 'name' => 'database_write',
75                                 'functions' => ['test', 'it2'],
76                         ],
77                         'cache' => [
78                                 'timestamp' => time(),
79                                 'name' => 'cache',
80                                 'functions' => ['test', 'it3'],
81                         ],
82                         'cache_write' => [
83                                 'timestamp' => time(),
84                                 'name' => 'cache_write',
85                                 'functions' => ['test', 'it4'],
86                         ],
87                         'network' => [
88                                 'timestamp' => time(),
89                                 'name' => 'network',
90                                 'functions' => ['test', 'it5'],
91                         ],
92                         'file' => [
93                                 'timestamp' => time(),
94                                 'name' => 'file',
95                                 'functions' => [],
96                         ],
97                         'rendering' => [
98                                 'timestamp' => time(),
99                                 'name' => 'rendering',
100                                 'functions' => ['test', 'it7'],
101                         ],
102                         'parser' => [
103                                 'timestamp' => time(),
104                                 'name' => 'parser',
105                                 'functions' => ['test', 'it8'],
106                         ],
107                         'marktime' => [
108                                 'timestamp' => time(),
109                                 'name' => 'parser',
110                                 'functions' => ['test'],
111                         ],
112                         // This one isn't set during reset
113                         'unknown' => [
114                                 'timestamp' => time(),
115                                 'name' => 'unknown',
116                                 'functions' => ['test'],
117                         ],
118                 ];
119         }
120
121         /**
122          * Test the Profiler savetimestamp
123          * @dataProvider dataPerformance
124          */
125         public function testSaveTimestamp($timestamp, $name, array $functions)
126         {
127                 $configCache = \Mockery::mock(Cache::class);
128                 $configCache->shouldReceive('get')
129                             ->withAnyArgs()
130                             ->andReturn(true)
131                             ->twice();
132
133                 $profiler = new Profiler($configCache);
134
135                 foreach ($functions as $function) {
136                         $profiler->saveTimestamp($timestamp, $name, $function);
137                 }
138
139                 self::assertGreaterThanOrEqual(0, $profiler->get($name));
140         }
141
142         /**
143          * Test the Profiler reset
144          * @dataProvider dataPerformance
145          */
146         public function testReset($timestamp, $name)
147         {
148                 $configCache = \Mockery::mock(Cache::class);
149                 $configCache->shouldReceive('get')
150                             ->withAnyArgs()
151                             ->andReturn(true)
152                             ->twice();
153
154                 $profiler = new Profiler($configCache);
155
156                 $profiler->saveTimestamp($timestamp, $name);
157                 $profiler->reset();
158
159                 self::assertEquals(0, $profiler->get($name));
160         }
161
162         public function dataBig()
163         {
164                 return [
165                         'big' => [
166                                 'data' => [
167                                         'database' => [
168                                                 'timestamp' => time(),
169                                                 'name' => 'database',
170                                                 'functions' => ['test', 'it'],
171                                         ],
172                                         'database_write' => [
173                                                 'timestamp' => time(),
174                                                 'name' => 'database_write',
175                                                 'functions' => ['test', 'it2'],
176                                         ],
177                                         'cache' => [
178                                                 'timestamp' => time(),
179                                                 'name' => 'cache',
180                                                 'functions' => ['test', 'it3'],
181                                         ],
182                                         'cache_write' => [
183                                                 'timestamp' => time(),
184                                                 'name' => 'cache_write',
185                                                 'functions' => ['test', 'it4'],
186                                         ],
187                                         'network' => [
188                                                 'timestamp' => time(),
189                                                 'name' => 'network',
190                                                 'functions' => ['test', 'it5'],
191                                         ],
192                                 ]
193                         ]
194                 ];
195         }
196
197         /**
198          * Test the output of the Profiler
199          * @dataProvider dataBig
200          */
201         public function testSaveLog($data)
202         {
203                 $this->logger
204                         ->shouldReceive('info')
205                         ->with('test', \Mockery::any())
206                         ->once();
207                 $this->logger
208                         ->shouldReceive('info')
209                         ->once();
210
211                 $configCache = \Mockery::mock(Cache::class);
212                 $configCache->shouldReceive('get')
213                             ->withAnyArgs()
214                             ->andReturn(true)
215                             ->twice();
216
217                 $profiler = new Profiler($configCache);
218
219                 foreach ($data as $perf => $items) {
220                         foreach ($items['functions'] as $function) {
221                                 $profiler->saveTimestamp($items['timestamp'], $items['name'], $function);
222                         }
223                 }
224
225                 $profiler->saveLog($this->logger, 'test');
226
227                 $output = $profiler->getRendertimeString();
228
229                 foreach ($data as $perf => $items) {
230                         foreach ($items['functions'] as $function) {
231                                 // assert that the output contains the functions
232                                 self::assertRegExp('/' . $function . ': \d+/', $output);
233                         }
234                 }
235         }
236
237         /**
238          * Test different enable and disable states of the profiler
239          */
240         public function testEnableDisable()
241         {
242                 $configCache = \Mockery::mock(Cache::class);
243                 $configCache->shouldReceive('get')
244                             ->with('system', 'profiler')
245                             ->andReturn(true)
246                             ->once();
247                 $configCache->shouldReceive('get')
248                             ->with('rendertime', 'callstack')
249                             ->andReturn(false)
250                             ->once();
251
252                 $profiler = new Profiler($configCache);
253
254                 self::assertFalse($profiler->isRendertime());
255                 self::assertEmpty($profiler->getRendertimeString());
256
257                 $profiler->saveTimestamp(time(), 'network', 'test1');
258
259                 $config = \Mockery::mock(IConfig::class);
260                 $config->shouldReceive('get')
261                             ->with('system', 'profiler')
262                             ->andReturn(false)
263                             ->once();
264                 $config->shouldReceive('get')
265                             ->with('rendertime', 'callstack')
266                             ->andReturn(false)
267                             ->once();
268
269                 $profiler->update($config);
270
271                 self::assertFalse($profiler->isRendertime());
272                 self::assertEmpty($profiler->getRendertimeString());
273
274                 $config->shouldReceive('get')
275                        ->with('system', 'profiler')
276                        ->andReturn(true)
277                        ->once();
278                 $config->shouldReceive('get')
279                        ->with('rendertime', 'callstack')
280                        ->andReturn(true)
281                        ->once();
282
283                 $profiler->update($config);
284
285                 $profiler->saveTimestamp(time(), 'database', 'test2');
286
287                 self::assertTrue($profiler->isRendertime());
288                 $output = $profiler->getRendertimeString();
289                 self::assertRegExp('/test1: \d+/', $output);
290                 self::assertRegExp('/test2: \d+/', $output);
291         }
292 }