Issues (13)

tests/PidFileTestCase.php (2 issues)

1
<?php
2
declare(strict_types=1);
3
/**
4
 * Created by PhpStorm.
5
 * User: danchukas
6
 * Date: 2017-07-17 21:51
7
 */
8
9
namespace DanchukAS\DenyMultiplyRun;
10
11
use DanchukAS\Mock\TypeList\NotStringList;
12
use PHPUnit\Framework\TestCase;
13
14
/**
15
 * Class PidFileTestCase
16
 * included shared test settings.
17
 * @package DanchukAS\DenyMultiplyRunTest
18
 */
19
abstract class PidFileTestCase extends TestCase
20
{
21
    protected static $noExistFileName;
22
23
    protected static $existFileName;
24
25
    private static $tempFileList = [];
26
27
    public function setUp()
28
    {
29
        self::$noExistFileName = self::getFileName();
30
        self::$existFileName = self::newTempFileName();
31
    }
32
33
    /**
34
     * @return string
35
     */
36
    private static function getFileName(): string
37
    {
38
        $file_name = sys_get_temp_dir() . '/' . uniqid('vd_', true);
39
        self::$tempFileList[] = $file_name;
40
        return $file_name;
41
    }
42
43
    /**
44
     * @return bool|string
45
     */
46
    private static function newTempFileName()
47
    {
48
        $file_name = tempnam(sys_get_temp_dir(), 'vo_');
49
        self::$tempFileList[] = $file_name;
50
        return $file_name;
51
    }
52
53
    public function tearDown()
54
    {
55
        foreach (self::$tempFileList as $file_name) {
56
            /** @noinspection PhpUsageOfSilenceOperatorInspection */
57
            @unlink($file_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

57
            /** @scrutinizer ignore-unhandled */ @unlink($file_name);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
58
        }
59
    }
60
61
    /**
62
     * @return array
63
     */
64
    public function notFileNameProvider()
65
    {
66
        static $not_file_name = null;
67
68
        if (null === $not_file_name) {
69
            $not_file_name = \array_merge($this->notStringProvider(), $this->noValidFileNameProvider());
70
        }
71
72
73
        return $not_file_name;
74
    }
75
76
    /**
77
     * @return array
78
     */
79
    public function notStringProvider()
80
    {
81
        static $not_string_list = null;
82
        if (null === $not_string_list) {
83
            $not_string_list = NotStringList::getList();
84
85
            foreach ($not_string_list as &$param) {
86
                $param['throw'] = 'TypeError';
87
            }
88
        }
89
90
91
        return $not_string_list;
92
    }
93
94
95
    /**
96
     * @return array
97
     */
98
    public function noValidFileNameProvider()
99
    {
100
        static $file_name_list = null;
101
102
        if (null === $file_name_list) {
103
            $file_name_list = [
104
                ['']
105
                , ['.']
106
                , ['/']
107
                , ['//']
108
            ];
109
110
            foreach ($file_name_list as &$param) {
111
                $param['throw'] = 'Exception';
112
            }
113
        }
114
115
        return $file_name_list;
116
    }
117
118
    /**
119
     * return array
120
     */
121
    public function deletePidFileParam()
122
    {
123
        static $param = null;
124
125
        if (null === $param) {
126
            // existed file without write access for current user.
127
            // for Ubuntu is /etc/hosts.
128
            $file_name = '/etc/hosts';
129
130
            $message = $this->adminOrNotUnix($file_name);
131
132
            $param = [
133
                'noExistFileName' => [self::getFileName()]
134
                , 'wrongParam' => [null]
135
                , 'accessDenied' => [$file_name, $message]
136
            ];
137
        }
138
139
        return $param;
140
    }
141
142
    /**
143
     * @param $file_name
144
     * @return null|string
145
     */
146
    private function adminOrNotUnix($file_name)
147
    {
148
        $message = null;
149
150
        if (!file_exists($file_name)) {
151
            $message = 'test only for *nix.';
152
        } elseif (is_writable($file_name)) {
153
            $message = 'test runned under super/admin user. Change user.';
154
        }
155
        return $message;
156
    }
157
158
    /**
159
     * return array
160
     */
161
    public function setPidFileParam()
162
    {
163
        static $param = null;
164
165
        if (null === $param) {
166
            $param = [
167
                'lockedPidFile' => [
168
                    self::lockedPidFile()
169
                    , Exception\LockFileFail::class
170
                ]
171
                , 'fileHasExistPid' => [
172
                    self::fileWithExistedPid()
173
                    , Exception\ProcessExisted::class
174
                ]
175
                , '' => [
176
                    self::noValidPidFile()
177
                    , Exception\ConvertPidFail::class
178
                ]
179
            ];
180
        }
181
182
        return $param;
183
    }
184
185
    /**
186
     *
187
     */
188
    private static function lockedPidFile()
189
    {
190
        while (true) {
191
            $file_name = self::newTempFileName();
192
            $file_resource = fopen($file_name, 'rb+');
193
            flock($file_resource, LOCK_EX);
0 ignored issues
show
It seems like $file_resource can also be of type false; however, parameter $handle of flock() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

193
            flock(/** @scrutinizer ignore-type */ $file_resource, LOCK_EX);
Loading history...
194
195
            yield $file_name;
196
        }
197
    }
198
199
    /**
200
     *
201
     */
202
    private static function fileWithExistedPid()
203
    {
204
        while (true) {
205
            $file_name = self::newTempFileName();
206
            file_put_contents($file_name, getmypid());
207
208
            yield $file_name;
209
        }
210
    }
211
212
    /**
213
     *
214
     */
215
    private static function noValidPidFile()
216
    {
217
        while (true) {
218
            $file_name = self::newTempFileName();
219
            file_put_contents($file_name, '12as');
220
221
            yield $file_name;
222
        }
223
    }
224
}
225