github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/test/apiv2/python/rest_api/test_v2_0_0_container.py (about) 1 import multiprocessing 2 import queue 3 import random 4 import threading 5 import unittest 6 7 import requests 8 import time 9 from dateutil.parser import parse 10 11 from .fixtures import APITestCase 12 13 14 class ContainerTestCase(APITestCase): 15 def test_list(self): 16 r = requests.get(self.uri("/containers/json"), timeout=5) 17 self.assertEqual(r.status_code, 200, r.text) 18 obj = r.json() 19 self.assertEqual(len(obj), 1) 20 21 def test_list_filters(self): 22 r = requests.get( 23 self.podman_url 24 + "/v1.40/containers/json?filters%3D%7B%22status%22%3A%5B%22running%22%5D%7D" 25 ) 26 self.assertEqual(r.status_code, 200, r.text) 27 payload = r.json() 28 containerAmnt = len(payload) 29 self.assertGreater(containerAmnt, 0) 30 31 def test_list_all(self): 32 r = requests.get(self.uri("/containers/json?all=true")) 33 self.assertEqual(r.status_code, 200, r.text) 34 self.assertId(r.content) 35 36 def test_inspect(self): 37 r = requests.get(self.uri(self.resolve_container("/containers/{}/json"))) 38 self.assertEqual(r.status_code, 200, r.text) 39 self.assertId(r.content) 40 _ = parse(r.json()["Created"]) 41 42 r = requests.post( 43 self.podman_url + "/v1.40/containers/create?name=topcontainer", 44 json={ 45 "Cmd": ["top"], 46 "Image": "alpine:latest", 47 "Healthcheck": { 48 "Test": ["CMD", "pidof", "top"], 49 "Interval": 5000000000, 50 "Timeout": 2000000000, 51 "Retries": 3, 52 "StartPeriod": 5000000000, 53 }, 54 }, 55 ) 56 self.assertEqual(r.status_code, 201, r.text) 57 payload = r.json() 58 container_id = payload["Id"] 59 self.assertIsNotNone(container_id) 60 61 r = requests.get(self.podman_url + f"/v1.40/containers/{container_id}/json") 62 self.assertEqual(r.status_code, 200, r.text) 63 self.assertId(r.content) 64 out = r.json() 65 self.assertIsNotNone(out["State"].get("Health")) 66 self.assertListEqual(["CMD", "pidof", "top"], out["Config"]["Healthcheck"]["Test"]) 67 self.assertEqual(5000000000, out["Config"]["Healthcheck"]["Interval"]) 68 self.assertEqual(2000000000, out["Config"]["Healthcheck"]["Timeout"]) 69 self.assertEqual(3, out["Config"]["Healthcheck"]["Retries"]) 70 self.assertEqual(5000000000, out["Config"]["Healthcheck"]["StartPeriod"]) 71 72 r = requests.get(self.uri(f"/containers/{container_id}/json")) 73 self.assertEqual(r.status_code, 200, r.text) 74 self.assertId(r.content) 75 out = r.json() 76 hc = out["Config"]["Healthcheck"]["Test"] 77 self.assertListEqual(["CMD", "pidof", "top"], hc) 78 79 r = requests.post(self.podman_url + f"/v1.40/containers/{container_id}/start") 80 self.assertEqual(r.status_code, 204, r.text) 81 82 r = requests.get(self.podman_url + f"/v1.40/containers/{container_id}/json") 83 self.assertEqual(r.status_code, 200, r.text) 84 out = r.json() 85 state = out["State"]["Health"] 86 self.assertIsInstance(state, dict) 87 88 def test_stats(self): 89 r = requests.get(self.uri(self.resolve_container("/containers/{}/stats?stream=false"))) 90 self.assertIn(r.status_code, (200, 409), r.text) 91 if r.status_code == 200: 92 self.assertId(r.content) 93 r = requests.get( 94 self.uri(self.resolve_container("/containers/{}/stats?stream=false&one-shot=true")) 95 ) 96 self.assertIn(r.status_code, (200, 409), r.text) 97 if r.status_code == 200: 98 self.assertId(r.content) 99 100 def test_delete(self): 101 r = requests.delete(self.uri(self.resolve_container("/containers/{}?force=true"))) 102 self.assertEqual(r.status_code, 200, r.text) 103 104 def test_stop(self): 105 r = requests.post(self.uri(self.resolve_container("/containers/{}/start"))) 106 self.assertIn(r.status_code, (204, 304), r.text) 107 108 r = requests.post(self.uri(self.resolve_container("/containers/{}/stop"))) 109 self.assertIn(r.status_code, (204, 304), r.text) 110 111 def test_start(self): 112 r = requests.post(self.uri(self.resolve_container("/containers/{}/stop"))) 113 self.assertIn(r.status_code, (204, 304), r.text) 114 115 r = requests.post(self.uri(self.resolve_container("/containers/{}/start"))) 116 self.assertIn(r.status_code, (204, 304), r.text) 117 118 def test_restart(self): 119 r = requests.post(self.uri(self.resolve_container("/containers/{}/start"))) 120 self.assertIn(r.status_code, (204, 304), r.text) 121 122 r = requests.post(self.uri(self.resolve_container("/containers/{}/restart")), timeout=5) 123 self.assertEqual(r.status_code, 204, r.text) 124 125 def test_resize(self): 126 r = requests.post(self.uri(self.resolve_container("/containers/{}/resize?h=43&w=80"))) 127 self.assertIn(r.status_code, (200, 409), r.text) 128 if r.status_code == 200: 129 self.assertEqual(r.text, "", r.text) 130 131 def test_attach(self): 132 self.skipTest("FIXME: Test timeouts") 133 r = requests.post(self.uri(self.resolve_container("/containers/{}/attach?logs=true")), timeout=5) 134 self.assertIn(r.status_code, (101, 500), r.text) 135 136 def test_logs(self): 137 r = requests.get(self.uri(self.resolve_container("/containers/{}/logs?stdout=true"))) 138 self.assertEqual(r.status_code, 200, r.text) 139 r = requests.post( 140 self.podman_url + "/v1.40/containers/create?name=topcontainer", 141 json={"Cmd": ["top", "ls"], "Image": "alpine:latest"}, 142 ) 143 self.assertEqual(r.status_code, 201, r.text) 144 payload = r.json() 145 container_id = payload["Id"] 146 self.assertIsNotNone(container_id) 147 r = requests.get( 148 self.podman_url 149 + f"/v1.40/containers/{payload['Id']}/logs?follow=false&stdout=true&until=0" 150 ) 151 self.assertEqual(r.status_code, 200, r.text) 152 r = requests.get( 153 self.podman_url 154 + f"/v1.40/containers/{payload['Id']}/logs?follow=false&stdout=true&until=1" 155 ) 156 self.assertEqual(r.status_code, 200, r.text) 157 158 def test_commit(self): 159 r = requests.post(self.uri(self.resolve_container("/commit?container={}"))) 160 self.assertEqual(r.status_code, 200, r.text) 161 self.assertId(r.content) 162 163 obj = r.json() 164 self.assertIsInstance(obj, dict) 165 166 def test_prune(self): 167 name = f"Container_{random.getrandbits(160):x}" 168 169 r = requests.post( 170 self.podman_url + f"/v1.40/containers/create?name={name}", 171 json={ 172 "Cmd": ["cp", "/etc/motd", "/motd.size_test"], 173 "Image": "alpine:latest", 174 "NetworkDisabled": True, 175 }, 176 ) 177 self.assertEqual(r.status_code, 201, r.text) 178 create = r.json() 179 180 r = requests.post(self.podman_url + f"/v1.40/containers/{create['Id']}/start") 181 self.assertEqual(r.status_code, 204, r.text) 182 183 r = requests.post(self.podman_url + f"/v1.40/containers/{create['Id']}/wait") 184 self.assertEqual(r.status_code, 200, r.text) 185 wait = r.json() 186 self.assertEqual(wait["StatusCode"], 0, wait["Error"]) 187 188 prune = requests.post(self.podman_url + "/v1.40/containers/prune") 189 self.assertEqual(prune.status_code, 200, prune.status_code) 190 prune_payload = prune.json() 191 self.assertGreater(prune_payload["SpaceReclaimed"], 0) 192 self.assertIn(create["Id"], prune_payload["ContainersDeleted"]) 193 194 # Delete any orphaned containers 195 r = requests.get(self.podman_url + "/v1.40/containers/json?all=true") 196 self.assertEqual(r.status_code, 200, r.text) 197 for self.resolve_container in r.json(): 198 requests.delete( 199 self.podman_url + f"/v1.40/containers/{self.resolve_container['Id']}?force=true" 200 ) 201 202 # Image prune here tied to containers freeing up 203 prune = requests.post(self.podman_url + "/v1.40/images/prune") 204 self.assertEqual(prune.status_code, 200, prune.text) 205 prune_payload = prune.json() 206 self.assertGreater(prune_payload["SpaceReclaimed"], 0) 207 208 # FIXME need method to determine which image is going to be "pruned" to fix test 209 # TODO should handler be recursive when deleting images? 210 # self.assertIn(img["Id"], prune_payload["ImagesDeleted"][1]["Deleted"]) 211 212 # FIXME (@vrothberg): I commented this line out during the `libimage` migration. 213 # It doesn't make sense to report anything to be deleted if the reclaimed space 214 # is zero. I think the test needs some rewrite. 215 # self.assertIsNotNone(prune_payload["ImagesDeleted"][1]["Deleted"]) 216 217 def test_status(self): 218 r = requests.post( 219 self.podman_url + "/v1.40/containers/create?name=topcontainer", 220 json={"Cmd": ["top"], "Image": "alpine:latest"}, 221 ) 222 self.assertEqual(r.status_code, 201, r.text) 223 payload = r.json() 224 container_id = payload["Id"] 225 self.assertIsNotNone(container_id) 226 227 r = requests.get( 228 self.podman_url + "/v1.40/containers/json", 229 params={"all": "true", "filters": f'{{"id":["{container_id}"]}}'}, 230 ) 231 self.assertEqual(r.status_code, 200, r.text) 232 payload = r.json() 233 self.assertEqual(payload[0]["Status"], "Created") 234 235 r = requests.post(self.podman_url + f"/v1.40/containers/{container_id}/start") 236 self.assertEqual(r.status_code, 204, r.text) 237 238 r = requests.get( 239 self.podman_url + "/v1.40/containers/json", 240 params={"all": "true", "filters": f'{{"id":["{container_id}"]}}'}, 241 ) 242 self.assertEqual(r.status_code, 200, r.text) 243 payload = r.json() 244 self.assertTrue(str(payload[0]["Status"]).startswith("Up")) 245 246 r = requests.post(self.podman_url + f"/v1.40/containers/{container_id}/pause") 247 self.assertEqual(r.status_code, 204, r.text) 248 249 r = requests.get( 250 self.podman_url + "/v1.40/containers/json", 251 params={"all": "true", "filters": f'{{"id":["{container_id}"]}}'}, 252 ) 253 self.assertEqual(r.status_code, 200, r.text) 254 payload = r.json() 255 self.assertTrue(str(payload[0]["Status"]).startswith("Up")) 256 self.assertTrue(str(payload[0]["Status"]).endswith("(Paused)")) 257 258 r = requests.post(self.podman_url + f"/v1.40/containers/{container_id}/unpause") 259 self.assertEqual(r.status_code, 204, r.text) 260 r = requests.post(self.podman_url + f"/v1.40/containers/{container_id}/stop") 261 self.assertEqual(r.status_code, 204, r.text) 262 263 r = requests.get( 264 self.podman_url + "/v1.40/containers/json", 265 params={"all": "true", "filters": f'{{"id":["{container_id}"]}}'}, 266 ) 267 self.assertEqual(r.status_code, 200, r.text) 268 payload = r.json() 269 self.assertTrue(str(payload[0]["Status"]).startswith("Exited")) 270 271 r = requests.delete(self.podman_url + f"/v1.40/containers/{container_id}") 272 self.assertEqual(r.status_code, 204, r.text) 273 274 def test_top_no_stream(self): 275 uri = self.uri(self.resolve_container("/containers/{}/top")) 276 q = queue.Queue() 277 278 def _impl(fifo): 279 fifo.put(requests.get(uri, params={"stream": False}, timeout=2)) 280 281 top = threading.Thread(target=_impl, args=(q,)) 282 top.start() 283 time.sleep(2) 284 self.assertFalse(top.is_alive(), f"GET {uri} failed to return in 2s") 285 286 qr = q.get(False) 287 self.assertEqual(qr.status_code, 200, qr.text) 288 289 qr.close() 290 top.join() 291 292 def test_top_stream(self): 293 uri = self.uri(self.resolve_container("/containers/{}/top")) 294 q = queue.Queue() 295 296 stop_thread = False 297 298 def _impl(fifo, stop): 299 try: 300 with requests.get(uri, params={"stream": True, "delay": 1}, stream=True) as r: 301 r.raise_for_status() 302 fifo.put(r) 303 for buf in r.iter_lines(chunk_size=None): 304 if stop(): 305 break 306 fifo.put(buf) 307 except Exception: 308 pass 309 310 top = threading.Thread(target=_impl, args=(q, (lambda: stop_thread))) 311 top.start() 312 time.sleep(4) 313 self.assertTrue(top.is_alive(), f"GET {uri} exited too soon") 314 stop_thread = True 315 316 for _ in range(10): 317 try: 318 qr = q.get_nowait() 319 if qr is not None: 320 self.assertEqual(qr.status_code, 200) 321 qr.close() 322 break 323 except queue.Empty: 324 pass 325 finally: 326 time.sleep(1) 327 else: 328 self.fail("Server failed to respond in 10s") 329 top.join() 330 331 def test_memory(self): 332 r = requests.post( 333 self.podman_url + "/v1.4.0/libpod/containers/create", 334 json={ 335 "Name": "memory", 336 "Cmd": ["top"], 337 "Image": "alpine:latest", 338 "Resource_Limits": { 339 "Memory":{ 340 "Limit": 1000, 341 }, 342 "CPU":{ 343 "Shares": 200, 344 }, 345 }, 346 }, 347 ) 348 self.assertEqual(r.status_code, 201, r.text) 349 payload = r.json() 350 container_id = payload["Id"] 351 self.assertIsNotNone(container_id) 352 353 r = requests.get(self.podman_url + f"/v1.40/containers/{container_id}/json") 354 self.assertEqual(r.status_code, 200, r.text) 355 self.assertId(r.content) 356 out = r.json() 357 self.assertEqual(2000, out["HostConfig"]["MemorySwap"]) 358 self.assertEqual(1000, out["HostConfig"]["Memory"]) 359 360 361 if __name__ == "__main__": 362 unittest.main()