Skip to content

Commit 025d0d0

Browse files
authored
Copy the docker tests for podman
1 parent e750378 commit 025d0d0

File tree

1 file changed

+194
-0
lines changed

1 file changed

+194
-0
lines changed

tests/test_connectors/test_podman.py

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
import shlex
2+
from subprocess import PIPE
3+
from unittest import TestCase
4+
from unittest.mock import MagicMock, mock_open, patch
5+
6+
from pyinfra.api import Config, State
7+
from pyinfra.api.connect import connect_all
8+
from pyinfra.api.exceptions import InventoryError, PyinfraError
9+
from pyinfra.connectors.util import make_unix_command
10+
11+
from ..util import make_inventory
12+
13+
14+
def fake_podman_shell(command, splitlines=None):
15+
if command == "podman run -d not-an-image tail -f /dev/null":
16+
return ["containerid"]
17+
18+
if command == "podman commit containerid":
19+
return ["sha256:blahsomerandomstringdata"]
20+
21+
if command == "podman rm -f containerid":
22+
return []
23+
24+
raise PyinfraError("Invalid command: {0}".format(command))
25+
26+
27+
@patch("pyinfra.connectors.docker.local.shell", fake_podman_shell)
28+
@patch("pyinfra.connectors.docker.mkstemp", lambda: (None, "__tempfile__"))
29+
@patch("pyinfra.connectors.docker.os.remove", lambda f: None)
30+
@patch("pyinfra.connectors.docker.os.close", lambda f: None)
31+
@patch("pyinfra.connectors.docker.open", mock_open(read_data="test!"), create=True)
32+
@patch("pyinfra.api.util.open", mock_open(read_data="test!"), create=True)
33+
class TestPodmanConnector(TestCase):
34+
def setUp(self):
35+
self.fake_popen_patch = patch("pyinfra.connectors.util.Popen")
36+
self.fake_popen_mock = self.fake_popen_patch.start()
37+
38+
def tearDown(self):
39+
self.fake_popen_patch.stop()
40+
41+
def test_missing_image(self):
42+
with self.assertRaises(InventoryError):
43+
make_inventory(hosts=("@podman",))
44+
45+
def test_user_provided_container_id(self):
46+
inventory = make_inventory(
47+
hosts=(("@podman/not-an-image", {"docker_container_id": "abc"}),),
48+
)
49+
State(inventory, Config())
50+
host = inventory.get_host("@podman/not-an-image")
51+
host.connect()
52+
assert host.data.docker_container_id == "abc"
53+
54+
def test_connect_all(self):
55+
inventory = make_inventory(hosts=("@podman/not-an-image",))
56+
state = State(inventory, Config())
57+
connect_all(state)
58+
assert len(state.active_hosts) == 1
59+
60+
def test_connect_all_error(self):
61+
inventory = make_inventory(hosts=("@podman/a-broken-image",))
62+
state = State(inventory, Config())
63+
64+
with self.assertRaises(PyinfraError):
65+
connect_all(state)
66+
67+
def test_connect_disconnect_host(self):
68+
inventory = make_inventory(hosts=("@podman/not-an-image",))
69+
state = State(inventory, Config())
70+
host = inventory.get_host("@podman/not-an-image")
71+
host.connect(reason=True)
72+
assert len(state.active_hosts) == 0
73+
host.disconnect()
74+
75+
def test_run_shell_command(self):
76+
inventory = make_inventory(hosts=("@podman/not-an-image",))
77+
State(inventory, Config())
78+
79+
command = "echo hi"
80+
self.fake_popen_mock().returncode = 0
81+
82+
host = inventory.get_host("@podman/not-an-image")
83+
host.connect()
84+
out = host.run_shell_command(
85+
command,
86+
_stdin="hello",
87+
_get_pty=True,
88+
print_output=True,
89+
)
90+
assert len(out) == 2
91+
assert out[0] is True
92+
93+
command = make_unix_command(command).get_raw_value()
94+
command = shlex.quote(command)
95+
podman_command = "podman exec -it containerid sh -c {0}".format(command)
96+
shell_command = make_unix_command(podman_command).get_raw_value()
97+
98+
self.fake_popen_mock.assert_called_with(
99+
shell_command,
100+
shell=True,
101+
stdout=PIPE,
102+
stderr=PIPE,
103+
stdin=PIPE,
104+
)
105+
106+
def test_run_shell_command_success_exit_codes(self):
107+
inventory = make_inventory(hosts=("@podman/not-an-image",))
108+
State(inventory, Config())
109+
110+
command = "echo hi"
111+
self.fake_popen_mock().returncode = 1
112+
113+
host = inventory.get_host("@podman/not-an-image")
114+
host.connect()
115+
out = host.run_shell_command(command, _success_exit_codes=[1])
116+
assert out[0] is True
117+
118+
def test_run_shell_command_error(self):
119+
inventory = make_inventory(hosts=("@podman/not-an-image",))
120+
state = State(inventory, Config())
121+
122+
command = "echo hi"
123+
self.fake_popen_mock().returncode = 1
124+
125+
host = inventory.get_host("@podman/not-an-image")
126+
host.connect(state)
127+
out = host.run_shell_command(command)
128+
assert out[0] is False
129+
130+
def test_put_file(self):
131+
inventory = make_inventory(hosts=("@podman/not-an-image",))
132+
State(inventory, Config())
133+
134+
host = inventory.get_host("@podman/not-an-image")
135+
host.connect()
136+
137+
fake_process = MagicMock(returncode=0)
138+
self.fake_popen_mock.return_value = fake_process
139+
140+
host.put_file("not-a-file", "not-another-file", print_output=True)
141+
142+
self.fake_popen_mock.assert_called_with(
143+
"sh -c 'podman cp __tempfile__ containerid:not-another-file'",
144+
shell=True,
145+
stdout=PIPE,
146+
stderr=PIPE,
147+
stdin=PIPE,
148+
)
149+
150+
def test_put_file_error(self):
151+
inventory = make_inventory(hosts=("@podman/not-an-image",))
152+
State(inventory, Config())
153+
154+
host = inventory.get_host("@podman/not-an-image")
155+
host.connect()
156+
157+
fake_process = MagicMock(returncode=1)
158+
self.fake_popen_mock.return_value = fake_process
159+
160+
with self.assertRaises(IOError):
161+
host.put_file("not-a-file", "not-another-file", print_output=True)
162+
163+
def test_get_file(self):
164+
inventory = make_inventory(hosts=("@podman/not-an-image",))
165+
State(inventory, Config())
166+
167+
host = inventory.get_host("@podman/not-an-image")
168+
host.connect()
169+
170+
fake_process = MagicMock(returncode=0)
171+
self.fake_popen_mock.return_value = fake_process
172+
173+
host.get_file("not-a-file", "not-another-file", print_output=True)
174+
175+
self.fake_popen_mock.assert_called_with(
176+
"sh -c 'podman cp containerid:not-a-file __tempfile__'",
177+
shell=True,
178+
stdout=PIPE,
179+
stderr=PIPE,
180+
stdin=PIPE,
181+
)
182+
183+
def test_get_file_error(self):
184+
inventory = make_inventory(hosts=("@podman/not-an-image",))
185+
State(inventory, Config())
186+
187+
host = inventory.get_host("@podman/not-an-image")
188+
host.connect()
189+
190+
fake_process = MagicMock(returncode=1)
191+
self.fake_popen_mock.return_value = fake_process
192+
193+
with self.assertRaises(IOError):
194+
host.get_file("not-a-file", "not-another-file", print_output=True)

0 commit comments

Comments
 (0)