Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
41.51% covered (danger)
41.51%
22 / 53
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
phpbb_lock_flock_test
41.51% covered (danger)
41.51%
22 / 53
66.67% covered (warning)
66.67%
2 / 3
10.00
0.00% covered (danger)
0.00%
0 / 1
 test_lock
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 test_consecutive_locking
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
1
 test_concurrent_locking
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
12
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
14class phpbb_lock_flock_test extends phpbb_test_case
15{
16    public function test_lock()
17    {
18        $path = __DIR__ . '/../tmp/precious';
19
20        $lock = new \phpbb\lock\flock($path);
21        $ok = $lock->acquire();
22        $this->assertTrue($ok);
23        $lock->release();
24    }
25
26    public function test_consecutive_locking()
27    {
28        $path = __DIR__ . '/../tmp/precious';
29
30        $lock = new \phpbb\lock\flock($path);
31        $ok = $lock->acquire();
32        $this->assertTrue($ok);
33        $this->assertTrue($lock->owns_lock());
34        $lock->release();
35        $this->assertFalse($lock->owns_lock());
36
37        $ok = $lock->acquire();
38        $this->assertTrue($ok);
39        $this->assertTrue($lock->owns_lock());
40        $lock->release();
41        $this->assertFalse($lock->owns_lock());
42
43        $ok = $lock->acquire();
44        $this->assertTrue($ok);
45        $this->assertTrue($lock->owns_lock());
46        $lock->release();
47        $this->assertFalse($lock->owns_lock());
48    }
49
50    /* This hangs the process.
51    public function test_concurrent_locking_fail()
52    {
53        $path = __DIR__ . '/../tmp/precious';
54
55        $lock1 = new \phpbb\lock\flock($path);
56        $ok = $lock1->acquire();
57        $this->assertTrue($ok);
58
59        $lock2 = new \phpbb\lock\flock($path);
60        $ok = $lock2->acquire();
61        $this->assertFalse($ok);
62
63        $lock->release();
64        $ok = $lock2->acquire();
65        $this->assertTrue($ok);
66    }
67    */
68
69    public function test_concurrent_locking()
70    {
71        if (!function_exists('pcntl_fork'))
72        {
73            $this->markTestSkipped('pcntl extension and pcntl_fork are required for this test');
74        }
75
76        $path = __DIR__ . '/../tmp/precious';
77
78        $pid = pcntl_fork();
79        if ($pid)
80        {
81            // parent
82            // wait 0.5 s, acquire the lock, note how long it took
83            sleep(1);
84
85            $lock = new \phpbb\lock\flock($path);
86            $start = microtime(true);
87            $ok = $lock->acquire();
88            $delta = microtime(true) - $start;
89            $this->assertTrue($ok);
90            $this->assertTrue($lock->owns_lock());
91            $this->assertGreaterThan(0.5, $delta, 'First lock acquired too soon');
92
93            $lock->release();
94            $this->assertFalse($lock->owns_lock());
95
96            // acquire again, this should be instantaneous
97            $start = microtime(true);
98            $ok = $lock->acquire();
99            $delta = microtime(true) - $start;
100            $this->assertTrue($ok);
101            $this->assertTrue($lock->owns_lock());
102            $this->assertLessThan(0.1, $delta, 'Second lock not acquired instantaneously');
103
104            // reap the child
105            $status = null;
106            pcntl_waitpid($pid, $status);
107        }
108        else
109        {
110            // child
111            // immediately acquire the lock and sleep for 2 s
112            $lock = new \phpbb\lock\flock($path);
113            $ok = $lock->acquire();
114            $this->assertTrue($ok);
115            $this->assertTrue($lock->owns_lock());
116            sleep(2);
117            $lock->release();
118            $this->assertFalse($lock->owns_lock());
119
120            // and go away silently
121            pcntl_exec('/usr/bin/env', array('true'));
122        }
123    }
124}