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
12namespace Symfony\Component\Process\Tests;
13
14use PHPUnit\Framework\TestCase;
15use Symfony\Component\Process\ExecutableFinder;
16
17/**
18 * @author Chris Smith <chris@cs278.org>
19 */
20class 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