Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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()
Ejemplo n.º 7
0
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")
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
class VolumesManagerTestCase(unittest.TestCase):
    """Test VolumesManager 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.volumes
        self.assertIsInstance(manager, VolumesManager)

    @requests_mock.Mocker()
    def test_create(self, mock):
        adapter = mock.post(
            tests.LIBPOD_URL + "/volumes/create",
            json=FIRST_VOLUME,
            status_code=requests.codes.created,
        )

        actual = self.client.volumes.create(
            "dbase",
            labels={
                "BackupRequired": True,
            },
        )
        self.assertIsInstance(actual, Volume)
        self.assertTrue(adapter.called_once)
        self.assertDictEqual(
            adapter.last_request.json(),
            {
                "Name": "dbase",
                "Labels": {
                    "BackupRequired": True,
                },
            },
        )
        self.assertEqual(actual.id, "dbase")
        self.assertDictEqual(
            actual.attrs["Labels"],
            {
                "BackupRequired": True,
            },
        )

    @requests_mock.Mocker()
    def test_get(self, mock):
        mock.get(
            tests.LIBPOD_URL + "/volumes/dbase/json",
            json=FIRST_VOLUME,
        )

        actual = self.client.volumes.get("dbase")
        self.assertIsInstance(actual, Volume)
        self.assertDictEqual(actual.attrs, FIRST_VOLUME)
        self.assertEqual(actual.id, actual.name)

    @requests_mock.Mocker()
    def test_get_404(self, mock):
        adapter = mock.get(
            tests.LIBPOD_URL + "/volumes/dbase/json",
            text="Not Found",
            status_code=404,
        )

        with self.assertRaises(NotFound):
            self.client.volumes.get("dbase")
        self.assertTrue(adapter.called_once)

    @requests_mock.Mocker()
    def test_list(self, mock):
        mock.get(tests.LIBPOD_URL + "/volumes/json",
                 json=[FIRST_VOLUME, SECOND_VOLUME])

        actual = self.client.volumes.list(filters={"driver": "local"})
        self.assertEqual(len(actual), 2)

        self.assertIsInstance(actual[0], Volume)
        self.assertEqual(actual[0].name, "dbase")

        self.assertIsInstance(actual[1], Volume)
        self.assertEqual(actual[1].id, "source")

    @requests_mock.Mocker()
    def test_list_404(self, mock):
        mock.get(tests.LIBPOD_URL + "/volumes/json",
                 text="Not Found",
                 status_code=404)

        actual = self.client.volumes.list()
        self.assertIsInstance(actual, list)
        self.assertEqual(len(actual), 0)

    @requests_mock.Mocker()
    def test_prune(self, mock):
        mock.post(
            tests.LIBPOD_URL + "/volumes/prune",
            json=[
                {
                    "Id": "dbase",
                    "Size": 1024
                },
                {
                    "Id": "source",
                    "Size": 1024
                },
            ],
        )

        actual = self.client.volumes.prune()
        self.assertDictEqual(actual, {
            "VolumesDeleted": ["dbase", "source"],
            "SpaceReclaimed": 2048
        })
Ejemplo n.º 11
0
class TestClientImagesManager(unittest.TestCase):
    """Test ImagesManager 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.images
        self.assertIsInstance(manager, ImagesManager)

    @requests_mock.Mocker()
    def test_list_empty(self, mock):
        """Unit test Images list()."""
        mock.get(
            tests.BASE_URL + "/libpod/images/json",
            text="[]",
        )

        images = self.client.images.list()
        self.assertEqual(len(images), 0)

    @requests_mock.Mocker()
    def test_list_1(self, mock):
        """Unit test Images list()."""
        mock.get(
            tests.BASE_URL + "/libpod/images/json",
            json=[FIRST_IMAGE],
        )

        images = self.client.images.list()
        self.assertEqual(len(images), 1)

        self.assertIsInstance(images[0], Image)

        self.assertEqual(str(images[0]),
                         "<Image: 'fedora:latest', 'fedora:33'>")

        self.assertEqual(
            images[0].id,
            "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab"
        )

        self.assertIsInstance(images[0].labels, dict)
        self.assertEqual(len(images[0].labels), 1)

        self.assertEqual(images[0].short_id, "sha256:326dd9d7ad")

        self.assertIsInstance(images[0].tags, list)
        self.assertEqual(len(images[0].tags), 2)

    @requests_mock.Mocker()
    def test_list_2(self, mock):
        """Unit test Images list()."""
        mock.get(
            tests.BASE_URL + "/libpod/images/json",
            json=[FIRST_IMAGE, SECOND_IMAGE],
        )

        images = self.client.images.list()
        self.assertEqual(len(images), 2)

        self.assertIsInstance(images[0], Image)
        self.assertIsInstance(images[1], Image)

        self.assertEqual(images[1].short_id, "c4b16966ec")
        self.assertIsInstance(images[1].labels, dict)
        self.assertEqual(len(images[1].labels), 0)

        self.assertIsInstance(images[1].tags, list)
        self.assertEqual(len(images[1].tags), 0)

    @requests_mock.Mocker()
    def test_list_filters(self, mock):
        """Unit test filters param for Images list()."""
        mock.get(
            tests.BASE_URL + "/libpod/images/json"
            "?filters=%7B%22dangling%22%3A+%5B%22True%22%5D%7D",
            json=[FIRST_IMAGE],
        )

        images = self.client.images.list(filters={"dangling": True})
        self.assertEqual(
            images[0].id,
            "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab"
        )

    @requests_mock.Mocker()
    def test_list_all(self, mock):
        """Unit test filters param for Images list()."""
        mock.get(
            tests.BASE_URL + "/libpod/images/json?all=true",
            json=[FIRST_IMAGE],
        )

        images = self.client.images.list(all=True)
        self.assertEqual(
            images[0].id,
            "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab"
        )

    @requests_mock.Mocker()
    def test_prune(self, mock):
        """Unit test Images prune()."""
        mock.post(
            tests.BASE_URL + "/libpod/images/prune",
            json=[{
                "Id":
                "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab",
                "Err": None,
                "Size": 1024,
            }],
        )

        results = self.client.images.prune()
        self.assertIn("ImagesDeleted", results)
        self.assertIn("SpaceReclaimed", results)

        self.assertEqual(
            results["ImagesDeleted"][0]["Deleted"],
            "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab",
        )
        self.assertEqual(results["SpaceReclaimed"], 1024)

    @requests_mock.Mocker()
    def test_prune_filters(self, mock):
        """Unit test filters param for Images prune()."""
        mock.post(
            tests.BASE_URL + "/libpod/images/prune"
            "?filters=%7B%22dangling%22%3A+%5B%22True%22%5D%7D",
            json=[
                {
                    "Id":
                    "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab",
                    "Size": 1024,
                },
                {
                    "Id":
                    "c4b16966ecd94ffa910eab4e630e24f259bf34a87e924cd4b1434f267b0e354e",
                    "Size": 1024,
                },
            ],
        )

        report = self.client.images.prune(filters={"dangling": True})
        self.assertIn("ImagesDeleted", report)
        self.assertIn("SpaceReclaimed", report)

        self.assertEqual(report["SpaceReclaimed"], 2048)

        deleted = [
            r["Deleted"] for r in report["ImagesDeleted"] if "Deleted" in r
        ]
        self.assertEqual(len(deleted), 2)
        self.assertIn(
            "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab",
            deleted)
        self.assertGreater(len("".join(deleted)), 0)

        untagged = [
            r["Untagged"] for r in report["ImagesDeleted"] if "Untagged" in r
        ]
        self.assertEqual(len(untagged), 2)
        self.assertEqual(len("".join(untagged)), 0)

    @requests_mock.Mocker()
    def test_prune_failure(self, mock):
        """Unit test to report error carried in response body."""
        mock.post(
            tests.BASE_URL + "/libpod/images/prune",
            json=[{
                "Err": "Test prune failure in response body.",
            }],
        )

        with self.assertRaises(APIError) as e:
            self.client.images.prune()
        self.assertEqual(e.exception.explanation,
                         "Test prune failure in response body.")

    @requests_mock.Mocker()
    def test_get(self, mock):
        mock.get(
            tests.BASE_URL + "/libpod/images/fedora%3Alatest/json",
            json=FIRST_IMAGE,
        )

        image = self.client.images.get("fedora:latest")
        self.assertIsInstance(image, Image)
        self.assertDictEqual(FIRST_IMAGE["Labels"], image.attrs["Labels"])

    @requests_mock.Mocker()
    def test_get_oserror(self, mock):
        mock.get(
            tests.BASE_URL + "/libpod/images/bad_image/json",
            exc=OSError,
        )

        with self.assertRaises(APIError) as e:
            _ = self.client.images.get("bad_image")
        self.assertEqual(
            str(e.exception),
            tests.BASE_URL +
            "/libpod/images/bad_image/json (GET operation failed)",
        )

    @requests_mock.Mocker()
    def test_get_404(self, mock):
        mock.get(
            tests.BASE_URL + "/libpod/images/bad_image/json",
            status_code=404,
            json={
                "cause": "Image not found",
                "message": "Image not found",
                "response": 404,
            },
        )

        with self.assertRaises(ImageNotFound):
            _ = self.client.images.get("bad_image")

    @requests_mock.Mocker()
    def test_get_500(self, mock):
        mock.get(
            tests.BASE_URL + "/libpod/images/bad_image/json",
            status_code=500,
            json={
                "cause": "Server error",
                "message": "Server error",
                "response": 500,
            },
        )

        with self.assertRaises(APIError):
            _ = self.client.images.get("bad_image")

    @requests_mock.Mocker()
    def test_remove(self, mock):
        mock.delete(
            tests.BASE_URL + "/libpod/images/fedora:latest",
            json={
                "Untagged": [
                    "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab"
                ],
                "Deleted": [
                    "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab",
                    "c4b16966ecd94ffa910eab4e630e24f259bf34a87e924cd4b1434f267b0e354e",
                ],
                "Errors": [],
                "ExitCode":
                0,
            },
        )

        report = self.client.images.remove("fedora:latest")
        self.assertEqual(len(report), 4)

        deleted = [r["Deleted"] for r in report if "Deleted" in r]
        self.assertEqual(len(deleted), 2)

        untagged = [r["Untagged"] for r in report if "Untagged" in r]
        self.assertEqual(len(untagged), 1)

        errors = [r["Errors"] for r in report if "Errors" in r]
        self.assertEqual(len(errors), 0)

        codes = [r["ExitCode"] for r in report if "ExitCode" in r]
        self.assertEqual(len(codes), 1)
        self.assertEqual(codes[0], 0)

    @requests_mock.Mocker()
    def test_load(self, mock):
        mock.post(
            tests.BASE_URL + "/libpod/images/load",
            json={"Names": ["quay.io/fedora:latest"]},
        )
        mock.get(
            tests.BASE_URL + "/libpod/images/quay.io%2Ffedora%3Alatest/json",
            json=FIRST_IMAGE,
        )

        gntr = self.client.images.load(b'This is a weird tarball...')
        self.assertIsInstance(gntr, types.GeneratorType)

        report = list(gntr)
        self.assertEqual(len(report), 1)
        self.assertEqual(
            report[0].id,
            "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab"
        )

    @requests_mock.Mocker()
    def test_search(self, mock):
        mock.get(
            tests.BASE_URL + "/libpod/images/search?term=fedora&noTrunc=true",
            json=[
                {
                    "description": "mock term=fedora search",
                    "is_official": False,
                    "is_automated": False,
                    "name": "quay.io/libpod/fedora",
                    "star_count": 0,
                },
            ],
        )

        report = self.client.images.search("fedora")
        self.assertEqual(len(report), 1)

        self.assertEqual(report[0]["name"], "quay.io/libpod/fedora")

    @requests_mock.Mocker()
    def test_search_oserror(self, mock):
        mock.get(
            tests.BASE_URL + "/libpod/images/search?term=fedora&noTrunc=true",
            exc=OSError,
        )

        with self.assertRaises(OSError):
            self.client.images.search("fedora")

    @requests_mock.Mocker()
    def test_search_500(self, mock):
        mock.get(
            tests.BASE_URL + "/libpod/images/search?term=fedora&noTrunc=true",
            status_code=500,
            json={
                "cause": "Server error",
                "message": "Server error",
                "response": 500,
            },
        )

        with self.assertRaises(OSError):
            self.client.images.search("fedora")

    @requests_mock.Mocker()
    def test_search_limit(self, mock):
        mock.get(
            tests.BASE_URL +
            "/libpod/images/search?term=fedora&noTrunc=true&limit=5",
            json=[
                {
                    "description": "mock term=fedora search",
                    "is_official": False,
                    "is_automated": False,
                    "name": "quay.io/libpod/fedora",
                    "star_count": 0,
                },
            ],
        )

        report = self.client.images.search("fedora", limit=5)
        self.assertEqual(len(report), 1)

        self.assertEqual(report[0]["name"], "quay.io/libpod/fedora")

    @requests_mock.Mocker()
    def test_search_filters(self, mock):
        mock.get(
            tests.BASE_URL + "/libpod/images/search"
            "?filters=%7B%22stars%22%3A+%5B%225%22%5D%7D&noTrunc=True&term=fedora",
            json=[
                {
                    "description": "mock term=fedora search",
                    "is_official": False,
                    "is_automated": False,
                    "name": "quay.io/libpod/fedora",
                    "star_count": 0,
                },
            ],
        )

        report = self.client.images.search("fedora", filters={"stars": 5})
        self.assertEqual(len(report), 1)

        self.assertEqual(report[0]["name"], "quay.io/libpod/fedora")

    @requests_mock.Mocker()
    def test_push(self, mock):
        mock.post(tests.BASE_URL + "/libpod/images/quay.io%2Ffedora/push")

        report = self.client.images.push("quay.io/fedora", "latest")

        expected = r"""{"status": "Pushing repository quay.io/fedora (1 tags)"}
{"status": "Pushing", "progressDetail": {}, "id": "quay.io/fedora"}
"""
        self.assertEqual(report, expected)

    @requests_mock.Mocker()
    def test_pull(self, mock):
        image_id = "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab"
        mock.post(
            tests.BASE_URL + "/libpod/images/pull"
            "?reference=quay.io%2Ffedora%3Alatest",
            json={
                "error": "",
                "id": image_id,
                "images": [image_id],
                "stream": "",
            },
        )
        mock.get(
            tests.BASE_URL + "/libpod/images"
            "/sha256%3A326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/json",
            json=FIRST_IMAGE,
        )

        image = self.client.images.pull("quay.io/fedora", "latest")
        self.assertEqual(image.id, image_id)

    @requests_mock.Mocker()
    def test_pull_enhanced(self, mock):
        image_id = "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab"
        mock.post(
            tests.BASE_URL + "/libpod/images/pull"
            "?reference=quay.io%2Ffedora%3Alatest",
            json={
                "error": "",
                "id": image_id,
                "images": [image_id],
                "stream": "",
            },
        )
        mock.get(
            tests.BASE_URL + "/libpod/images"
            "/sha256%3A326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/json",
            json=FIRST_IMAGE,
        )

        image = self.client.images.pull("quay.io/fedora:latest")
        self.assertEqual(image.id, image_id)

    @requests_mock.Mocker()
    def test_pull_platform(self, mock):
        image_id = "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab"
        adapter = mock.post(
            tests.BASE_URL +
            "/libpod/images/pull?reference=quay.io%2Ffedora%3Alatest&OS=linux",
            json={
                "error": "",
                "id": image_id,
                "images": [image_id],
                "stream": "",
            },
        )
        mock.get(
            tests.BASE_URL + "/libpod/images"
            "/sha256%3A326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/json",
            json=FIRST_IMAGE,
        )

        image = self.client.images.pull("quay.io/fedora:latest",
                                        platform="linux")
        self.assertEqual(image.id, image_id)
        self.assertTrue(adapter.called_once)

    @requests_mock.Mocker()
    def test_pull_2x(self, mock):
        image_id = "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab"
        mock.post(
            tests.BASE_URL + "/libpod/images/pull"
            "?reference=quay.io%2Ffedora&allTags=True",
            json={
                "error":
                "",
                "id":
                image_id,
                "images": [
                    image_id,
                    "c4b16966ecd94ffa910eab4e630e24f259bf34a87e924cd4b1434f267b0e354e",
                ],
                "stream":
                "",
            },
        )
        mock.get(
            tests.BASE_URL + "/libpod/images"
            "/sha256%3A326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/json",
            json=FIRST_IMAGE,
        )
        mock.get(
            tests.BASE_URL + "/libpod/images"
            "/c4b16966ecd94ffa910eab4e630e24f259bf34a87e924cd4b1434f267b0e354e/json",
            json=SECOND_IMAGE,
        )

        images = self.client.images.pull("quay.io/fedora",
                                         "latest",
                                         all_tags=True)
        self.assertIsInstance(images, Iterable)
        self.assertIsInstance(images[0], Image)
        self.assertIsInstance(images[1], Image)

        self.assertEqual(images[0].id, image_id)
        self.assertEqual(
            images[1].id,
            "c4b16966ecd94ffa910eab4e630e24f259bf34a87e924cd4b1434f267b0e354e")
