github.com/AbhinandanKurakure/podman/v3@v3.4.10/test/python/docker/compat/test_images.py (about) 1 import collections 2 import io 3 import os 4 import subprocess 5 import sys 6 import time 7 import unittest 8 9 from docker import DockerClient, errors 10 from docker.errors import APIError 11 12 from test.python.docker import Podman 13 from test.python.docker.compat import common, constant 14 15 16 class TestImages(unittest.TestCase): 17 podman = None # initialized podman configuration for tests 18 service = None # podman service instance 19 20 def setUp(self): 21 super().setUp() 22 self.client = DockerClient(base_url="tcp://127.0.0.1:8080", timeout=15) 23 24 TestImages.podman.restore_image_from_cache(self.client) 25 26 def tearDown(self): 27 common.remove_all_images(self.client) 28 self.client.close() 29 return super().tearDown() 30 31 @classmethod 32 def setUpClass(cls): 33 super().setUpClass() 34 TestImages.podman = Podman() 35 TestImages.service = TestImages.podman.open( 36 "system", "service", "tcp:127.0.0.1:8080", "--time=0" 37 ) 38 # give the service some time to be ready... 39 time.sleep(2) 40 41 returncode = TestImages.service.poll() 42 if returncode is not None: 43 raise subprocess.CalledProcessError(returncode, "podman system service") 44 45 @classmethod 46 def tearDownClass(cls): 47 TestImages.service.terminate() 48 stdout, stderr = TestImages.service.communicate(timeout=0.5) 49 if stdout: 50 sys.stdout.write("\nImages Service Stdout:\n" + stdout.decode("utf-8")) 51 if stderr: 52 sys.stderr.write("\nImAges Service Stderr:\n" + stderr.decode("utf-8")) 53 54 TestImages.podman.tear_down() 55 return super().tearDownClass() 56 57 def test_tag_valid_image(self): 58 """Validates if the image is tagged successfully""" 59 alpine = self.client.images.get(constant.ALPINE) 60 self.assertTrue(alpine.tag("demo", constant.ALPINE_SHORTNAME)) 61 62 alpine = self.client.images.get(constant.ALPINE) 63 for t in alpine.tags: 64 self.assertIn("alpine", t) 65 66 # @unittest.skip("doesn't work now") 67 def test_retag_valid_image(self): 68 """Validates if name updates when the image is retagged""" 69 alpine = self.client.images.get(constant.ALPINE) 70 self.assertTrue(alpine.tag("demo", "rename")) 71 72 alpine = self.client.images.get(constant.ALPINE) 73 self.assertNotIn("demo:test", alpine.tags) 74 75 def test_list_images(self): 76 """List images""" 77 self.assertEqual(len(self.client.images.list()), 1) 78 79 # Add more images 80 self.client.images.pull(constant.BB) 81 self.assertEqual(len(self.client.images.list()), 2) 82 83 # List images with filter 84 self.assertEqual(len(self.client.images.list(filters={"reference": "alpine"})), 1) 85 86 # Disabled due to dependence on potentially unstable search results and 87 # failures because podman truncates image descriptions which otherwise 88 # would satisfy test condition. 89 #def test_search_image(self): 90 # """Search for image""" 91 # for r in self.client.images.search("alpine"): 92 # # registry matches if string is in either one 93 # self.assertIn("alpine", r["Name"]+" "+r["Description"].lower()) 94 95 def test_search_bogus_image(self): 96 """Search for bogus image should throw exception""" 97 try: 98 r = self.client.images.search("bogus/bogus") 99 except: 100 return 101 self.assertTrue(len(r) == 0) 102 103 def test_remove_image(self): 104 """Remove image""" 105 # Check for error with wrong image name 106 with self.assertRaises(errors.NotFound): 107 self.client.images.remove("dummy") 108 self.assertEqual(len(self.client.images.list()), 1) 109 110 self.client.images.remove(constant.ALPINE) 111 self.assertEqual(len(self.client.images.list()), 0) 112 113 def test_image_history(self): 114 """Image history""" 115 img = self.client.images.get(constant.ALPINE) 116 history = img.history() 117 image_id = img.id[7:] if img.id.startswith("sha256:") else img.id 118 119 found = False 120 for change in history: 121 found |= image_id in change.values() 122 self.assertTrue(found, f"image id {image_id} not found in history") 123 124 def test_get_image_exists_not(self): 125 """Negative test for get image""" 126 with self.assertRaises(errors.NotFound): 127 response = self.client.images.get("image_does_not_exists") 128 collections.deque(response) 129 130 def test_save_image(self): 131 """Export Image""" 132 image = self.client.images.pull(constant.BB) 133 134 file = os.path.join(TestImages.podman.image_cache, "busybox.tar") 135 with open(file, mode="wb") as tarball: 136 for frame in image.save(named=True): 137 tarball.write(frame) 138 sz = os.path.getsize(file) 139 self.assertGreater(sz, 0) 140 141 def test_load_image(self): 142 """Import|Load Image""" 143 self.assertEqual(len(self.client.images.list()), 1) 144 145 image = self.client.images.pull(constant.BB) 146 file = os.path.join(TestImages.podman.image_cache, "busybox.tar") 147 with open(file, mode="wb") as tarball: 148 for frame in image.save(): 149 tarball.write(frame) 150 151 with open(file, mode="rb") as saved: 152 _ = self.client.images.load(saved) 153 154 self.assertEqual(len(self.client.images.list()), 2) 155 156 def test_load_corrupt_image(self): 157 """Import|Load Image failure""" 158 tarball = io.BytesIO("This is a corrupt tarball".encode("utf-8")) 159 with self.assertRaises(APIError): 160 self.client.images.load(tarball) 161 162 def test_build_image(self): 163 labels = {"apple": "red", "grape": "green"} 164 _ = self.client.images.build( 165 path="test/python/docker/build_labels", labels=labels, tag="labels", isolation="default" 166 ) 167 image = self.client.images.get("labels") 168 self.assertEqual(image.labels["apple"], labels["apple"]) 169 self.assertEqual(image.labels["grape"], labels["grape"]) 170 171 172 if __name__ == "__main__": 173 # Setup temporary space 174 unittest.main()