Completed
Pull Request — master (#1609)
by Mischa
01:42
created

test_run_interactive_shell_command_custom_streams()   B

Complexity

Conditions 4

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 4
dl 0
loc 24
rs 8.6845
1
from contextlib import ExitStack
2
import os
3
import sys
4
from tempfile import NamedTemporaryFile
5
import unittest
6
7
from coalib.misc.Shell import (
8
    escape_path_argument, prepare_string_argument,
9
    run_interactive_shell_command, run_shell_command)
10
11
12
class EscapePathArgumentTest(unittest.TestCase):
13
14
    def test_escape_path_argument_sh(self):
15
        _type = "sh"
16
        self.assertEqual(
17
            escape_path_argument("/home/usr/a-file", _type),
18
            "/home/usr/a-file")
19
        self.assertEqual(
20
            escape_path_argument("/home/usr/a-dir/", _type),
21
            "/home/usr/a-dir/")
22
        self.assertEqual(
23
            escape_path_argument("/home/us r/a-file with spaces.bla",
24
                                 _type),
25
            "/home/us\\ r/a-file\\ with\\ spaces.bla")
26
        self.assertEqual(
27
            escape_path_argument("/home/us r/a-dir with spaces/x/",
28
                                 _type),
29
            "/home/us\\ r/a-dir\\ with\\ spaces/x/")
30
        self.assertEqual(
31
            escape_path_argument(
32
                "relative something/with cherries and/pickles.delicious",
33
                _type),
34
            "relative\\ something/with\\ cherries\\ and/pickles.delicious")
35
36
    def test_escape_path_argument_cmd(self):
37
        _type = "cmd"
38
        self.assertEqual(
39
            escape_path_argument("C:\\Windows\\has-a-weird-shell.txt", _type),
40
            "\"C:\\Windows\\has-a-weird-shell.txt\"")
41
        self.assertEqual(
42
            escape_path_argument("C:\\Windows\\lolrofl\\dirs\\", _type),
43
            "\"C:\\Windows\\lolrofl\\dirs\\\"")
44
        self.assertEqual(
45
            escape_path_argument("X:\\Users\\Maito Gai\\fi le.exe", _type),
46
            "\"X:\\Users\\Maito Gai\\fi le.exe\"")
47
        self.assertEqual(
48
            escape_path_argument("X:\\Users\\Mai to Gai\\director y\\",
49
                                 _type),
50
            "\"X:\\Users\\Mai to Gai\\director y\\\"")
51
        self.assertEqual(
52
            escape_path_argument("X:\\Users\\Maito Gai\\\"seven-gates\".y",
53
                                 _type),
54
            "\"X:\\Users\\Maito Gai\\^\"seven-gates^\".y\"")
55
        self.assertEqual(
56
            escape_path_argument("System32\\my-custom relative tool\\",
57
                                 _type),
58
            "\"System32\\my-custom relative tool\\\"")
59
        self.assertEqual(
60
            escape_path_argument("System32\\illegal\" name \"\".curd", _type),
61
            "\"System32\\illegal^\" name ^\"^\".curd\"")
62
63
    def test_escape_path_argument_unsupported(self):
64
        _type = "INVALID"
65
        self.assertEqual(
66
            escape_path_argument("/home/usr/a-file", _type),
67
            "/home/usr/a-file")
68
        self.assertEqual(
69
            escape_path_argument("/home/us r/a-file with spaces.bla", _type),
70
            "/home/us r/a-file with spaces.bla")
71
        self.assertEqual(
72
            escape_path_argument("|home|us r|a*dir with spaces|x|", _type),
73
            "|home|us r|a*dir with spaces|x|")
74
        self.assertEqual(
75
            escape_path_argument("system|a|b|c?d", _type),
76
            "system|a|b|c?d")
77
78
79
class RunShellCommandTest(unittest.TestCase):
80
81
    @staticmethod
82
    def construct_testscript_command(scriptname):
83
        return " ".join(
84
            escape_path_argument(s) for s in (
85
                sys.executable,
86
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
87
                             "run_shell_command_testfiles",
88
                             scriptname)))
89
90
    def test_run_interactive_shell_command(self):
