1 <?php
2 
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
12 namespace Symfony\Component\Process\Tests;
13 
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\Process\ExecutableFinder;
16 
17 /**
18  * @author Chris Smith <chris@cs278.org>
19  */
20 class ExecutableFinderTest extends TestCase
21 {
22     private $path;
23 
24     protected function tearDown()
25     {
26         if ($this->path) {
27             // Restore path if it was changed.
28             putenv('PATH='.$this->path);
29         }
30     }
31 
32     private function setPath($path)
33     {
34         $this->path = getenv('PATH');
35         putenv('PATH='.$path);
36     }
37 
38     public function testFind()
39     {
40         if (ini_get('open_basedir')) {
41             $this->markTestSkipped('Cannot test when open_basedir is set');
42         }
43 
44         $this->setPath(\dirname(\PHP_BINARY));
45 
46         $finder = new ExecutableFinder();
47         $result = $finder->find($this->getPhpBinaryName());
48 
49         $this->assertSamePath(\PHP_BINARY, $result);
50     }
51 
52     public function testFindWithDefault()
53     {
54         if (ini_get('open_basedir')) {
55             $this->markTestSkipped('Cannot test when open_basedir is set');
56         }
57 
58         $expected = 'defaultValue';
59 
60         $this->setPath('');
61 
62         $finder = new ExecutableFinder();
63         $result = $finder->find('foo', $expected);
64 
65         $this->assertEquals($expected, $result);
66     }
67 
68     public function testFindWithNullAsDefault()
69     {
70         if (ini_get('open_basedir')) {
71             $this->markTestSkipped('Cannot test when open_basedir is set');
72         }
73 
74         $this->setPath('');
75 
76         $finder = new ExecutableFinder();
77 
78         $result = $finder->find('foo');
79 
80         $this->assertNull($result);
81     }
82 
83     public function testFindWithExtraDirs()
84     {
85         if (ini_get('open_basedir')) {
86             $this->markTestSkipped('Cannot test when open_basedir is set');
87         }
88 
89         $this->setPath('');
90 
91         $extraDirs = [\dirname(\PHP_BINARY)];
92 
93         $finder = new ExecutableFinder();
94         $result = $finder->find($this->getPhpBinaryName(), null, $extraDirs);
95 
96         $this->assertSamePath(\PHP_BINARY, $result);
97     }
98 
99     public function testFindWithOpenBaseDir()
100     {
101         if ('\\' === \DIRECTORY_SEPARATOR) {
102             $this->markTestSkipped('Cannot run test on windows');
103         }
104 
105         if (ini_get('open_basedir')) {
106             $this->markTestSkipped('Cannot test when open_basedir is set');
107         }
108 
109         $this->iniSet('open_basedir', \dirname(\PHP_BINARY).(!\defined('HHVM_VERSION') || HHVM_VERSION_ID >= 30800 ? \PATH_SEPARATOR.'/' : ''));
110 
111         $finder = new ExecutableFinder();
112         $result = $finder->find($this->getPhpBinaryName());
113 
114         $this->assertSamePath(\PHP_BINARY, $result);
115     }
116 
117     public function testFindProcessInOpenBasedir()
118     {
119         if (ini_get('open_basedir')) {
120             $this->markTestSkipped('Cannot test when open_basedir is set');
121         }
122         if ('\\' === \DIRECTORY_SEPARATOR) {
123             $this->markTestSkipped('Cannot run test on windows');
124         }
125 
126         $this->setPath('');
127         $this->iniSet('open_basedir', \PHP_BINARY.(!\defined('HHVM_VERSION') || HHVM_VERSION_ID >= 30800 ? \PATH_SEPARATOR.'/' : ''));
128 
129         $finder = new ExecutableFinder();
130         $result = $finder->find($this->getPhpBinaryName(), false);
131 
132         $this->assertSamePath(\PHP_BINARY, $result);
133     }
134 
135     public function testFindBatchExecutableOnWindows()
136     {
137         if (ini_get('open_basedir')) {
138             $this->markTestSkipped('Cannot test when open_basedir is set');
139         }
140         if ('\\' !== \DIRECTORY_SEPARATOR) {
141             $this->markTestSkipped('Can be only tested on windows');
142         }
143 
144         $target = tempnam(sys_get_temp_dir(), 'example-windows-executable');
145 
146         touch($target);
147         touch($target.'.BAT');
148 
149         $this->assertFalse(is_executable($target));
150 
151         $this->setPath(sys_get_temp_dir());
152 
153         $finder = new ExecutableFinder();
154         $result = $finder->find(basename($target), false);
155 
156         unlink($target);
157         unlink($target.'.BAT');
158 
159         $this->assertSamePath($target.'.BAT', $result);
160     }
161 
162     private function assertSamePath($expected, $tested)
163     {
164         if ('\\' === \DIRECTORY_SEPARATOR) {
165             $this->assertEquals(strtolower($expected), strtolower($tested));
166         } else {
167             $this->assertEquals($expected, $tested);
168         }
169     }
170 
171     private function getPhpBinaryName()
172     {
173         return basename(\PHP_BINARY, '\\' === \DIRECTORY_SEPARATOR ? '.exe' : '');
174     }
175 }
176