frostfs-testlib/tests/test_local_shell_interactive.py

79 lines
2.9 KiB
Python
Raw Normal View History

from unittest import TestCase
from shell.interfaces import CommandOptions, InteractiveInput
from shell.local_shell import LocalShell
from tests.helpers import format_error_details
class TestLocalShellInteractive(TestCase):
@classmethod
def setUpClass(cls):
cls.shell = LocalShell()
def test_command_with_one_prompt(self):
script = "password = input('Password: '); print(password)"
inputs = [InteractiveInput(prompt_pattern="Password", input="test")]
result = self.shell.exec(
f"python -c \"{script}\"",
CommandOptions(interactive_inputs=inputs)
)
self.assertEqual(0, result.return_code)
self.assertOutputLines(["Password: test", "test"], result.stdout)
self.assertEqual("", result.stderr)
def test_command_with_several_prompts(self):
script = (
"input1 = input('Input1: '); print(input1); "
"input2 = input('Input2: '); print(input2)"
)
inputs = [
InteractiveInput(prompt_pattern="Input1", input="test1"),
InteractiveInput(prompt_pattern="Input2", input="test2"),
]
result = self.shell.exec(
f"python -c \"{script}\"",
CommandOptions(interactive_inputs=inputs)
)
self.assertEqual(0, result.return_code)
self.assertOutputLines(["Input1: test1", "test1", "Input2: test2", "test2"], result.stdout)
self.assertEqual("", result.stderr)
def test_failed_command_with_check(self):
script = "invalid script"
inputs = [InteractiveInput(prompt_pattern=".*", input="test")]
with self.assertRaises(RuntimeError) as exc:
self.shell.exec(f"python -c \"{script}\"", CommandOptions(interactive_inputs=inputs))
error = format_error_details(exc.exception)
self.assertIn("Error", error)
# TODO: it would be nice to have return code as well
# self.assertIn("return code: 1", error)
def test_failed_command_without_check(self):
script = "invalid script"
inputs = [InteractiveInput(prompt_pattern=".*", input="test")]
result = self.shell.exec(
f"python -c \"{script}\"",
CommandOptions(interactive_inputs=inputs, check=False),
)
self.assertEqual(1, result.return_code)
def test_non_existing_binary(self):
inputs = [InteractiveInput(prompt_pattern=".*", input="test")]
with self.assertRaises(RuntimeError) as exc:
self.shell.exec("not-a-command", CommandOptions(interactive_inputs=inputs))
error = format_error_details(exc.exception)
self.assertIn("command was not found or was not executable", error)
def assertOutputLines(self, expected_lines: list[str], output: str) -> None:
output_lines = [line.strip() for line in output.split("\n") if line.strip()]
self.assertEqual(expected_lines, output_lines)