91
        command = RunShellCommandTest.construct_testscript_command(
92
            "test_interactive_program.py")
93
94
        with run_interactive_shell_command(command) as p:
95
            self.assertEqual(p.stdout.readline(), "test_program X\n")
96
            self.assertEqual(p.stdout.readline(), "Type in a number:\n")
97
            p.stdin.write("33\n")
98
            p.stdin.flush()
99
            self.assertEqual(p.stdout.readline(), "33\n")
100
            self.assertEqual(p.stdout.readline(), "Exiting program.\n")
101
102
            self.assertEqual(p.stdout.read(), "")
103
            self.assertEqual(p.stderr.read(), "")
104
105
    def test_run_interactive_shell_command_custom_streams(self):
106
        command = RunShellCommandTest.construct_testscript_command(
107
            "test_interactive_program.py")
108
109
        with ExitStack() as stack:
110
            streams = {s: stack.enter_context(NamedTemporaryFile(mode="w+"))
111
                       for s in ["stdout", "stderr", "stdin"]}
112
113
            with run_interactive_shell_command(command, **streams) as p:
114
                streams["stdin"].write("712\n")
115
                streams["stdin"].flush()
116
                streams["stdin"].seek(0)
117
118
            self.assertFalse(streams["stdout"].closed)
119
            self.assertFalse(streams["stderr"].closed)
120
            self.assertFalse(streams["stdin"].closed)
121
122
            streams["stdout"].seek(0)
123
            self.assertEqual(streams["stdout"].read(),
124
                             "test_program X\nType in a number:\n712\n"
125
                             "Exiting program.\n")
126
127
            streams["stderr"].seek(0)
128
            self.assertEqual(streams["stderr"].read(), "")
129
130
    def test_run_interactive_shell_command_kwargs_delegation(self):
131
        with self.assertRaises(TypeError):
132
            with run_interactive_shell_command("some_command",
133
                                               weird_parameter=30):
134
                pass
135
136
    def test_run_shell_command_without_stdin(self):
137
        command = RunShellCommandTest.construct_testscript_command(
138
            "test_program.py")
139
140
        stdout, stderr = run_shell_command(command)
141
142
        expected = ("test_program Z\n"
143
                    "non-interactive mode.\n"
144
                    "Exiting...\n")
145
        self.assertEqual(stdout, expected)
146
        self.assertEqual(stderr, "")
147
148
    def test_run_shell_command_with_stdin(self):
149
        command = RunShellCommandTest.construct_testscript_command(
150
            "test_input_program.py")
151
152
        stdout, stderr = run_shell_command(command, "1  4  10  22")
153
154
        self.assertEqual(stdout, "37\n")
155
        self.assertEqual(stderr, "")
156
157
        stdout, stderr = run_shell_command(command, "1 p 5")
158
159
        self.assertEqual(stdout, "")
160
        self.assertEqual(stderr, "INVALID INPUT\n")
161
162
    def test_run_shell_command_kwargs_delegation(self):
163
        with self.assertRaises(TypeError):
164
            run_shell_command("super-cool-command", weird_parameter2="abc")
165
166
167
class PrepareStringArgumentTest(unittest.TestCase):
168
169
    def setUp(self):
170
        self.test_strings = ("normal_string",
171
                             "string with spaces",
172
                             'string with quotes"a',
173
                             "string with s-quotes'b",
174
                             "bsn \n A",
175
                             "unrecognized \\q escape")
176
177
    def test_prepare_string_argument_sh(self):
178
        expected_results = ('"normal_string"',
179
                            '"string with spaces"',
180
                            '"string with quotes\\"a"',
181
                            '"string with s-quotes\'b"',
182
                            '"bsn \n A"',
183
                            '"unrecognized \\q escape"')
184
185
        for string, result in zip(self.test_strings, expected_results):
186
            self.assertEqual(prepare_string_argument(string, "sh"),
187
                             result)
188
189
    def test_prepare_string_argument_unsupported(self):
190
        for string in self.test_strings:
191
            self.assertEqual(prepare_string_argument(string, "WeIrD_O/S"),
192
                             string)
193