Ejemplo n.º 12
0
class TestClientImages(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.images
        self.assertIsInstance(manager, ImagesManager)

    @requests_mock.Mocker()
    def test_history(self, mock):
        mock.get(
            "http+unix://localhost:9999/v3.0.0/libpod/images"
            "/326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/history",
            json=[{
                "Id":
                "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab",
                "Comment": "",
                "Created": 1614208404,
                "CreatedBy": "2021-02-24T23:13:24+00:00",
                "Tags": ["latest"],
                "Size": 1024,
            }],
        )
        mock.get(
            "http+unix://localhost:9999/v3.0.0/libpod/images"
            "/326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/json",
            json=FIRST_IMAGE,
        )

        image = self.client.images.get(
            "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab")
        history = image.history()
        self.assertEqual(history[0]["Id"], image.id)

    @requests_mock.Mocker()
    def test_reload(self, mock):
        update = FIRST_IMAGE.copy()
        update["Containers"] = 0

        mock.get(
            "http+unix://localhost:9999/v3.0.0/libpod/images"
            "/326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/json",
            [
                {
                    "json": FIRST_IMAGE
                },
                {
                    "json": update
                },
            ],
        )

        image = self.client.images.get(
            "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab")
        self.assertEqual(image.attrs["Containers"], 2)

        image.reload()
        self.assertEqual(image.attrs["Containers"], 0)

    @requests_mock.Mocker()
    def test_save(self, mock):

        tarball = b'Yet another weird tarball...'
        body = io.BytesIO(tarball)

        mock.get(
            "http+unix://localhost:9999/v3.0.0/libpod/images"
            "/326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/json",
            json=FIRST_IMAGE,
        )
        mock.get(
            "http+unix://localhost:9999/v3.0.0/libpod/images/"
            "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/get",
            body=body,
        )

        image = self.client.images.get(
            "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab")

        with io.BytesIO() as fd:
            for chunk in image.save():
                fd.write(chunk)
            self.assertEqual(fd.getbuffer(), tarball)
Ejemplo n.º 13
0
class PodsManagerTestCase(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.pods
        self.assertIsInstance(manager, PodsManager)

    @requests_mock.Mocker()
    def test_create(self, mock):
        adapter = mock.post(
            tests.BASE_URL + "/libpod/pods/create",
            json={
                "Id":
                "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8"
            },
            status_code=201,
        )
        mock.get(
            tests.BASE_URL + "/libpod/pods"
            "/c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8/json",
            json=FIRST_POD,
        )

        actual = self.client.pods.create(name="database")
        self.assertIsInstance(actual, Pod)

        self.assertTrue(adapter.called_once)
        self.assertDictEqual(adapter.last_request.json(), {"name": "database"})

    @requests_mock.Mocker()
    def test_get(self, mock):
        mock.get(
            tests.BASE_URL + "/libpod/pods"
            "/c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8/json",
            json=FIRST_POD,
        )

        actual = self.client.pods.get(
            "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8")
        self.assertEqual(
            actual.id,
            "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8")

    @requests_mock.Mocker()
    def test_get404(self, mock):
        mock.get(
            tests.BASE_URL + "/libpod/pods"
            "/c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8/json",
            status_code=404,
            json={
                "cause":
                "no such pod",
                "message":
                "no pod with name or ID "
                "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8"
                " found: no such pod",
                "response":
                404,
            },
        )

        with self.assertRaises(NotFound):
            self.client.pods.get(
                "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8"
            )

    @requests_mock.Mocker()
    def test_list(self, mock):
        mock.get(tests.BASE_URL + "/libpod/pods/json",
                 json=[FIRST_POD, SECOND_POD])

        actual = self.client.pods.list()

        self.assertEqual(
            actual[0].id,
            "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8")
        self.assertEqual(
            actual[1].id,
            "c847d00ed0474835a2e246f00e90346fe98d388f98064f4494953c5fb921b8bc")

    @requests_mock.Mocker()
    def test_prune(self, mock):
        adapter = mock.post(
            tests.BASE_URL + "/libpod/pods/prune",
            json=[
                {
                    "Err":
                    None,
                    "Id":
                    "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8",
                },
                {
                    "Err":
                    None,
                    "Id":
                    "c847d00ed0474835a2e246f00e90346fe98d388f98064f4494953c5fb921b8bc",
                },
            ],
        )

        actual = self.client.pods.prune()
        self.assertTrue(adapter.called_once)
        self.assertListEqual(
            actual["PodsDeleted"],
            [
                "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8",
                "c847d00ed0474835a2e246f00e90346fe98d388f98064f4494953c5fb921b8bc",
            ],
        )
        self.assertEqual(actual["SpaceReclaimed"], 0)

    @requests_mock.Mocker()
    def test_stats(self, mock):
        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(
            tests.BASE_URL + "/libpod/pods/stats"
            "?namesOrIDs=c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8",
            json=body,
        )

        actual = self.client.pods.stats(
            name=
            "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8")
        self.assertDictEqual(actual, body)

    def test_stats_400(self):
        with self.assertRaises(ValueError):
            self.client.pods.stats(all=True, name="container")
Ejemplo n.º 14
0
class SystemTestCase(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_df(self, mock):
        body = {
            "Containers": [
                {"ContainerID": "f1fb3564c202"},
                {"ContainerID": "779afab684c7"},
            ],
            "Images": [
                {"ImageID": "118cc2c68ef5"},
                {"ImageID": "a6b4a8255f9e"},
            ],
            "Volumes": [
                {"VolumeName": "27df59163be8"},
                {"VolumeName": "77a83a10f86e"},
            ],
        }

        mock.get(
            tests.BASE_URL + "/libpod/system/df",
            json=body,
        )

        actual = self.client.df()
        self.assertDictEqual(actual, body)

    @requests_mock.Mocker()
    def test_info(self, mock):
        body = {
            "host": {
                "arch": "amd65",
                "os": "linux",
            }
        }
        mock.get(tests.BASE_URL + "/libpod/info", json=body)

        actual = self.client.info()
        self.assertDictEqual(actual, body)

    @requests_mock.Mocker()
    def test_ping(self, mock):
        mock.head(tests.BASE_URL + "/libpod/_ping")
        self.assertTrue(self.client.ping())

    @requests_mock.Mocker()
    def test_version(self, mock):
        body = {
            "APIVersion": "3.0.0",
            "MinAPIVersion": "3.0.0",
            "Arch": "amd64",
            "Os": "linux",
        }
        mock.get(tests.BASE_URL + "/libpod/version", json=body)
        self.assertDictEqual(self.client.version(), body)
Ejemplo n.º 15
0
class NetworkTestCase(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):
        expected = {"Id": "1cf06390-709d-4ffa-a054-c3083abe367c"}
        actual = Network(attrs=expected)
        self.assertEqual(actual.id, expected["Id"])

        actual = Network(attrs={"name": "database"})
        self.assertEqual(
            actual.id,
            "3549b0028b75d981cdda2e573e9cb49dedc200185876df299f912b79f69dabd8")

    def test_name(self):
        actual = Network(attrs={"Name": "database"})
        self.assertEqual(actual.name, "database")

        actual = Network({"name": "database"})
        self.assertEqual(actual.name, "database")

    @requests_mock.Mocker()
    def test_remove(self, mock):
        adapter = mock.delete(
            "http+unix://localhost:9999/v1.40/networks/podman",
            json={
                "Name": "podman",
                "Err": None
            },
        )
        mock.get("http+unix://localhost:9999/v1.40/networks/podman",
                 json=FIRST_NETWORK)

        net = self.client.networks.get("podman")

        net.remove(force=True)
        self.assertEqual(adapter.call_count, 1)

    @requests_mock.Mocker()
    def test_connect(self, mock):
        adapter = mock.post(
            "http+unix://localhost:9999/v1.40/networks/podman/connect", )
        mock.get("http+unix://localhost:9999/v1.40/networks/podman",
                 json=FIRST_NETWORK)

        net = self.client.networks.get("podman")
        net.connect(
            "podman_ctnr",
            aliases=["production"],
            ipv4_address="172.16.0.1",
        )

        self.assertEqual(adapter.call_count, 1)
        self.assertDictEqual(
            adapter.last_request.json(),
            {
                'Container': 'podman_ctnr',
                "EndpointConfig": {
                    'Aliases': ['production'],
                    'IPAMConfig': {
                        'IPv4Address': '172.16.0.1'
                    },
                    'IPAddress':
                    '172.16.0.1',
                    'NetworkID':
                    '2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9',
                },
            },
        )

    @requests_mock.Mocker()
    def test_disconnect(self, mock):
        adapter = mock.post(
            "http+unix://localhost:9999/v1.40/networks/podman/disconnect", )
        mock.get("http+unix://localhost:9999/v1.40/networks/podman",
                 json=FIRST_NETWORK)

        net = self.client.networks.get("podman")
        net.disconnect("podman_ctnr", force=True)

        self.assertEqual(adapter.call_count, 1)
        self.assertDictEqual(
            adapter.last_request.json(),
            {
                'Container': 'podman_ctnr',
                "Force": True,
            },
        )
Ejemplo n.º 16
0
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="http+unix://localhost:9999")

    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(
            "http+unix://localhost:9999/v3.0.0/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(
            "http+unix://localhost:9999/v3.0.0/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(
            "http+unix://localhost:9999/v3.0.0/libpod/containers/json",
            text="[]",
        )
        actual = self.client.containers.list()
        self.assertListEqual(actual, [])

    @requests_mock.Mocker()
    def test_list(self, mock):
        mock.get(
            "http+unix://localhost:9999/v3.0.0/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(
            "http+unix://localhost:9999/v3.0.0/libpod/containers/json"
            "?all=True"
            "&filters=%7B%22status%22%3A+%5B%22running%22%5D%2C+"
            "%22before%22%3A+%5B%226dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03%22%5D%2C+"
            "%22since%22%3A+%5B%2287e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd%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(
            "http+unix://localhost:9999/v3.0.0/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(
            "http+unix://localhost:9999/v3.0.0/libpod/containers/prune",
            json=[
                {
                    "id":
                    "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd",
                    "space": 1024,
                },
                {
                    "id":
                    "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03",
                    "space": 1024,
                },
            ],
        )
        actual = self.client.containers.prune()
        self.assertDictEqual(
            actual,
            {
                "ContainersDeleted": [
                    "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd",
                    "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03",
                ],
                "SpaceReclaimed":
                2048,
            },
        )
Ejemplo n.º 17
0
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"])
Ejemplo n.º 18
0
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")
Ejemplo n.º 19
0
class PodmanClientTestCase(unittest.TestCase):
    """Test the PodmanClient() object."""

    opener = mock.mock_open(read_data="""
[containers]
  log_size_max = -1
  pids_limit = 2048
  userns_size = 65536

[engine]
  num_locks = 2048
  active_service = "testing"
  stop_timeout = 10
  [engine.service_destinations]
    [engine.service_destinations.production]
      uri = "ssh://root@localhost:22/run/podman/podman.sock"
      identity = "/home/root/.ssh/id_rsa"
    [engine.service_destinations.testing]
      uri = "ssh://qe@localhost:2222/run/podman/podman.sock"
      identity = "/home/qe/.ssh/id_rsa"

[network]
""")

    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

    @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",
            }
        }
        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 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 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,
                                                           encoding="utf-8")

    def test_connect_404(self):
        with mock.patch.multiple(Path,
                                 open=self.mocked_open,
                                 exists=MagicMock(return_value=True)):
            with self.assertRaises(KeyError):
                _ = PodmanClient(connection="not defined")

    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,
                                                           encoding="utf-8")
