diff options
Diffstat (limited to 'tools/permission_prompt_test.py')
-rwxr-xr-x | tools/permission_prompt_test.py | 266 |
1 files changed, 118 insertions, 148 deletions
diff --git a/tools/permission_prompt_test.py b/tools/permission_prompt_test.py index c5ebe4acb..312af2cf2 100755 --- a/tools/permission_prompt_test.py +++ b/tools/permission_prompt_test.py @@ -5,16 +5,22 @@ import os import pty import select import subprocess +import sys +import time -from util import build_path, executable_suffix +from util import build_path, executable_suffix, green_ok, red_failed PERMISSIONS_PROMPT_TEST_TS = "tools/permission_prompt_test.ts" +PROMPT_PATTERN = b'⚠️' +FIRST_CHECK_FAILED_PATTERN = b'First check failed' +PERMISSION_DENIED_PATTERN = b'PermissionDenied: permission denied' + # This function is copied from: # https://gist.github.com/hayd/4f46a68fc697ba8888a7b517a414583e # https://stackoverflow.com/q/52954248/1240268 -def tty_capture(cmd, bytes_input): +def tty_capture(cmd, bytes_input, timeout=5): """Capture the output of cmd with bytes_input to stdin, with stdin, stdout and stderr as TTYs.""" mo, so = pty.openpty() # provide tty to enable line-buffering @@ -22,21 +28,23 @@ def tty_capture(cmd, bytes_input): mi, si = pty.openpty() fdmap = {mo: 'stdout', me: 'stderr', mi: 'stdin'} + timeout_exact = time.time() + timeout p = subprocess.Popen( cmd, bufsize=1, stdin=si, stdout=so, stderr=se, close_fds=True) os.write(mi, bytes_input) - timeout = .04 # seconds + select_timeout = .04 #seconds res = {'stdout': b'', 'stderr': b''} while True: - ready, _, _ = select.select([mo, me], [], [], timeout) + ready, _, _ = select.select([mo, me], [], [], select_timeout) if ready: for fd in ready: data = os.read(fd, 512) if not data: break res[fdmap[fd]] += data - elif p.poll() is not None: # select timed-out + elif p.poll() is not None or time.time( + ) > timeout_exact: # select timed-out break # p exited for fd in [si, so, se, mi, mo, me]: os.close(fd) # can't do it sooner: it leads to errno.EIO error @@ -44,181 +52,143 @@ def tty_capture(cmd, bytes_input): return p.returncode, res['stdout'], res['stderr'] +# Wraps a test in debug printouts +# so we have visual indicator of what test failed +def wrap_test(test_name, test_method, *argv): + sys.stdout.write(test_name + " ... ") + try: + test_method(*argv) + print green_ok() + except AssertionError: + print red_failed() + raise + + class Prompt(object): - def __init__(self, deno_exe): + def __init__(self, deno_exe, test_types): self.deno_exe = deno_exe + self.test_types = test_types - def run(self, - arg, - bytes_input, - allow_read=False, - allow_write=False, - allow_net=False, - allow_env=False, - allow_run=False, - no_prompt=False): + def run(self, args, bytes_input): "Returns (return_code, stdout, stderr)." - cmd = [self.deno_exe, PERMISSIONS_PROMPT_TEST_TS, arg] - if allow_read: - cmd.append("--allow-read") - if allow_write: - cmd.append("--allow-write") - if allow_net: - cmd.append("--allow-net") - if allow_env: - cmd.append("--allow-env") - if allow_run: - cmd.append("--allow-run") - if no_prompt: - cmd.append("--no-prompt") + cmd = [self.deno_exe, PERMISSIONS_PROMPT_TEST_TS] + args return tty_capture(cmd, bytes_input) def warm_up(self): # ignore the ts compiling message - self.run('needsWrite', b'', allow_write=True) - - def test_read_yes(self): - code, stdout, stderr = self.run('needsRead', b'y\n') + self.run('needsWrite', b'', ["--allow-write"]) + + def test(self): + for test_type in self.test_types: + test_name_base = "test_" + test_type + wrap_test(test_name_base + "_allow_flag", self.test_allow_flag, + test_type) + wrap_test(test_name_base + "_yes_yes", self.test_yes_yes, + test_type) + wrap_test(test_name_base + "_yes_no", self.test_yes_no, test_type) + wrap_test(test_name_base + "_no_no", self.test_no_no, test_type) + wrap_test(test_name_base + "_no_yes", self.test_no_yes, test_type) + wrap_test(test_name_base + "_allow", self.test_allow, test_type) + wrap_test(test_name_base + "_deny", self.test_deny, test_type) + wrap_test(test_name_base + "_unrecognized_option", + self.test_unrecognized_option, test_type) + wrap_test(test_name_base + "_no_prompt", self.test_no_prompt, + test_type) + wrap_test(test_name_base + "_no_prompt_allow", + self.test_no_prompt_allow, test_type) + + def test_allow_flag(self, test_type): + code, stdout, stderr = self.run( + ["needs" + test_type.capitalize(), "--allow-" + test_type], b'') assert code == 0 - assert stdout == b'' - assert b'⚠️ Deno requests read access' in stderr + assert not PROMPT_PATTERN in stderr + assert not FIRST_CHECK_FAILED_PATTERN in stdout + assert not PERMISSION_DENIED_PATTERN in stderr - def test_read_arg(self): - code, stdout, stderr = self.run('needsRead', b'', allow_read=True) + def test_yes_yes(self, test_type): + code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + b'y\ny\n') assert code == 0 - assert stdout == b'' - assert stderr == b'' + assert PROMPT_PATTERN in stderr + assert not FIRST_CHECK_FAILED_PATTERN in stdout + assert not PERMISSION_DENIED_PATTERN in stderr - def test_read_no(self): - code, _stdout, stderr = self.run('needsRead', b'N\n') + def test_yes_no(self, test_type): + code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + b'y\nn\n') assert code == 1 - assert b'PermissionDenied: permission denied' in stderr - assert b'⚠️ Deno requests read access' in stderr + assert PROMPT_PATTERN in stderr + assert not FIRST_CHECK_FAILED_PATTERN in stdout + assert PERMISSION_DENIED_PATTERN in stderr - def test_read_no_prompt(self): - code, _stdout, stderr = self.run('needsRead', b'', no_prompt=True) + def test_no_no(self, test_type): + code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + b'n\nn\n') assert code == 1 - assert b'PermissionDenied: permission denied' in stderr + assert PROMPT_PATTERN in stderr + assert FIRST_CHECK_FAILED_PATTERN in stdout + assert PERMISSION_DENIED_PATTERN in stderr - def test_write_yes(self): - code, stdout, stderr = self.run('needsWrite', b'y\n') + def test_no_yes(self, test_type): + code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + b'n\ny\n') assert code == 0 - assert stdout == b'' - assert b'⚠️ Deno requests write access' in stderr - def test_write_arg(self): - code, stdout, stderr = self.run('needsWrite', b'', allow_write=True) - assert code == 0 - assert stdout == b'' - assert stderr == b'' - - def test_write_no(self): - code, _stdout, stderr = self.run('needsWrite', b'N\n') - assert code == 1 - assert b'PermissionDenied: permission denied' in stderr - assert b'⚠️ Deno requests write access' in stderr + assert PROMPT_PATTERN in stderr + assert FIRST_CHECK_FAILED_PATTERN in stdout + assert not PERMISSION_DENIED_PATTERN in stderr - def test_write_no_prompt(self): - code, _stdout, stderr = self.run('needsWrite', b'', no_prompt=True) - assert code == 1 - assert b'PermissionDenied: permission denied' in stderr - - def test_env_yes(self): - code, stdout, stderr = self.run('needsEnv', b'y\n') - assert code == 0 - assert stdout == b'' - assert b'⚠️ Deno requests access to environment' in stderr - - def test_env_arg(self): - code, stdout, stderr = self.run('needsEnv', b'', allow_env=True) + def test_allow(self, test_type): + code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + b'a\n') assert code == 0 - assert stdout == b'' - assert stderr == b'' - - def test_env_no(self): - code, _stdout, stderr = self.run('needsEnv', b'N\n') - assert code == 1 - assert b'PermissionDenied: permission denied' in stderr - assert b'⚠️ Deno requests access to environment' in stderr + assert PROMPT_PATTERN in stderr + assert not FIRST_CHECK_FAILED_PATTERN in stdout + assert not PERMISSION_DENIED_PATTERN in stderr - def test_env_no_prompt(self): - code, _stdout, stderr = self.run('needsEnv', b'', no_prompt=True) + def test_deny(self, test_type): + code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + b'd\n') assert code == 1 - assert b'PermissionDenied: permission denied' in stderr + assert PROMPT_PATTERN in stderr + assert FIRST_CHECK_FAILED_PATTERN in stdout + assert PERMISSION_DENIED_PATTERN in stderr - def test_net_yes(self): - code, stdout, stderr = self.run('needsEnv', b'y\n') + def test_unrecognized_option(self, test_type): + code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + b'e\na\n') assert code == 0 - assert stdout == b'' - assert b'⚠️ Deno requests access to environment' in stderr - - def test_net_arg(self): - code, stdout, stderr = self.run('needsNet', b'', allow_net=True) - assert code == 0 - assert stdout == b'' - assert stderr == b'' - - def test_net_no(self): - code, _stdout, stderr = self.run('needsNet', b'N\n') + assert PROMPT_PATTERN in stderr + assert not FIRST_CHECK_FAILED_PATTERN in stdout + assert not PERMISSION_DENIED_PATTERN in stderr + assert b'Unrecognized option' in stderr + + def test_no_prompt(self, test_type): + code, stdout, stderr = self.run( + ["needs" + test_type.capitalize(), "--no-prompt"], b'') assert code == 1 - assert b'PermissionDenied: permission denied' in stderr - assert b'⚠️ Deno requests network access' in stderr - - def test_net_no_prompt(self): - code, _stdout, stderr = self.run('needsNet', b'', no_prompt=True) - assert code == 1 - assert b'PermissionDenied: permission denied' in stderr - - def test_run_yes(self): - code, stdout, stderr = self.run('needsRun', b'y\n') + assert not PROMPT_PATTERN in stderr + assert FIRST_CHECK_FAILED_PATTERN in stdout + assert PERMISSION_DENIED_PATTERN in stderr + + def test_no_prompt_allow(self, test_type): + code, stdout, stderr = self.run([ + "needs" + test_type.capitalize(), "--no-prompt", + "--allow-" + test_type + ], b'') assert code == 0 - assert stdout == b'hello' - assert b'⚠️ Deno requests access to run' in stderr - - def test_run_arg(self): - code, stdout, stderr = self.run('needsRun', b'', allow_run=True) - assert code == 0 - assert stdout == b'hello' - assert stderr == b'' - - def test_run_no(self): - code, _stdout, stderr = self.run('needsRun', b'N\n') - assert code == 1 - assert b'PermissionDenied: permission denied' in stderr - assert b'⚠️ Deno requests access to run' in stderr - - def test_run_no_prompt(self): - code, _stdout, stderr = self.run('needsRun', b'', no_prompt=True) - assert code == 1 - assert b'PermissionDenied: permission denied' in stderr + assert not PROMPT_PATTERN in stderr + assert not FIRST_CHECK_FAILED_PATTERN in stdout + assert not PERMISSION_DENIED_PATTERN in stderr def permission_prompt_test(deno_exe): - p = Prompt(deno_exe) - p.warm_up() - p.test_read_yes() - p.test_read_arg() - p.test_read_no() - p.test_read_no_prompt() - p.test_write_yes() - p.test_write_arg() - p.test_write_no() - p.test_write_no_prompt() - p.test_env_yes() - p.test_env_arg() - p.test_env_no() - p.test_env_no_prompt() - p.test_net_yes() - p.test_net_arg() - p.test_net_no() - p.test_net_no_prompt() - p.test_run_yes() - p.test_run_arg() - p.test_run_no() - p.test_run_no_prompt() + p = Prompt(deno_exe, ["read", "write", "env", "net", "run"]) + p.test() def main(): + print "Permissions prompt tests" deno_exe = os.path.join(build_path(), "deno" + executable_suffix) permission_prompt_test(deno_exe) |