blob: 12d602a8bad382925403269f902bf3dc57fccc42 [file] [edit]
#!/usr/bin/env vpython3
# Copyright 2019 The LUCI Authors. All rights reserved.
# Use of this source code is governed under the Apache License, Version 2.0
# that can be found in the LICENSE file.
# pylint: disable=missing-docstring
# pylint: disable=import-error
# pylint: disable=invalid-name
import os
import sys
import tempfile
import unittest
# Mutates sys.path.
import test_env
# third_party/
from depot_tools import auto_stub
from utils import file_path
from utils import tools
_ACTUALLY_WINDOWS = sys.platform == "win32"
class FindExecutableTest(auto_stub.TestCase):
"""This tests the tools.find_executable function.
All test cases and helper functions are written so that they can operate (with
few exceptions) on all platforms that run the test. Tests which test the
Windows behavior of find_executable must include the string "WIN" in their
test function name.
"""
def setUp(self):
super(FindExecutableTest, self).setUp()
self.PATH = []
self.playground = os.path.realpath(tempfile.mkdtemp('tools_test-'))
self._orig_cwd = os.getcwd()
os.chdir(self.playground)
if 'WIN' in self.id():
self.mock(sys, "platform", "win32")
else:
self.mock(sys, "platform", "linux")
# initial
self._touch_exe('SYSTEM', 'python')
self._touch_exe('SYSTEM', 'python.exe')
self._add_PATH_abs('SYSTEM')
def tearDown(self):
super(FindExecutableTest, self).tearDown()
# restore cwd
os.chdir(self._orig_cwd)
file_path.rmtree(self.playground)
def _add_PATH_abs(self, *path_toks):
self.PATH.append(self._abs(*path_toks))
def _abs(self, *path_toks):
return os.path.abspath(os.path.join(self.playground, *path_toks))
def _touch(self, *path_toks):
full = self._abs(*path_toks)
d = os.path.dirname(full)
if not os.path.isdir(d):
os.makedirs(d)
with open(full, 'w') as f:
f.write('hi')
return full
def _touch_exe(self, *path_toks):
full = self._touch(*path_toks)
if not _ACTUALLY_WINDOWS:
os.chmod(full, 0o777)
return full
def _fe(self, cmd):
return tools.find_executable(cmd, env={'PATH': os.pathsep.join(self.PATH)})
def test_missing_passthrough(self):
cmd = ['not_a_real_path']
self.assertEqual(cmd, self._fe(cmd))
def test_missing_abs_passthrough(self):
cmd = [self._abs('not', 'real')]
self.assertEqual(cmd, self._fe(cmd))
@unittest.skipIf(sys.platform == 'win32', 'posix only')
def test_bad_permissions(self):
cmd = ['config_file']
os.chmod(self._touch('something', 'dir', 'config_file'), 0)
os.chmod(self._abs('something', 'dir'), 0)
self._add_PATH_abs('something', 'dir')
self.assertEqual(cmd, self._fe(cmd))
def test_WIN_implicit_extension(self):
self.assertEqual([self._touch_exe('SYSTEM', 'hello.bat')],
self._fe(['hello']))
def test_implicit_cwd(self):
self.assertEqual([self._touch_exe('python')], self._fe(['python']))
def test_WIN_implicit_cwd(self):
self.assertEqual([self._touch_exe('python.bat')], self._fe(['python']))
def test_relative_PATH_entry(self):
self.PATH.insert(0, 'LOCAL')
self.assertEqual([self._touch_exe('LOCAL', 'thingy')], self._fe(['thingy']))
def test_skip_empty(self):
self.PATH.insert(0, '')
self.assertEqual([self._abs('SYSTEM', 'python')], self._fe(['python']))
def test_explicit_relative(self):
self.assertEqual([self._touch_exe('python')], self._fe(['./python']))
def test_WIN_explicit_relative(self):
self.assertEqual([self._touch_exe('python.exe')], self._fe(['./python']))
def test_explicit_relative_missing(self):
# slash gets flipped on windows because this is not resolved to an absolute
# path.
self.assertEqual([os.path.join('.', 'not_real')], self._fe(['./not_real']))
if __name__ == '__main__':
test_env.main()