class SystemIntegrationTest(base.IntegrationTest): """system call integration test""" def setUp(self): super().setUp() self.client = PodmanClient(base_url=self.socket_uri) self.addCleanup(self.client.close) def test_info(self): """integration: system info call""" output = self.client.info() self.assertTrue('host' in output) def test_version(self): """integration: system version call""" output = self.client.version() self.assertTrue('Platform' in output) self.assertTrue('Version' in output) self.assertTrue('ApiVersion' in output) def test_show_disk_usage(self): """integration: system disk usage call""" output = self.client.df() self.assertTrue('Images' in output) self.assertTrue('Containers' in output) self.assertTrue('Volumes' in output)
def test_unix_ping(self): with PodmanClient(base_url=f"unix://{self.socket_file}") as client: self.assertTrue(client.ping()) with PodmanClient( base_url=f"http+unix://{self.socket_file}") as client: self.assertTrue(client.ping())
class PodmanConnect: """Connect to the podman unix socket.""" def __init__(self, socket="/var/run/podman/podman.sock"): """Initialize the Directord pod connection class. Sets up the pod api object. :param socket: Socket path to connect to. :type socket: String """ self.pod = PodmanClient(base_url="unix://{socket}".format( socket=socket)) self.api = self.pod.api def __exit__(self, *args, **kwargs): """Close the connection and exit.""" self.close() def __enter__(self): """Return self for use within a context manager.""" return self def close(self): """Close the connection.""" self.pod.close()
class VolumeTestCase(unittest.TestCase): def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url="http+unix://localhost:9999") def tearDown(self) -> None: super().tearDown() self.client.close() def test_id(self): actual = Volume(attrs={"Name": "dbase"}) self.assertEqual(actual.id, "dbase") @requests_mock.Mocker() def test_remove(self, mock): adapter = mock.delete( "http+unix://localhost:9999/v3.0.0/libpod/volumes/dbase?force=True", status_code=204) mock.get("http+unix://localhost:9999/v3.0.0/libpod/volumes/dbase", json=FIRST_VOLUME) volume = self.client.volumes.get("dbase") volume.remove(force=True) self.assertTrue(adapter.called_once)
class VolumeTestCase(unittest.TestCase): def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url=tests.BASE_SOCK) def tearDown(self) -> None: super().tearDown() self.client.close() def test_id(self): actual = Volume(attrs={"Name": "dbase"}) self.assertEqual(actual.id, "dbase") @requests_mock.Mocker() def test_remove(self, mock): adapter = mock.delete(tests.BASE_URL + "/libpod/volumes/dbase?force=True", status_code=204) vol_manager = VolumesManager(self.client.api) volume = vol_manager.prepare_model(attrs=FIRST_VOLUME) volume.remove(force=True) self.assertTrue(adapter.called_once)
class TestPodmanClient(unittest.TestCase): """Test the PodmanClient() object.""" def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url='unix://*****:*****@mock.patch('requests.Session.close') def test_close(self, mock_close): self.client.close() mock_close.assert_called_once_with() @requests_mock.Mocker() def test_contextmanager(self, mock): body = { "host": { "arch": "amd65", "os": "linux", } } mock.get("http+unix://localhost:9999/v3.0.0/libpod/system/info", json=body) with PodmanClient(base_url="http+unix://localhost:9999") as client: actual = client.info() self.assertDictEqual(actual, body)
class ManifestTestCase(unittest.TestCase): def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url="http+unix://localhost:9999") def tearDown(self) -> None: super().tearDown() self.client.close() def test_podmanclient(self): manager = self.client.manifests self.assertIsInstance(manager, ManifestsManager) def test_list(self): with self.assertRaises(NotImplementedError): self.client.manifests.list() def test_name(self): with self.assertRaises(ValueError): manifest = Manifest(attrs={"names": ""}) _ = manifest.name with self.assertRaises(ValueError): manifest = Manifest() _ = manifest.name
def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url=tests.BASE_SOCK) def mocked_open(self, *args, **kwargs): return PodmanClientTestCase.opener(self, *args, **kwargs) self.mocked_open = mocked_open
def _podman_connect(self, podman_uri: str): logging.debug("Connecting to Podman API") try: client = PodmanClient(base_url=podman_uri, timeout=60) client.info() # info() will try to connect to the API except APIError as e: raise PoolManagerError(f"Could not connect to Podman API: {e}") self._podman_client = client
class TestPodmanClient(unittest.TestCase): """Test the PodmanClient() object.""" def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url='unix://*****:*****@mock.patch('requests.Session.close') def test_close(self, mock_close): self.client.close() mock_close.assert_called_once_with()
def test_ssh_ping(self): with PodmanClient( base_url= f"http+ssh://{getpass.getuser()}@localhost:22{self.socket_file}" ) as client: self.assertTrue(client.ping()) with PodmanClient( base_url= f"ssh://{getpass.getuser()}@localhost:22{self.socket_file}" ) as client: self.assertTrue(client.ping())
def __init__(self, socket="/var/run/podman/podman.sock"): """Initialize the Directord pod connection class. Sets up the pod api object. :param socket: Socket path to connect to. :type socket: String """ self.pod = PodmanClient(base_url="unix://{socket}".format( socket=socket)) self.api = self.pod.api
class EventsManagerTestCase(unittest.TestCase): def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url=tests.BASE_SOCK) def tearDown(self) -> None: super().tearDown() self.client.close() @requests_mock.Mocker() def test_list(self, mock): stream = [{ "Type": "pod", "Action": "create", "Actor": { "ID": "", "Attributes": { "image": "", "name": "", "containerExitCode": 0, }, }, "Scope": "local", "Time": 1615845480, "TimeNano": 1615845480, }] buffer = io.StringIO() for item in stream: buffer.write(json.JSONEncoder().encode(item)) buffer.write("\n") adapter = mock.get(tests.LIBPOD_URL + "/events", text=buffer.getvalue()) manager = EventsManager(client=self.client.api) actual = manager.list(decode=True) self.assertIsInstance(actual, GeneratorType) for item in actual: self.assertIsInstance(item, dict) self.assertEqual(item["Type"], "pod") actual = manager.list(decode=False) self.assertIsInstance(actual, GeneratorType) for item in actual: self.assertIsInstance(item, bytes) event = json.loads(item) self.assertEqual(event["Type"], "pod")
class SecretsTestCase(unittest.TestCase): def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url=tests.BASE_SOCK) def tearDown(self) -> None: super().tearDown() self.client.close() def test_podmanclient(self): manager = self.client.secrets self.assertIsInstance(manager, SecretsManager)
class PodsManagerTestCase(unittest.TestCase): def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url="http+unix://localhost:9999") def tearDown(self) -> None: super().tearDown() self.client.close() def test_podmanclient(self): manager = self.client.pods self.assertIsInstance(manager, PodsManager)
def setUp(self): super().setUp() self.client = PodmanClient(base_url=self.socket_uri) self.addCleanup(self.client.close) with suppress(NotFound): self.client.networks.get("integration_test").remove(force=True)
def setUp(self): super().setUp() self.client = PodmanClient(base_url=self.socket_uri) self.addCleanup(self.client.close) self.alpine_image = self.client.images.pull("quay.io/libpod/alpine", tag="latest")
def test_tcp_ping(self): podman = utils.PodmanLauncher( "tcp:localhost:8889", podman_path=base.IntegrationTest.podman, log_level=self.log_level, ) try: podman.start(check_socket=False) time.sleep(0.5) with PodmanClient(base_url=f"tcp:localhost:8889") as client: self.assertTrue(client.ping()) with PodmanClient(base_url=f"http://localhost:8889") as client: self.assertTrue(client.ping()) finally: podman.stop()
def test_swarm(self): with PodmanClient(base_url=tests.BASE_SOCK) as client: with self.assertRaises(NotImplementedError): # concrete property _ = client.swarm with self.assertRaises(NotImplementedError): # aliased property _ = client.nodes
def setUp(self): super().setUp() self.client = PodmanClient(base_url=self.socket_uri) self.addCleanup(self.client.close) self.alpine_image = self.client.images.pull("quay.io/libpod/alpine", tag="latest") # TODO should this use podman binary instead? for container in self.client.containers.list(): container.remove(force=True)
def test_contextmanager(self, mock): body = { "host": { "arch": "amd65", "os": "linux", } } mock.get(tests.BASE_URL + "/libpod/info", json=body) with PodmanClient(base_url="http+unix://localhost:9999") as client: actual = client.info() self.assertDictEqual(actual, body)
def test_connect(self): with mock.patch.multiple(Path, open=self.mocked_open, exists=MagicMock(return_value=True)): with PodmanClient(connection="testing") as client: self.assertEqual( client.api.base_url.geturl(), "http+ssh://qe@localhost:2222/run/podman/podman.sock", ) # Build path to support tests running as root or a user expected = Path(xdg.BaseDirectory.xdg_config_home ) / "containers" / "containers.conf" PodmanClientTestCase.opener.assert_called_with(expected)
def test_connect_default(self): with mock.patch.multiple(Path, open=self.mocked_open, exists=MagicMock(return_value=True)): with PodmanClient() as client: expected = "http+unix://" + urllib.parse.quote_plus( str( Path(xdg.BaseDirectory.get_runtime_dir(strict=False)) / "podman" / "podman.sock")) self.assertEqual(client.api.base_url.geturl(), expected) # Build path to support tests running as root or a user expected = Path(xdg.BaseDirectory.xdg_config_home ) / "containers" / "containers.conf" PodmanClientTestCase.opener.assert_called_with(expected)
def test_contextmanager(self, mock): body = { "host": { "arch": "amd65", "os": "linux", } } adapter = mock.get(tests.LIBPOD_URL + "/info", json=body) with PodmanClient(base_url=tests.BASE_SOCK) as client: actual = client.info() self.assertDictEqual(actual, body) self.assertIn("User-Agent", mock.last_request.headers) self.assertIn("PodmanPy/", mock.last_request.headers["User-Agent"], mock.last_request.headers)
def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url="http+unix://localhost:9999")
class ContainersTestCase(unittest.TestCase): def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url="http+unix://localhost:9999") def tearDown(self) -> None: super().tearDown() self.client.close() @requests_mock.Mocker() def test_remove(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.delete( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd?v=True&force=True", status_code=204, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") container.remove(v=True, force=True) @requests_mock.Mocker() def test_rename(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.post( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/rename", status_code=204, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") container.rename("good_galileo") self.assertEqual(container.attrs["Name"], "good_galileo") @requests_mock.Mocker() def test_rename_409(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.post( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/rename", status_code=204, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") with self.assertRaises(ValueError): container.rename() @requests_mock.Mocker() def test_restart(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.post( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/restart?timeout=10", status_code=204, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") container.restart(timeout=10) @requests_mock.Mocker() def test_start_dkeys(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.post( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/start" "?detachKeys=%5Ef%5Eu", status_code=204, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") container.start(detach_keys="^f^u") @requests_mock.Mocker() def test_start(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.post( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/start", status_code=204, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") container.start() @requests_mock.Mocker() def test_stats(self, mock): stream = [{ "Error": None, "Stats": [{ "ContainerId": "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd", "Name": "evil_ptolemy", "CPU": 1000.0, }], }] buffer = io.StringIO() for entry in stream: buffer.write(json.JSONEncoder().encode(entry)) buffer.write("\n") mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/stats" "?containers=87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd" "&stream=True", text=buffer.getvalue(), ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") stats = container.stats(decode=True) self.assertIsInstance(stats, Iterable) for entry in stats: self.assertIsInstance(entry, dict) for stat in entry["Stats"]: self.assertEqual( stat["ContainerId"], "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd", ) @requests_mock.Mocker() def test_stop(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.post( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/stop" "?all=True&timeout=10.0", status_code=204, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") container.stop(all=True, timeout=10.0) @requests_mock.Mocker() def test_stop_304(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.post( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/stop", json={ "cause": "container already stopped", "message": "container already stopped", "response": 304, }, status_code=304, ) with self.assertRaises(APIError): container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd" ) container.stop() @requests_mock.Mocker() def test_unpause(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.post( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/unpause", status_code=204, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") container.unpause() @requests_mock.Mocker() def test_pause(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.post( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/pause", status_code=204, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") container.pause() @requests_mock.Mocker() def test_wait(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.post( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/wait", status_code=204, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") container.wait() @requests_mock.Mocker() def test_diff(self, mock): payload = [ { "Path": "modified", "Kind": 0 }, { "Path": "added", "Kind": 1 }, { "Path": "deleted", "Kind": 2 }, ] mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/changes", json=payload, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") actual = container.diff() self.assertListEqual(actual, payload) @requests_mock.Mocker() def test_diff_404(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/changes", json={ "cause": "Container not found.", "message": "Container not found.", "response": 404, }, status_code=404, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") with self.assertRaises(NotFound): container.diff() @requests_mock.Mocker() def test_export(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) tarball = b'Yet another weird tarball...' body = io.BytesIO(tarball) mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/export", body=body, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") with io.BytesIO() as fd: for chunk in container.export(): fd.write(chunk) self.assertEqual(fd.getbuffer(), tarball) @requests_mock.Mocker() def test_get_archive(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) tarball = b'Yet another weird tarball...' body = io.BytesIO(tarball) header_value = { "name": "/etc/motd", "size": len(tarball), "mode": 0o444, "mtime": "20210309T12:49:0205:00", } encoded_value = base64.urlsafe_b64encode( json.dumps(header_value).encode("utf8")) mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/archive" "?path=/etc/motd", body=body, headers={ "x-docker-container-path-stat": encoded_value.decode("utf8") }, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") actual = container.get_archive("/etc/motd") self.assertEqual(len(actual), 2) self.assertEqual(actual[1]["name"], "/etc/motd") with io.BytesIO() as fd: for chunk in actual[0]: fd.write(chunk) self.assertEqual(fd.getbuffer(), tarball) @requests_mock.Mocker() def test_commit(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.post( "http+unix://localhost:9999/v3.0.0/libpod/commit" "?author=redhat&changes=ADD+%2Fetc%2Fmod&comment=This+is+a+unittest" "&container=87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd&format=docker" "&pause=True&repo=quay.local&tag=unittest", status_code=201, json={ "ID": "d2459aad75354ddc9b5b23f863786e279637125af6ba4d4a83f881866b3c903f" }, ) mock.get( "http+unix://localhost:9999/v3.0.0/libpod/images/" "d2459aad75354ddc9b5b23f863786e279637125af6ba4d4a83f881866b3c903f/json", json={ "Id": "d2459aad75354ddc9b5b23f863786e279637125af6ba4d4a83f881866b3c903f" }, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") image = container.commit( repository="quay.local", tag="unittest", author="redhat", changes=["ADD /etc/mod"], comment="This is a unittest", format="docker", message="This is a unittest", pause=True, ) self.assertEqual( image.id, "d2459aad75354ddc9b5b23f863786e279637125af6ba4d4a83f881866b3c903f") @requests_mock.Mocker() def test_put_archive(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.put( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/archive" "?path=%2Fetc%2Fmotd", status_code=200, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") tarball = b'Yet another weird tarball...' body = io.BytesIO(tarball) actual = container.put_archive(path="/etc/motd", data=body.getvalue()) self.assertTrue(actual) @requests_mock.Mocker() def test_put_archive_404(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock.put( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/archive" "?path=deadbeef", status_code=404, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") tarball = b'Yet another weird tarball...' body = io.BytesIO(tarball) actual = container.put_archive(path="deadbeef", data=body.getvalue()) self.assertFalse(actual) @requests_mock.Mocker() def test_top(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) body = { "Processes": [ [ 'jhonce', '2417', '2274', '0', 'Mar01', '?', '00:00:01', '/usr/bin/ssh-agent /bin/sh -c exec -l /bin/bash -c "/usr/bin/gnome-session"', ], [ 'jhonce', '5544', '3522', '0', 'Mar01', 'pts/1', '00:00:02', '-bash' ], [ 'jhonce', '6140', '3522', '0', 'Mar01', 'pts/2', '00:00:00', '-bash' ], ], "Titles": ["UID", "PID", "PPID", "C", "STIME", "TTY", "TIME CMD"], } mock.get( "http+unix://localhost:9999/v3.0.0/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/top", json=body, ) container = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") actual = container.top() self.assertDictEqual(actual, body)
def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url=tests.BASE_SOCK)
class NetworksManagerTestCase(unittest.TestCase): """Test NetworksManager area of concern. Note: Mock responses need to be coded for libpod returns. The python bindings are responsible for mapping to compatible output. """ def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url=tests.BASE_SOCK) def tearDown(self) -> None: super().tearDown() self.client.close() def test_podmanclient(self): manager = self.client.networks self.assertIsInstance(manager, NetworksManager) @requests_mock.Mocker() def test_get(self, mock): mock.get( tests.COMPATIBLE_URL + "/networks/podman", json=FIRST_NETWORK, ) actual = self.client.networks.get("podman") self.assertIsInstance(actual, Network) self.assertEqual( actual.id, "2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9" ) @requests_mock.Mocker() def test_get_libpod(self, mock): mock.get( tests.LIBPOD_URL + "/networks/podman/json", json=FIRST_NETWORK_LIBPOD, ) actual = self.client.networks.get("podman", compatible=False) self.assertIsInstance(actual, Network) self.assertEqual(actual.attrs["name"], "podman") @requests_mock.Mocker() def test_list(self, mock): mock.get( tests.COMPATIBLE_URL + "/networks", json=[FIRST_NETWORK, SECOND_NETWORK], ) actual = self.client.networks.list() self.assertEqual(len(actual), 2) self.assertIsInstance(actual[0], Network) self.assertEqual( actual[0].id, "2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9" ) self.assertEqual(actual[0].attrs["Name"], "podman") self.assertIsInstance(actual[1], Network) self.assertEqual( actual[1].id, "3549b0028b75d981cdda2e573e9cb49dedc200185876df299f912b79f69dabd8" ) self.assertEqual(actual[1].name, "database") @requests_mock.Mocker() def test_list_libpod(self, mock): mock.get( tests.LIBPOD_URL + "/networks/json", json=FIRST_NETWORK_LIBPOD + SECOND_NETWORK_LIBPOD, ) actual = self.client.networks.list(compatible=False) self.assertEqual(len(actual), 2) self.assertIsInstance(actual[0], Network) self.assertEqual( actual[0].id, "2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9" ) self.assertEqual(actual[0].attrs["name"], "podman") self.assertIsInstance(actual[1], Network) self.assertEqual( actual[1].id, "3549b0028b75d981cdda2e573e9cb49dedc200185876df299f912b79f69dabd8" ) self.assertEqual(actual[1].name, "database") @requests_mock.Mocker() def test_create(self, mock): adapter = mock.post( tests.LIBPOD_URL + "/networks/create?name=podman", json={ "Filename": "/home/developer/.config/cni/net.d/podman.conflist", }, ) mock.get( tests.COMPATIBLE_URL + "/networks/podman", json=FIRST_NETWORK, ) pool = IPAMPool(subnet="172.16.0.0/12", iprange="172.16.0.0/16", gateway="172.31.255.254") ipam = IPAMConfig(pool_configs=[pool]) network = self.client.networks.create( "podman", disabled_dns=True, enable_ipv6=False, ipam=ipam ) self.assertIsInstance(network, Network) self.assertEqual(adapter.call_count, 1) self.assertDictEqual( adapter.last_request.json(), { 'DisabledDNS': True, 'Gateway': '172.31.255.254', 'IPv6': False, 'Range': {'IP': '172.16.0.0', 'Mask': "//8AAA=="}, 'Subnet': {'IP': '172.16.0.0', 'Mask': "//AAAA=="}, }, ) self.assertEqual(network.name, "podman") @requests_mock.Mocker() def test_create_defaults(self, mock): adapter = mock.post( tests.LIBPOD_URL + "/networks/create?name=podman", json={ "Filename": "/home/developer/.config/cni/net.d/podman.conflist", }, ) mock.get( tests.COMPATIBLE_URL + "/networks/podman", json=FIRST_NETWORK, ) network = self.client.networks.create("podman") self.assertEqual(adapter.call_count, 1) self.assertEqual(network.name, "podman") self.assertEqual(len(adapter.last_request.json()), 0) @requests_mock.Mocker() def test_prune(self, mock): mock.post( tests.COMPATIBLE_URL + "/networks/prune", json={"NetworksDeleted": ["podman", "database"]}, ) actual = self.client.networks.prune() self.assertListEqual(actual["NetworksDeleted"], ["podman", "database"]) @requests_mock.Mocker() def test_prune_libpod(self, mock): mock.post( tests.LIBPOD_URL + "/networks/prune", json=[ {"Name": "podman", "Error": None}, {"Name": "database", "Error": None}, ], ) actual = self.client.networks.prune(compatible=False) self.assertListEqual(actual["NetworksDeleted"], ["podman", "database"])
class RegistryDataTestCase(unittest.TestCase): """Test RegistryData. Note: Mock responses need to be coded for libpod returns. The python bindings are responsible for mapping to compatible output. """ def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url="http+unix://localhost:9999") def tearDown(self) -> None: super().tearDown() self.client.close() @requests_mock.Mocker() def test_init(self, mock): mock.get( "http+unix://localhost:9999/v3.0.0/libpod/images/" "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/json", json=FIRST_IMAGE, ) actual = RegistryData( "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab", client=self.client.api, collection=ImagesManager(client=self.client.api), ) self.assertEqual( actual.id, "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab" ) def test_platform(self): rd = RegistryData( "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab", attrs=FIRST_IMAGE, collection=ImagesManager(client=self.client.api), ) self.assertTrue(rd.has_platform("linux/amd64/fedora")) def test_platform_dict(self): rd = RegistryData( "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab", attrs=FIRST_IMAGE, collection=ImagesManager(client=self.client.api), ) self.assertTrue(rd.has_platform({"os": "linux", "architecture": "amd64"})) def test_platform_404(self): rd = RegistryData( "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab", attrs=FIRST_IMAGE, collection=ImagesManager(client=self.client.api), ) self.assertFalse(rd.has_platform({"os": "COS", "architecture": "X-MP"})) def test_platform_409(self): rd = RegistryData( "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab", attrs=FIRST_IMAGE, collection=ImagesManager(client=self.client.api), ) with self.assertRaises(InvalidArgument): rd.has_platform(list()) def test_platform_500(self): rd = RegistryData( "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab", attrs=FIRST_IMAGE, collection=ImagesManager(client=self.client.api), ) with self.assertRaises(InvalidArgument): rd.has_platform("This/is/not/a/legal/image/name")
class ContainersManagerTestCase(unittest.TestCase): """Test ContainersManager area of concern. Note: Mock responses need to be coded for libpod returns. The python bindings are responsible for mapping to compatible output. """ def setUp(self) -> None: super().setUp() self.client = PodmanClient(base_url=tests.BASE_SOCK) def tearDown(self) -> None: super().tearDown() self.client.close() def test_podmanclient(self): manager = self.client.containers self.assertIsInstance(manager, ContainersManager) @requests_mock.Mocker() def test_get(self, mock): mock.get( tests.BASE_URL + "/libpod/containers" "/87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) actual = self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") self.assertEqual( actual.id, "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") @requests_mock.Mocker() def test_get_404(self, mock): mock.get( tests.BASE_URL + "/libpod/containers" "/87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json={ "cause": "Container not found.", "message": "Container not found.", "response": 404, }, status_code=404, ) with self.assertRaises(NotFound): self.client.containers.get( "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd" ) @requests_mock.Mocker() def test_list_empty(self, mock): mock.get( tests.BASE_URL + "/libpod/containers/json", text="[]", ) actual = self.client.containers.list() self.assertListEqual(actual, []) @requests_mock.Mocker() def test_list(self, mock): mock.get( tests.BASE_URL + "/libpod/containers/json", json=[FIRST_CONTAINER, SECOND_CONTAINER], ) actual = self.client.containers.list() self.assertIsInstance(actual, list) self.assertEqual( actual[0].id, "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") self.assertEqual( actual[1].id, "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03") @requests_mock.Mocker() def test_list_filtered(self, mock): mock.get( tests.BASE_URL + "/libpod/containers/json?" "all=True" "&filters=%7B" "%22before%22%3A" "+%5B%226dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03%22%5D%2C" "+%22since%22%3A" "+%5B%2287e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd%22%5D%2C" "+%22status%22%3A+%5B%22running%22%5D%7D", json=[FIRST_CONTAINER, SECOND_CONTAINER], ) actual = self.client.containers.list( all=True, filters={"status": "running"}, since= "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd", before= "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03", ) self.assertIsInstance(actual, list) self.assertEqual( actual[0].id, "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") self.assertEqual( actual[1].id, "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03") @requests_mock.Mocker() def test_list_no_filters(self, mock): mock.get( tests.BASE_URL + "/libpod/containers/json", json=[FIRST_CONTAINER, SECOND_CONTAINER], ) actual = self.client.containers.list() self.assertIsInstance(actual, list) self.assertEqual( actual[0].id, "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd") self.assertEqual( actual[1].id, "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03") @requests_mock.Mocker() def test_prune(self, mock): mock.post( tests.BASE_URL + "/libpod/containers/prune", json=[ { "Id": "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd", "Size": 1024, }, { "Id": "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03", "Size": 1024, }, ], ) actual = self.client.containers.prune() self.assertDictEqual( actual, { "ContainersDeleted": [ "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd", "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03", ], "SpaceReclaimed": 2048, }, ) @requests_mock.Mocker() def test_create(self, mock): mock.post( tests.BASE_URL + "/libpod/containers/create", status_code=201, json={ "Id": "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd", "Warnings": [], }, ) mock.get( tests.BASE_URL + "/libpod/containers" "/87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) actual = self.client.containers.create("fedora", "/usr/bin/ls", cpu_count=9999) self.assertIsInstance(actual, Container) @requests_mock.Mocker() def test_create_404(self, mock): mock.post( tests.BASE_URL + "/libpod/containers/create", status_code=404, json={ "cause": "Image not found", "message": "Image not found", "response": 404, }, ) with self.assertRaises(ImageNotFound): self.client.containers.create("fedora", "/usr/bin/ls", cpu_count=9999) def test_create_unsupported_key(self): with self.assertRaises(TypeError) as e: self.client.containers.create("fedora", "/usr/bin/ls", blkio_weight=100.0) def test_create_unknown_key(self): with self.assertRaises(TypeError) as e: self.client.containers.create("fedora", "/usr/bin/ls", unknown_key=100.0) @requests_mock.Mocker() def test_run_detached(self, mock): mock.post( tests.BASE_URL + "/libpod/containers/create", status_code=201, json={ "Id": "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd", "Warnings": [], }, ) mock.post( tests.BASE_URL + "/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/start", status_code=204, ) mock.get( tests.BASE_URL + "/libpod/containers" "/87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) with patch.multiple(Container, logs=DEFAULT, wait=DEFAULT, autospec=True) as mock_container: mock_container["logs"].return_value = list() mock_container["wait"].return_value = {"StatusCode": 0} actual = self.client.containers.run("fedora", "/usr/bin/ls", detach=True) self.assertIsInstance(actual, Container) @requests_mock.Mocker() def test_run(self, mock): mock.post( tests.BASE_URL + "/libpod/containers/create", status_code=201, json={ "Id": "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd", "Warnings": [], }, ) mock.post( tests.BASE_URL + "/libpod/containers/" "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/start", status_code=204, ) mock.get( tests.BASE_URL + "/libpod/containers" "/87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/json", json=FIRST_CONTAINER, ) mock_logs = ( b"This is a unittest - line 1", b"This is a unittest - line 2", ) with patch.multiple(Container, logs=DEFAULT, wait=DEFAULT, autospec=True) as mock_container: mock_container["wait"].return_value = {"StatusCode": 0} with self.subTest("Results not streamed"): mock_container["logs"].return_value = iter(mock_logs) actual = self.client.containers.run("fedora", "/usr/bin/ls") self.assertIsInstance(actual, bytes) self.assertEqual( actual, b'This is a unittest - line 1This is a unittest - line 2') # iter() cannot be reset so subtests used to create new instance with self.subTest("Stream results"): mock_container["logs"].return_value = iter(mock_logs) actual = self.client.containers.run("fedora", "/usr/bin/ls", stream=True) self.assertNotIsInstance(actual, bytes) self.assertIsInstance(actual, Iterator) self.assertEqual(next(actual), b"This is a unittest - line 1") self.assertEqual(next(actual), b"This is a unittest - line 2")