Completed
Push — develope ( 2c1c90...4f785e )
by Anatoliy
01:54
created

PidFileTestCase::lockedPidFile()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 0
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: danchukas
5
 * Date: 2017-07-17 21:51
6
 */
7
8
namespace DanchukAS\DenyMultiplyRun;
9
10
use PHPUnit\Framework\TestCase;
11
12
/**
13
 * Class PidFileTestCase
14
 * included shared test settings.
15
 * @package DanchukAS\DenyMultiplyRunTest
16
 */
17
abstract class PidFileTestCase extends TestCase
18
{
19
    protected static $noExistFileName;
20
21
    protected static $existFileName;
22
23
    private static $tempFileList = [];
24
25
    public function setUp()
26
    {
27
        self::$noExistFileName = self::getFileName();
28
        self::$existFileName = self::newTempFileName();
29
    }
30
31
    /**
32
     * @return string
33
     */
34
    private static function getFileName(): string
35
    {
36
        $file_name = sys_get_temp_dir() . '/' . uniqid('vd_', true);
37
        self::$tempFileList[] = $file_name;
38
        return $file_name;
39
    }
40
41
    /**
42
     * @return bool|string
43
     */
44
    private static function newTempFileName()
45
    {
46
        $file_name = tempnam(sys_get_temp_dir(), 'vo_');
47
        self::$tempFileList[] = $file_name;
48
        return $file_name;
49
    }
50
51
    public function tearDown()
52
    {
53
        foreach (self::$tempFileList as $file_name) {
54
            /** @noinspection PhpUsageOfSilenceOperatorInspection */
55
            @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

55
            /** @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...
56
        }
57
    }
58
59
    /**
60
     * @return array
61
     */
62
    public function notFileNameProvider()
63
    {
64
        static $not_file_name = null;
65
66
        if (is_null($not_file_name)) {
67
            $not_file_name = $this->notStringProvider() + $this->noValidFileNameProvider();
68
        }
69
70
        return $not_file_name;
71
    }
72
73
    /**
74
     * @return array
75
     */
76
    public function notStringProvider()
77
    {
78
        static $not_string_list = null;
79
        if (is_null($not_string_list)) {
80
            $right_resource = fopen(__FILE__, "r");
81
            fclose($right_resource);
82
            $fail_resource = $right_resource;
83
84
            $not_string_list = [
85
                "null" => [null]
86
                , "boolean" => [false]
87
                , "int" => [0]
88
                , "array" => [[]]
89
                , "function" => [function () {
90
                }]
91
                , "object" => [new \Exception]
92
                , "resource" => [$fail_resource]
93
            ];
94
95
            foreach ($not_string_list as &$param) {
96
                $param["throw"] = "TypeError";
97
            }
98
        }
99
100
        return $not_string_list;
101
    }
102
103
    /**
104
     * @return array
105
     */
106
    public function noValidFileNameProvider()
107
    {
108
        static $file_name_list = null;
109
110
        if (is_null($file_name_list)) {
111
            $file_name_list = [
112
                [""]
113
                , ["."]
114
                , ["/"]
115
                , ['//']
116
            ];
117
118
            foreach ($file_name_list as &$param) {
119
                $param["throw"] = "Exception";
120
            }
121
        }
122
123
        return $file_name_list;
124
    }
125
126
    /**
127
     * return array
128
     */
129
    public function deletePidFileParam()
130
    {
131
        static $param = null;
132
133
        if (is_null($param)) {
134
            // existed file without write access for current user.
135
            // for Ubuntu is /etc/hosts.
136
            $file_name = "/etc/hosts";
137
138
            $message = $this->sudoOrNotUnix($file_name);
139
140
            $param = [
141
                "noExistFileName" => [self::getFileName()]
142
                , "wrongParam" => [null]
143
                , "accessDenied" => [$file_name, $message]
144
            ];
145
        }
146
147
        return $param;
148
    }
149
150
    /**
151
     * @param $file_name
152
     * @return null|string
153
     */
154
    private function sudoOrNotUnix($file_name)
155
    {
156
        $message = null;
157
158
        if (!file_exists($file_name)) {
159
            $message = "test only for *nix.";
160
        } elseif (is_writable($file_name)) {
161
            $message = "test runned under super/admin user. Change user.";
162
        }
163
        return $message;
164
    }
165
166
    /**
167
     * return array
168
     */
169
    public function setPidFileParam()
170
    {
171
        static $param = null;
172
173
        if (is_null($param)) {
174
            $param = [
175
                "lockedPidFile" => [
176
                    self::lockedPidFile()
177
                    , "DanchukAS\DenyMultiplyRun\Exception\LockFileFail"
178
                ]
179
                , "fileHasExistPid" => [
180
                    self::fileWithExistedPid()
181
                    , "DanchukAS\DenyMultiplyRun\Exception\ProcessExisted"
182
                ]
183
            ];
184
        }
185
186
        return $param;
187
    }
188
189
    /**
190
     *
191
     */
192
    private static function lockedPidFile()
193
    {
194
        while (true) {
195
            $file_name = self::newTempFileName();
196
            $file_resource = fopen($file_name, "r+");
197
            flock($file_resource, LOCK_EX);
198
199
            yield $file_name;
200
        }
201
    }
202
203
    /**
204
     *
205
     */
206
    private static function fileWithExistedPid()
207
    {
208
        while (true) {
209
            $file_name = self::newTempFileName();
210
            file_put_contents($file_name, getmypid());
211
212
            yield $file_name;
213
        }
214
    }
215
}
216