Ejemplo n.º 20
0
class ImageTestCase(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_history(self, mock):
        adapter = mock.get(
            tests.LIBPOD_URL +
            "/images/326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/history",
            json=[{
                "Id":
                "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab",
                "Comment": "",
                "Created": 1614208404,
                "CreatedBy": "2021-02-24T23:13:24+00:00",
                "Tags": ["latest"],
                "Size": 1024,
            }],
        )
        image = Image(attrs=FIRST_IMAGE, client=self.client.api)

        history = image.history()
        self.assertEqual(history[0]["Id"], image.id)
        self.assertTrue(adapter.called_once)

    @requests_mock.Mocker()
    def test_reload(self, mock):
        update = FIRST_IMAGE.copy()
        update["Containers"] = 0

        adapter = mock.get(
            tests.LIBPOD_URL +
            "/images/326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/json",
            [
                {
                    "json": FIRST_IMAGE
                },
                {
                    "json": update
                },
            ],
        )

        image = self.client.images.get(
            "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab")
        self.assertEqual(image.attrs["Containers"], 2)

        image.reload()
        self.assertEqual(image.attrs["Containers"], 0)
        self.assertTrue(adapter.call_count, 2)

    @requests_mock.Mocker()
    def test_save(self, mock):
        tarball = b'Yet another weird tarball...'
        body = io.BytesIO(tarball)

        adapter = mock.get(
            tests.LIBPOD_URL +
            "/images/326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab/get",
            body=body,
        )
        image = Image(attrs=FIRST_IMAGE, client=self.client.api)

        with io.BytesIO() as fd:
            for chunk in image.save():
                fd.write(chunk)
            self.assertEqual(fd.getbuffer(), tarball)
        self.assertTrue(adapter.called_once)
Ejemplo n.º 21
0
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")
Ejemplo n.º 22
0
class PodTestCase(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):
        expected = {"Id": "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8"}
        actual = Pod(attrs=expected)
        self.assertEqual(actual.id, expected["Id"])

        expected = {"Name": "redis-ngnix"}
        actual = Pod(attrs=expected)
        self.assertEqual(actual.name, expected["Name"])

    @requests_mock.Mocker()
    def test_kill(self, mock):
        adapter = mock.post(
            tests.BASE_URL + "/libpod/pods"
            "/c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8/kill",
            json={
                "Errs": [],
                "Id": "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8",
            },
        )

        pod = Pod(attrs=FIRST_POD, client=self.client.api)
        pod.kill()
        self.assertTrue(adapter.called_once)

    @requests_mock.Mocker()
    def test_kill_404(self, mock):
        adapter = mock.post(
            tests.BASE_URL + "/libpod/pods"
            "/c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8/kill",
            status_code=404,
            json={
                "cause": "no such pod",
                "message": "no pod with name or ID xyz found: no such pod",
                "response": 404,
            },
        )

        pod = Pod(attrs=FIRST_POD, client=self.client.api)
        with self.assertRaises(NotFound):
            pod.kill()
        self.assertTrue(adapter.called_once)

    @requests_mock.Mocker()
    def test_pause(self, mock):
        adapter = mock.post(
            tests.BASE_URL + "/libpod/pods"
            "/c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8/pause",
            json={
                "Errs": [],
                "Id": "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8",
            },
        )

        pod = Pod(attrs=FIRST_POD, client=self.client.api)
        pod.pause()
        self.assertTrue(adapter.called_once)

    @requests_mock.Mocker()
    def test_pause_404(self, mock):
        adapter = mock.post(
            tests.BASE_URL + "/libpod/pods"
            "/c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8/pause",
            status_code=404,
            json={
                "cause": "no such pod",
                "message": "no pod with name or ID xyz found: no such pod",
                "response": 404,
            },
        )

        pod = Pod(attrs=FIRST_POD, client=self.client.api)
        with self.assertRaises(NotFound):
            pod.pause()
        self.assertTrue(adapter.called_once)

    @requests_mock.Mocker()
    def test_remove(self, mock):
        adapter = mock.delete(
            tests.BASE_URL + "/libpod/pods/"
            "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8?force=True",
            json={
                "Errs": [],
                "Id": "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8",
            },
        )
        pod_manager = PodsManager(client=self.client.api)
        pod = pod_manager.prepare_model(attrs=FIRST_POD)

        pod.remove(force=True)
        self.assertTrue(adapter.called_once)

    @requests_mock.Mocker()
    def test_restart(self, mock):
        adapter = mock.post(
            tests.BASE_URL + "/libpod/pods"
            "/c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8/restart",
            json={
                "Errs": [],
                "Id": "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8",
            },
        )

        pod = Pod(attrs=FIRST_POD, client=self.client.api)
        pod.restart()
        self.assertTrue(adapter.called_once)

    @requests_mock.Mocker()
    def test_start(self, mock):
        adapter = mock.post(
            tests.BASE_URL + "/libpod/pods"
            "/c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8/start",
            json={
                "Errs": [],
                "Id": "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8",
            },
        )

        pod = Pod(attrs=FIRST_POD, client=self.client.api)
        pod.start()
        self.assertTrue(adapter.called_once)

    @requests_mock.Mocker()
    def test_stop(self, mock):
        adapter = mock.post(
            tests.BASE_URL + "/libpod/pods"
            "/c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8/stop?t=70.0",
            json={
                "Errs": [],
                "Id": "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8",
            },
        )

        pod = Pod(attrs=FIRST_POD, client=self.client.api)
        pod.stop(timeout=70.0)
        self.assertTrue(adapter.called_once)

    @requests_mock.Mocker()
    def test_top(self, mock):
        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"],
        }
        adapter = mock.get(
            tests.BASE_URL + "/libpod/pods"
            "/c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8/top"
            "?ps_args=aux&stream=False",
            json=body,
        )

        pod = Pod(attrs=FIRST_POD, client=self.client.api)
        actual = pod.top(ps_args="aux")
        self.assertDictEqual(actual, body)
        self.assertTrue(adapter.called_once)

    @requests_mock.Mocker()
    def test_unpause(self, mock):
        adapter = mock.post(
            tests.BASE_URL + "/libpod/pods"
            "/c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8/unpause",
            json={
                "Errs": [],
                "Id": "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8",
            },
        )
        pod = Pod(attrs=FIRST_POD, client=self.client.api)
        pod.unpause()
        self.assertTrue(adapter.called_once)
