mirror of https://github.com/containers/podman.git
Merge pull request #8308 from jwhonce/jira/run-976
Refactor to use DockerClient vs APIClient
This commit is contained in:
commit
0b1a60ec27
|
@ -17,9 +17,9 @@
|
||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
project = 'Podman'
|
project = "Podman"
|
||||||
copyright = '2019, team'
|
copyright = "2019, team"
|
||||||
author = 'team'
|
author = "team"
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
# -- General configuration ---------------------------------------------------
|
||||||
|
@ -28,33 +28,33 @@ author = 'team'
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
# ones.
|
# ones.
|
||||||
extensions = [
|
extensions = [
|
||||||
'recommonmark',
|
"recommonmark",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ['_templates']
|
templates_path = ["_templates"]
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
# List of patterns, relative to source directory, that match files and
|
||||||
# directories to ignore when looking for source files.
|
# directories to ignore when looking for source files.
|
||||||
# This pattern also affects html_static_path and html_extra_path.
|
# This pattern also affects html_static_path and html_extra_path.
|
||||||
exclude_patterns = []
|
exclude_patterns = []
|
||||||
|
|
||||||
master_doc = 'index'
|
master_doc = "index"
|
||||||
|
|
||||||
# -- Options for HTML output -------------------------------------------------
|
# -- Options for HTML output -------------------------------------------------
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
# a list of builtin themes.
|
# a list of builtin themes.
|
||||||
#
|
#
|
||||||
html_theme = 'alabaster'
|
html_theme = "alabaster"
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
html_static_path = ['_static']
|
html_static_path = ["_static"]
|
||||||
|
|
||||||
html_css_files = [
|
html_css_files = [
|
||||||
'custom.css',
|
"custom.css",
|
||||||
]
|
]
|
||||||
|
|
||||||
# -- Extension configuration -------------------------------------------------
|
# -- Extension configuration -------------------------------------------------
|
||||||
|
|
|
@ -28,17 +28,17 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// FYI scope and version are currently unused but are described by the API
|
// FYI scope and version are currently unused but are described by the API
|
||||||
// Leaving this for if/when we have to enable these
|
// Leaving this for if/when we have to enable these
|
||||||
//query := struct {
|
// query := struct {
|
||||||
// scope string
|
// scope string
|
||||||
// verbose bool
|
// verbose bool
|
||||||
//}{
|
// }{
|
||||||
// // override any golang type defaults
|
// // override any golang type defaults
|
||||||
//}
|
// }
|
||||||
//decoder := r.Context().Value("decoder").(*schema.Decoder)
|
// decoder := r.Context().Value("decoder").(*schema.Decoder)
|
||||||
//if err := decoder.Decode(&query, r.URL.Query()); err != nil {
|
// if err := decoder.Decode(&query, r.URL.Query()); err != nil {
|
||||||
// utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
|
// utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
|
||||||
// return
|
// return
|
||||||
//}
|
// }
|
||||||
config, err := runtime.GetConfig()
|
config, err := runtime.GetConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.InternalServerError(w, err)
|
utils.InternalServerError(w, err)
|
||||||
|
@ -119,7 +119,7 @@ func getNetworkResourceByName(name string, runtime *libpod.Runtime) (*types.Netw
|
||||||
}
|
}
|
||||||
report := types.NetworkResource{
|
report := types.NetworkResource{
|
||||||
Name: name,
|
Name: name,
|
||||||
ID: "",
|
ID: name,
|
||||||
Created: time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec)), // nolint: unconvert
|
Created: time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec)), // nolint: unconvert
|
||||||
Scope: "",
|
Scope: "",
|
||||||
Driver: network.DefaultNetworkDriver,
|
Driver: network.DefaultNetworkDriver,
|
||||||
|
@ -207,6 +207,7 @@ func ListNetworks(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
reports := make([]*types.NetworkResource, 0, len(netNames))
|
reports := make([]*types.NetworkResource, 0, len(netNames))
|
||||||
|
logrus.Errorf("netNames: %q", strings.Join(netNames, ", "))
|
||||||
for _, name := range netNames {
|
for _, name := range netNames {
|
||||||
report, err := getNetworkResourceByName(name, runtime)
|
report, err := getNetworkResourceByName(name, runtime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -276,21 +277,14 @@ func CreateNetwork(w http.ResponseWriter, r *http.Request) {
|
||||||
utils.InternalServerError(w, err)
|
utils.InternalServerError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
report := types.NetworkCreate{
|
|
||||||
CheckDuplicate: networkCreate.CheckDuplicate,
|
body := struct {
|
||||||
Driver: networkCreate.Driver,
|
Id string
|
||||||
Scope: networkCreate.Scope,
|
Warning []string
|
||||||
EnableIPv6: networkCreate.EnableIPv6,
|
}{
|
||||||
IPAM: networkCreate.IPAM,
|
Id: name,
|
||||||
Internal: networkCreate.Internal,
|
|
||||||
Attachable: networkCreate.Attachable,
|
|
||||||
Ingress: networkCreate.Ingress,
|
|
||||||
ConfigOnly: networkCreate.ConfigOnly,
|
|
||||||
ConfigFrom: networkCreate.ConfigFrom,
|
|
||||||
Options: networkCreate.Options,
|
|
||||||
Labels: networkCreate.Labels,
|
|
||||||
}
|
}
|
||||||
utils.WriteResponse(w, http.StatusOK, report)
|
utils.WriteResponse(w, http.StatusCreated, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
|
func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
|
@ -165,11 +165,34 @@ class TestApi(unittest.TestCase):
|
||||||
r = requests.get(_url(ctnr("/containers/{}/logs?stdout=true")))
|
r = requests.get(_url(ctnr("/containers/{}/logs?stdout=true")))
|
||||||
self.assertEqual(r.status_code, 200, r.text)
|
self.assertEqual(r.status_code, 200, r.text)
|
||||||
|
|
||||||
def test_post_create(self):
|
def test_post_create_compat(self):
|
||||||
self.skipTest("TODO: create request body")
|
"""Create network and container then connect to network"""
|
||||||
r = requests.post(_url("/containers/create?args=True"))
|
net = requests.post(
|
||||||
self.assertEqual(r.status_code, 200, r.text)
|
PODMAN_URL + "/v1.40/networks/create", json={"Name": "TestNetwork"}
|
||||||
json.loads(r.text)
|
)
|
||||||
|
self.assertEqual(net.status_code, 201, net.text)
|
||||||
|
|
||||||
|
create = requests.post(
|
||||||
|
PODMAN_URL + "/v1.40/containers/create?name=postCreate",
|
||||||
|
json={
|
||||||
|
"Cmd": ["date"],
|
||||||
|
"Image": "alpine:latest",
|
||||||
|
"NetworkDisabled": False,
|
||||||
|
"NetworkConfig": {
|
||||||
|
"EndpointConfig": {"TestNetwork": {"Aliases": ["test_post_create"]}}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assertEqual(create.status_code, 201, create.text)
|
||||||
|
payload = json.loads(create.text)
|
||||||
|
self.assertIsNotNone(payload["Id"])
|
||||||
|
|
||||||
|
connect = requests.post(
|
||||||
|
PODMAN_URL + "/v1.40/networks/TestNetwork/connect",
|
||||||
|
json={"Container": payload["Id"]},
|
||||||
|
)
|
||||||
|
self.assertEqual(connect.status_code, 200, create.text)
|
||||||
|
self.assertEqual(connect.text, "OK\n")
|
||||||
|
|
||||||
def test_commit(self):
|
def test_commit(self):
|
||||||
r = requests.post(_url(ctnr("/commit?container={}")))
|
r = requests.post(_url(ctnr("/commit?container={}")))
|
||||||
|
|
|
@ -6,6 +6,8 @@ import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
from docker import DockerClient
|
||||||
|
|
||||||
from test.python.docker import constant
|
from test.python.docker import constant
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,16 +143,15 @@ class Podman(object):
|
||||||
def tear_down(self):
|
def tear_down(self):
|
||||||
shutil.rmtree(self.anchor_directory, ignore_errors=True)
|
shutil.rmtree(self.anchor_directory, ignore_errors=True)
|
||||||
|
|
||||||
def restore_image_from_cache(self, client):
|
def restore_image_from_cache(self, client: DockerClient):
|
||||||
img = os.path.join(self.image_cache, constant.ALPINE_TARBALL)
|
path = os.path.join(self.image_cache, constant.ALPINE_TARBALL)
|
||||||
if not os.path.exists(img):
|
if not os.path.exists(path):
|
||||||
client.pull(constant.ALPINE)
|
img = client.images.pull(constant.ALPINE)
|
||||||
image = client.get_image(constant.ALPINE)
|
with open(path, mode="wb") as tarball:
|
||||||
with open(img, mode="wb") as tarball:
|
for frame in img.save(named=True):
|
||||||
for frame in image:
|
|
||||||
tarball.write(frame)
|
tarball.write(frame)
|
||||||
else:
|
else:
|
||||||
self.run("load", "-i", img, check=True)
|
self.run("load", "-i", path, check=True)
|
||||||
|
|
||||||
def flush_image_cache(self):
|
def flush_image_cache(self):
|
||||||
for f in pathlib.Path(self.image_cache).glob("*.tar"):
|
for f in pathlib.Path(self.image_cache).glob("*.tar"):
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
from docker import APIClient
|
from docker import DockerClient
|
||||||
|
|
||||||
from test.python.docker import constant
|
from test.python.docker import constant
|
||||||
|
|
||||||
|
|
||||||
def run_top_container(client: APIClient):
|
def run_top_container(client: DockerClient):
|
||||||
c = client.create_container(
|
c = client.containers.create(
|
||||||
constant.ALPINE, command="top", detach=True, tty=True, name="top"
|
constant.ALPINE, command="top", detach=True, tty=True, name="top"
|
||||||
)
|
)
|
||||||
client.start(c.get("Id"))
|
c.start()
|
||||||
return c.get("Id")
|
return c.id
|
||||||
|
|
||||||
|
|
||||||
def remove_all_containers(client: APIClient):
|
def remove_all_containers(client: DockerClient):
|
||||||
for ctnr in client.containers(quiet=True):
|
for ctnr in client.containers.list(all=True):
|
||||||
client.remove_container(ctnr, force=True)
|
ctnr.remove(force=True)
|
||||||
|
|
||||||
|
|
||||||
def remove_all_images(client: APIClient):
|
def remove_all_images(client: DockerClient):
|
||||||
for image in client.images(quiet=True):
|
for img in client.images.list():
|
||||||
client.remove_image(image, force=True)
|
# FIXME should DELETE /images accept the sha256: prefix?
|
||||||
|
id_ = img.id.removeprefix("sha256:")
|
||||||
|
client.images.remove(id_, force=True)
|
||||||
|
|
|
@ -3,7 +3,7 @@ import sys
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from docker import APIClient, errors
|
from docker import DockerClient, errors
|
||||||
|
|
||||||
from test.python.docker import Podman, common, constant
|
from test.python.docker import Podman, common, constant
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ class TestContainers(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.client = APIClient(base_url="tcp://127.0.0.1:8080", timeout=15)
|
self.client = DockerClient(base_url="tcp://127.0.0.1:8080", timeout=15)
|
||||||
TestContainers.podman.restore_image_from_cache(self.client)
|
TestContainers.podman.restore_image_from_cache(self.client)
|
||||||
TestContainers.topContainerId = common.run_top_container(self.client)
|
TestContainers.topContainerId = common.run_top_container(self.client)
|
||||||
self.assertIsNotNone(TestContainers.topContainerId)
|
self.assertIsNotNone(TestContainers.topContainerId)
|
||||||
|
@ -52,146 +52,115 @@ class TestContainers(unittest.TestCase):
|
||||||
TestContainers.podman.tear_down()
|
TestContainers.podman.tear_down()
|
||||||
return super().tearDownClass()
|
return super().tearDownClass()
|
||||||
|
|
||||||
def test_inspect_container(self):
|
|
||||||
# Inspect bogus container
|
|
||||||
with self.assertRaises(errors.NotFound) as error:
|
|
||||||
self.client.inspect_container("dummy")
|
|
||||||
self.assertEqual(error.exception.response.status_code, 404)
|
|
||||||
|
|
||||||
# Inspect valid container by Id
|
|
||||||
container = self.client.inspect_container(TestContainers.topContainerId)
|
|
||||||
self.assertIn("top", container["Name"])
|
|
||||||
|
|
||||||
# Inspect valid container by name
|
|
||||||
container = self.client.inspect_container("top")
|
|
||||||
self.assertIn(TestContainers.topContainerId, container["Id"])
|
|
||||||
|
|
||||||
def test_create_container(self):
|
def test_create_container(self):
|
||||||
# Run a container with detach mode
|
# Run a container with detach mode
|
||||||
container = self.client.create_container(image="alpine", detach=True)
|
self.client.containers.create(image="alpine", detach=True)
|
||||||
self.assertEqual(len(container), 2)
|
self.assertEqual(len(self.client.containers.list(all=True)), 2)
|
||||||
|
|
||||||
|
def test_create_network(self):
|
||||||
|
net = self.client.networks.create("testNetwork", driver="bridge")
|
||||||
|
ctnr = self.client.containers.create(image="alpine", detach=True)
|
||||||
|
net.connect(ctnr)
|
||||||
|
|
||||||
|
nets = self.client.networks.list(greedy=True)
|
||||||
|
self.assertGreaterEqual(len(nets), 1)
|
||||||
|
|
||||||
|
# TODO fix endpoint to include containers
|
||||||
|
# for n in nets:
|
||||||
|
# if n.id == "testNetwork":
|
||||||
|
# self.assertEqual(ctnr.id, n.containers)
|
||||||
|
# self.assertTrue(False, "testNetwork not found")
|
||||||
|
|
||||||
def test_start_container(self):
|
def test_start_container(self):
|
||||||
# Start bogus container
|
|
||||||
with self.assertRaises(errors.NotFound) as error:
|
|
||||||
self.client.start("dummy")
|
|
||||||
self.assertEqual(error.exception.response.status_code, 404)
|
|
||||||
|
|
||||||
# Podman docs says it should give a 304 but returns with no response
|
# Podman docs says it should give a 304 but returns with no response
|
||||||
# # Start a already started container should return 304
|
# # Start a already started container should return 304
|
||||||
# response = self.client.start(container=TestContainers.topContainerId)
|
# response = self.client.api.start(container=TestContainers.topContainerId)
|
||||||
# self.assertEqual(error.exception.response.status_code, 304)
|
# self.assertEqual(error.exception.response.status_code, 304)
|
||||||
|
|
||||||
# Create a new container and validate the count
|
# Create a new container and validate the count
|
||||||
self.client.create_container(image=constant.ALPINE, name="container2")
|
self.client.containers.create(image=constant.ALPINE, name="container2")
|
||||||
containers = self.client.containers(quiet=True, all=True)
|
containers = self.client.containers.list(all=True)
|
||||||
self.assertEqual(len(containers), 2)
|
self.assertEqual(len(containers), 2)
|
||||||
|
|
||||||
def test_stop_container(self):
|
def test_stop_container(self):
|
||||||
# Stop bogus container
|
top = self.client.containers.get("top")
|
||||||
with self.assertRaises(errors.NotFound) as error:
|
self.assertEqual(top.status, "running")
|
||||||
self.client.stop("dummy")
|
|
||||||
self.assertEqual(error.exception.response.status_code, 404)
|
|
||||||
|
|
||||||
# Validate the container state
|
|
||||||
container = self.client.inspect_container("top")
|
|
||||||
self.assertEqual(container["State"]["Status"], "running")
|
|
||||||
|
|
||||||
# Stop a running container and validate the state
|
# Stop a running container and validate the state
|
||||||
self.client.stop(TestContainers.topContainerId)
|
top.stop()
|
||||||
container = self.client.inspect_container("top")
|
top.reload()
|
||||||
self.assertIn(
|
self.assertIn(top.status, ("stopped", "exited"))
|
||||||
container["State"]["Status"],
|
|
||||||
"stopped exited",
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_restart_container(self):
|
def test_restart_container(self):
|
||||||
# Restart bogus container
|
|
||||||
with self.assertRaises(errors.NotFound) as error:
|
|
||||||
self.client.restart("dummy")
|
|
||||||
self.assertEqual(error.exception.response.status_code, 404)
|
|
||||||
|
|
||||||
# Validate the container state
|
# Validate the container state
|
||||||
self.client.stop(TestContainers.topContainerId)
|
top = self.client.containers.get(TestContainers.topContainerId)
|
||||||
container = self.client.inspect_container("top")
|
top.stop()
|
||||||
self.assertEqual(container["State"]["Status"], "stopped")
|
top.reload()
|
||||||
|
self.assertIn(top.status, ("stopped", "exited"))
|
||||||
|
|
||||||
# restart a running container and validate the state
|
# restart a running container and validate the state
|
||||||
self.client.restart(TestContainers.topContainerId)
|
top.restart()
|
||||||
container = self.client.inspect_container("top")
|
top.reload()
|
||||||
self.assertEqual(container["State"]["Status"], "running")
|
self.assertEqual(top.status, "running")
|
||||||
|
|
||||||
def test_remove_container(self):
|
def test_remove_container(self):
|
||||||
# Remove bogus container
|
|
||||||
with self.assertRaises(errors.NotFound) as error:
|
|
||||||
self.client.remove_container("dummy")
|
|
||||||
self.assertEqual(error.exception.response.status_code, 404)
|
|
||||||
|
|
||||||
# Remove container by ID with force
|
# Remove container by ID with force
|
||||||
self.client.remove_container(TestContainers.topContainerId, force=True)
|
top = self.client.containers.get(TestContainers.topContainerId)
|
||||||
containers = self.client.containers()
|
top.remove(force=True)
|
||||||
self.assertEqual(len(containers), 0)
|
self.assertEqual(len(self.client.containers.list()), 0)
|
||||||
|
|
||||||
def test_remove_container_without_force(self):
|
def test_remove_container_without_force(self):
|
||||||
# Validate current container count
|
# Validate current container count
|
||||||
containers = self.client.containers()
|
self.assertTrue(len(self.client.containers.list()), 1)
|
||||||
self.assertTrue(len(containers), 1)
|
|
||||||
|
|
||||||
# Remove running container should throw error
|
# Remove running container should throw error
|
||||||
|
top = self.client.containers.get(TestContainers.topContainerId)
|
||||||
with self.assertRaises(errors.APIError) as error:
|
with self.assertRaises(errors.APIError) as error:
|
||||||
self.client.remove_container(TestContainers.topContainerId)
|
top.remove()
|
||||||
self.assertEqual(error.exception.response.status_code, 500)
|
self.assertEqual(error.exception.response.status_code, 500)
|
||||||
|
|
||||||
# Remove container by ID with force
|
# Remove container by ID without force
|
||||||
self.client.stop(TestContainers.topContainerId)
|
top.stop()
|
||||||
self.client.remove_container(TestContainers.topContainerId)
|
top.remove()
|
||||||
containers = self.client.containers()
|
self.assertEqual(len(self.client.containers.list()), 0)
|
||||||
self.assertEqual(len(containers), 0)
|
|
||||||
|
|
||||||
def test_pause_container(self):
|
def test_pause_container(self):
|
||||||
# Pause bogus container
|
|
||||||
with self.assertRaises(errors.NotFound) as error:
|
|
||||||
self.client.pause("dummy")
|
|
||||||
self.assertEqual(error.exception.response.status_code, 404)
|
|
||||||
|
|
||||||
# Validate the container state
|
# Validate the container state
|
||||||
container = self.client.inspect_container("top")
|
top = self.client.containers.get(TestContainers.topContainerId)
|
||||||
self.assertEqual(container["State"]["Status"], "running")
|
self.assertEqual(top.status, "running")
|
||||||
|
|
||||||
# Pause a running container and validate the state
|
# Pause a running container and validate the state
|
||||||
self.client.pause(container["Id"])
|
top.pause()
|
||||||
container = self.client.inspect_container("top")
|
top.reload()
|
||||||
self.assertEqual(container["State"]["Status"], "paused")
|
self.assertEqual(top.status, "paused")
|
||||||
|
|
||||||
def test_pause_stopped_container(self):
|
def test_pause_stopped_container(self):
|
||||||
# Stop the container
|
# Stop the container
|
||||||
self.client.stop(TestContainers.topContainerId)
|
top = self.client.containers.get(TestContainers.topContainerId)
|
||||||
|
top.stop()
|
||||||
|
|
||||||
# Pause exited container should trow error
|
# Pause exited container should trow error
|
||||||
with self.assertRaises(errors.APIError) as error:
|
with self.assertRaises(errors.APIError) as error:
|
||||||
self.client.pause(TestContainers.topContainerId)
|
top.pause()
|
||||||
self.assertEqual(error.exception.response.status_code, 500)
|
self.assertEqual(error.exception.response.status_code, 500)
|
||||||
|
|
||||||
def test_unpause_container(self):
|
def test_unpause_container(self):
|
||||||
# Unpause bogus container
|
top = self.client.containers.get(TestContainers.topContainerId)
|
||||||
with self.assertRaises(errors.NotFound) as error:
|
|
||||||
self.client.unpause("dummy")
|
|
||||||
self.assertEqual(error.exception.response.status_code, 404)
|
|
||||||
|
|
||||||
# Validate the container state
|
# Validate the container state
|
||||||
self.client.pause(TestContainers.topContainerId)
|
top.pause()
|
||||||
container = self.client.inspect_container("top")
|
top.reload()
|
||||||
self.assertEqual(container["State"]["Status"], "paused")
|
self.assertEqual(top.status, "paused")
|
||||||
|
|
||||||
# Pause a running container and validate the state
|
# Pause a running container and validate the state
|
||||||
self.client.unpause(TestContainers.topContainerId)
|
top.unpause()
|
||||||
container = self.client.inspect_container("top")
|
top.reload()
|
||||||
self.assertEqual(container["State"]["Status"], "running")
|
self.assertEqual(top.status, "running")
|
||||||
|
|
||||||
def test_list_container(self):
|
def test_list_container(self):
|
||||||
# Add container and validate the count
|
# Add container and validate the count
|
||||||
self.client.create_container(image="alpine", detach=True)
|
self.client.containers.create(image="alpine", detach=True)
|
||||||
containers = self.client.containers(all=True)
|
containers = self.client.containers.list(all=True)
|
||||||
self.assertEqual(len(containers), 2)
|
self.assertEqual(len(containers), 2)
|
||||||
|
|
||||||
def test_filters(self):
|
def test_filters(self):
|
||||||
|
@ -199,16 +168,18 @@ class TestContainers(unittest.TestCase):
|
||||||
|
|
||||||
# List container with filter by id
|
# List container with filter by id
|
||||||
filters = {"id": TestContainers.topContainerId}
|
filters = {"id": TestContainers.topContainerId}
|
||||||
ctnrs = self.client.containers(all=True, filters=filters)
|
ctnrs = self.client.containers.list(all=True, filters=filters)
|
||||||
self.assertEqual(len(ctnrs), 1)
|
self.assertEqual(len(ctnrs), 1)
|
||||||
|
|
||||||
# List container with filter by name
|
# List container with filter by name
|
||||||
filters = {"name": "top"}
|
filters = {"name": "top"}
|
||||||
ctnrs = self.client.containers(all=True, filters=filters)
|
ctnrs = self.client.containers.list(all=True, filters=filters)
|
||||||
self.assertEqual(len(ctnrs), 1)
|
self.assertEqual(len(ctnrs), 1)
|
||||||
|
|
||||||
def test_rename_container(self):
|
def test_rename_container(self):
|
||||||
|
top = self.client.containers.get(TestContainers.topContainerId)
|
||||||
|
|
||||||
# rename bogus container
|
# rename bogus container
|
||||||
with self.assertRaises(errors.APIError) as error:
|
with self.assertRaises(errors.APIError) as error:
|
||||||
self.client.rename(container="dummy", name="newname")
|
top.rename(name="newname")
|
||||||
self.assertEqual(error.exception.response.status_code, 404)
|
self.assertEqual(error.exception.response.status_code, 404)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import sys
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from docker import APIClient, errors
|
from docker import DockerClient, errors
|
||||||
|
|
||||||
from test.python.docker import Podman, common, constant
|
from test.python.docker import Podman, common, constant
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class TestImages(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.client = APIClient(base_url="tcp://127.0.0.1:8080", timeout=15)
|
self.client = DockerClient(base_url="tcp://127.0.0.1:8080", timeout=15)
|
||||||
|
|
||||||
TestImages.podman.restore_image_from_cache(self.client)
|
TestImages.podman.restore_image_from_cache(self.client)
|
||||||
|
|
||||||
|
@ -51,83 +51,57 @@ class TestImages(unittest.TestCase):
|
||||||
TestImages.podman.tear_down()
|
TestImages.podman.tear_down()
|
||||||
return super().tearDownClass()
|
return super().tearDownClass()
|
||||||
|
|
||||||
def test_inspect_image(self):
|
|
||||||
"""Inspect Image"""
|
|
||||||
# Check for error with wrong image name
|
|
||||||
with self.assertRaises(errors.NotFound):
|
|
||||||
self.client.inspect_image("dummy")
|
|
||||||
alpine_image = self.client.inspect_image(constant.ALPINE)
|
|
||||||
self.assertIn(constant.ALPINE, alpine_image["RepoTags"])
|
|
||||||
|
|
||||||
def test_tag_invalid_image(self):
|
|
||||||
"""Tag Image
|
|
||||||
|
|
||||||
Validates if invalid image name is given a bad response is encountered
|
|
||||||
"""
|
|
||||||
with self.assertRaises(errors.NotFound):
|
|
||||||
self.client.tag("dummy", "demo")
|
|
||||||
|
|
||||||
def test_tag_valid_image(self):
|
def test_tag_valid_image(self):
|
||||||
"""Validates if the image is tagged successfully"""
|
"""Validates if the image is tagged successfully"""
|
||||||
self.client.tag(constant.ALPINE, "demo", constant.ALPINE_SHORTNAME)
|
alpine = self.client.images.get(constant.ALPINE)
|
||||||
alpine_image = self.client.inspect_image(constant.ALPINE)
|
self.assertTrue(alpine.tag("demo", constant.ALPINE_SHORTNAME))
|
||||||
for x in alpine_image["RepoTags"]:
|
|
||||||
self.assertIn("alpine", x)
|
alpine = self.client.images.get(constant.ALPINE)
|
||||||
|
for t in alpine.tags:
|
||||||
|
self.assertIn("alpine", t)
|
||||||
|
|
||||||
# @unittest.skip("doesn't work now")
|
# @unittest.skip("doesn't work now")
|
||||||
def test_retag_valid_image(self):
|
def test_retag_valid_image(self):
|
||||||
"""Validates if name updates when the image is retagged"""
|
"""Validates if name updates when the image is retagged"""
|
||||||
self.client.tag(constant.ALPINE_SHORTNAME, "demo", "rename")
|
alpine = self.client.images.get(constant.ALPINE)
|
||||||
alpine_image = self.client.inspect_image(constant.ALPINE)
|
self.assertTrue(alpine.tag("demo", "rename"))
|
||||||
self.assertNotIn("demo:test", alpine_image["RepoTags"])
|
|
||||||
|
alpine = self.client.images.get(constant.ALPINE)
|
||||||
|
self.assertNotIn("demo:test", alpine.tags)
|
||||||
|
|
||||||
def test_list_images(self):
|
def test_list_images(self):
|
||||||
"""List images"""
|
"""List images"""
|
||||||
all_images = self.client.images()
|
self.assertEqual(len(self.client.images.list()), 1)
|
||||||
self.assertEqual(len(all_images), 1)
|
|
||||||
# Add more images
|
# Add more images
|
||||||
self.client.pull(constant.BB)
|
self.client.images.pull(constant.BB)
|
||||||
all_images = self.client.images()
|
self.assertEqual(len(self.client.images.list()), 2)
|
||||||
self.assertEqual(len(all_images), 2)
|
|
||||||
|
|
||||||
# List images with filter
|
# List images with filter
|
||||||
filters = {"reference": "alpine"}
|
self.assertEqual(
|
||||||
all_images = self.client.images(filters=filters)
|
len(self.client.images.list(filters={"reference": "alpine"})), 1
|
||||||
self.assertEqual(len(all_images), 1)
|
)
|
||||||
|
|
||||||
def test_search_image(self):
|
def test_search_image(self):
|
||||||
"""Search for image"""
|
"""Search for image"""
|
||||||
response = self.client.search("libpod/alpine")
|
for r in self.client.images.search("libpod/alpine"):
|
||||||
for i in response:
|
self.assertIn("quay.io/libpod/alpine", r["Name"])
|
||||||
self.assertIn("quay.io/libpod/alpine", i["Name"])
|
|
||||||
|
|
||||||
def test_remove_image(self):
|
def test_remove_image(self):
|
||||||
"""Remove image"""
|
"""Remove image"""
|
||||||
# Check for error with wrong image name
|
# Check for error with wrong image name
|
||||||
with self.assertRaises(errors.NotFound):
|
with self.assertRaises(errors.NotFound):
|
||||||
self.client.remove_image("dummy")
|
self.client.images.remove("dummy")
|
||||||
all_images = self.client.images()
|
self.assertEqual(len(self.client.images.list()), 1)
|
||||||
self.assertEqual(len(all_images), 1)
|
|
||||||
|
|
||||||
alpine_image = self.client.inspect_image(constant.ALPINE)
|
self.client.images.remove(constant.ALPINE)
|
||||||
self.client.remove_image(alpine_image["Id"])
|
self.assertEqual(len(self.client.images.list()), 0)
|
||||||
all_images = self.client.images()
|
|
||||||
self.assertEqual(len(all_images), 0)
|
|
||||||
|
|
||||||
def test_image_history(self):
|
def test_image_history(self):
|
||||||
"""Image history"""
|
"""Image history"""
|
||||||
# Check for error with wrong image name
|
img = self.client.images.get(constant.ALPINE)
|
||||||
with self.assertRaises(errors.NotFound):
|
history = img.history()
|
||||||
self.client.history("dummy")
|
image_id = img.id[7:] if img.id.startswith("sha256:") else img.id
|
||||||
|
|
||||||
# NOTE: history() has incorrect return type hint
|
|
||||||
history = self.client.history(constant.ALPINE)
|
|
||||||
alpine_image = self.client.inspect_image(constant.ALPINE)
|
|
||||||
image_id = (
|
|
||||||
alpine_image["Id"][7:]
|
|
||||||
if alpine_image["Id"].startswith("sha256:")
|
|
||||||
else alpine_image["Id"]
|
|
||||||
)
|
|
||||||
|
|
||||||
found = False
|
found = False
|
||||||
for change in history:
|
for change in history:
|
||||||
|
@ -137,31 +111,34 @@ class TestImages(unittest.TestCase):
|
||||||
def test_get_image_exists_not(self):
|
def test_get_image_exists_not(self):
|
||||||
"""Negative test for get image"""
|
"""Negative test for get image"""
|
||||||
with self.assertRaises(errors.NotFound):
|
with self.assertRaises(errors.NotFound):
|
||||||
response = self.client.get_image("image_does_not_exists")
|
response = self.client.images.get("image_does_not_exists")
|
||||||
collections.deque(response)
|
collections.deque(response)
|
||||||
|
|
||||||
def test_export_image(self):
|
def test_save_image(self):
|
||||||
"""Export Image"""
|
"""Export Image"""
|
||||||
self.client.pull(constant.BB)
|
image = self.client.images.pull(constant.BB)
|
||||||
image = self.client.get_image(constant.BB)
|
|
||||||
|
|
||||||
file = os.path.join(TestImages.podman.image_cache, "busybox.tar")
|
file = os.path.join(TestImages.podman.image_cache, "busybox.tar")
|
||||||
with open(file, mode="wb") as tarball:
|
with open(file, mode="wb") as tarball:
|
||||||
for frame in image:
|
for frame in image.save(named=True):
|
||||||
tarball.write(frame)
|
tarball.write(frame)
|
||||||
sz = os.path.getsize(file)
|
sz = os.path.getsize(file)
|
||||||
self.assertGreater(sz, 0)
|
self.assertGreater(sz, 0)
|
||||||
|
|
||||||
def test_import_image(self):
|
def test_load_image(self):
|
||||||
"""Import|Load Image"""
|
"""Import|Load Image"""
|
||||||
all_images = self.client.images()
|
self.assertEqual(len(self.client.images.list()), 1)
|
||||||
self.assertEqual(len(all_images), 1)
|
|
||||||
|
|
||||||
file = os.path.join(TestImages.podman.image_cache, constant.ALPINE_TARBALL)
|
image = self.client.images.pull(constant.BB)
|
||||||
self.client.import_image_from_file(filename=file)
|
file = os.path.join(TestImages.podman.image_cache, "busybox.tar")
|
||||||
|
with open(file, mode="wb") as tarball:
|
||||||
|
for frame in image.save():
|
||||||
|
tarball.write(frame)
|
||||||
|
|
||||||
all_images = self.client.images()
|
with open(file, mode="rb") as saved:
|
||||||
self.assertEqual(len(all_images), 2)
|
_ = self.client.images.load(saved)
|
||||||
|
|
||||||
|
self.assertEqual(len(self.client.images.list()), 2)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -3,7 +3,7 @@ import sys
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from docker import APIClient
|
from docker import DockerClient
|
||||||
|
|
||||||
from test.python.docker import Podman, common, constant
|
from test.python.docker import Podman, common, constant
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ class TestSystem(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.client = APIClient(base_url="tcp://127.0.0.1:8080", timeout=15)
|
self.client = DockerClient(base_url="tcp://127.0.0.1:8080", timeout=15)
|
||||||
|
|
||||||
TestSystem.podman.restore_image_from_cache(self.client)
|
TestSystem.podman.restore_image_from_cache(self.client)
|
||||||
TestSystem.topContainerId = common.run_top_container(self.client)
|
TestSystem.topContainerId = common.run_top_container(self.client)
|
||||||
|
@ -58,9 +58,10 @@ class TestSystem(unittest.TestCase):
|
||||||
def test_info_container_details(self):
|
def test_info_container_details(self):
|
||||||
info = self.client.info()
|
info = self.client.info()
|
||||||
self.assertEqual(info["Containers"], 1)
|
self.assertEqual(info["Containers"], 1)
|
||||||
self.client.create_container(image=constant.ALPINE)
|
self.client.containers.create(image=constant.ALPINE)
|
||||||
info = self.client.info()
|
info = self.client.info()
|
||||||
self.assertEqual(info["Containers"], 2)
|
self.assertEqual(info["Containers"], 2)
|
||||||
|
|
||||||
def test_version(self):
|
def test_version(self):
|
||||||
self.assertIsNotNone(self.client.version())
|
version = self.client.version()
|
||||||
|
self.assertIsNotNone(version["Platform"]["Name"])
|
||||||
|
|
Loading…
Reference in New Issue