Ejemplo n.º 23
0
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)
Ejemplo n.º 24
0
class TestBuildCase(unittest.TestCase):
    """Test ImagesManager build().

    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()

    @patch.object(api, "create_tar")
    @patch.object(api, "prepare_containerfile")
    def test_build(self, mock_prepare_containerfile, mock_create_tar):
        mock_prepare_containerfile.return_value = "Containerfile"
        mock_create_tar.return_value = b"This is a mocked tarball."

        stream = [
            {
                "stream": " ---\u003e a9eb17255234"
            },
            {
                "stream": "Step 1 : VOLUME /data"
            },
            {
                "stream": " ---\u003e Running in abdc1e6896c6"
            },
            {
                "stream": " ---\u003e 713bca62012e"
            },
            {
                "stream": "Removing intermediate container abdc1e6896c6"
            },
            {
                "stream": "Step 2 : CMD [\"/bin/sh\"]"
            },
            {
                "stream": " ---\u003e Running in dba30f2a1a7e"
            },
            {
                "stream": " ---\u003e 032b8b2855fc"
            },
            {
                "stream": "Removing intermediate container dba30f2a1a7e"
            },
            {
                "stream": "032b8b2855fc\n"
            },
        ]

        buffer = io.StringIO()
        for entry in stream:
            buffer.write(json.JSONEncoder().encode(entry))
            buffer.write("\n")

        with requests_mock.Mocker() as mock:
            mock.post(
                "http+unix://localhost:9999/v3.0.0/libpod/build"
                "?t=latest"
                "&buildargs=%7B%22BUILD_DATE%22%3A+%22January+1%2C+1970%22%7D"
                "&cpuperiod=10"
                "&extrahosts=%7B%22database%22%3A+%22127.0.0.1%22%7D"
                "&labels=%7B%22Unittest%22%3A+%22true%22%7D",
                text=buffer.getvalue(),
            )
            mock.get(
                "http+unix://localhost:9999/v3.0.0/libpod/images/032b8b2855fc/json",
                json={
                    "Id":
                    "032b8b2855fc",
                    "ParentId":
                    "",
                    "RepoTags":
                    ["fedora:latest", "fedora:33", "<none>:<none>"],
                    "RepoDigests": [
                        "fedora@sha256:9598a10fa72b402db876ccd4b3d240a4061c7d1e442745f1896ba37e1bf38664"
                    ],
                    "Created":
                    1614033320,
                    "Size":
                    23855104,
                    "VirtualSize":
                    23855104,
                    "SharedSize":
                    0,
                    "Labels": {},
                    "Containers":
                    2,
                },
            )

            image, logs = self.client.images.build(
                path="/tmp/context_dir",
                tag="latest",
                buildargs={
                    "BUILD_DATE": "January 1, 1970",
                },
                container_limits={
                    "cpuperiod": 10,
                },
                extra_hosts={"database": "127.0.0.1"},
                labels={"Unittest": "true"},
            )
            self.assertIsInstance(image, Image)
            self.assertEqual(image.id, "032b8b2855fc")
            self.assertIsInstance(logs, Iterable)

    @patch.object(api, "create_tar")
    @patch.object(api, "prepare_containerfile")
    def test_build_logged_error(self, mock_prepare_containerfile,
                                mock_create_tar):
        mock_prepare_containerfile.return_value = "Containerfile"
        mock_create_tar.return_value = b"This is a mocked tarball."

        stream = [
            {
                "error": "We do not need any stinking badges."
            },
        ]

        buffer = io.StringIO()
        for entry in stream:
            buffer.write(json.JSONEncoder().encode(entry))
            buffer.write("\n")

        with requests_mock.Mocker() as mock:
            mock.post(
                "http+unix://localhost:9999/v3.0.0/libpod/build",
                text=buffer.getvalue(),
            )

            with self.assertRaises(BuildError) as e:
                self.client.images.build(path="/tmp/context_dir")
            self.assertEqual(e.exception.msg,
                             "We do not need any stinking badges.")

    @requests_mock.Mocker()
    def test_build_no_context(self, mock):
        mock.post("http+unix://localhost:9999/v3.0.0/libpod/images/build")
        with self.assertRaises(TypeError):
            self.client.images.build()

    @requests_mock.Mocker()
    def test_build_encoding(self, mock):
        mock.post("http+unix://localhost:9999/v3.0.0/libpod/images/build")
        with self.assertRaises(DockerException):
            self.client.images.build(path="/root", gzip=True, encoding="utf-8")