diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/apiv2/10-images.at | 29 | ||||
-rw-r--r-- | test/apiv2/40-pods.at | 4 | ||||
-rw-r--r-- | test/apiv2/rest_api/__init__.py | 0 | ||||
-rw-r--r-- | test/apiv2/rest_api/test_rest_v1_0_0.py | 219 | ||||
-rwxr-xr-x | test/apiv2/test-apiv2 | 19 | ||||
-rw-r--r-- | test/e2e/attach_test.go | 1 | ||||
-rw-r--r-- | test/e2e/common_test.go | 8 | ||||
-rw-r--r-- | test/e2e/events_test.go | 49 | ||||
-rw-r--r-- | test/e2e/ps_test.go | 25 | ||||
-rw-r--r-- | test/system/010-images.bats | 2 | ||||
-rw-r--r-- | test/system/200-pod.bats | 12 |
11 files changed, 331 insertions, 37 deletions
diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at index 1c8da0c2f..1c7ba8948 100644 --- a/test/apiv2/10-images.at +++ b/test/apiv2/10-images.at @@ -7,15 +7,15 @@ podman pull -q $IMAGE t GET libpod/images/json 200 \ - .[0].ID~[0-9a-f]\\{64\\} -iid=$(jq -r '.[0].ID' <<<"$output") + .[0].Id~[0-9a-f]\\{64\\} +iid=$(jq -r '.[0].Id' <<<"$output") t GET libpod/images/$iid/exists 204 t GET libpod/images/$PODMAN_TEST_IMAGE_NAME/exists 204 # FIXME: compare to actual podman info t GET libpod/images/json 200 \ - .[0].ID=${iid} + .[0].Id=${iid} t GET libpod/images/$iid/json 200 \ .Id=$iid \ @@ -33,4 +33,27 @@ t GET images/$iid/json 200 \ #t POST images/create fromImage=alpine 201 foo +# Display the image history +t GET libpod/images/nonesuch/history 404 + +for i in $iid ${iid:0:12} $PODMAN_TEST_IMAGE_NAME; do + t GET libpod/images/$i/history 200 \ + .[0].Id=$iid \ + .[0].Created~[0-9]\\{10\\} \ + .[0].Tags=null \ + .[0].Size=0 \ + .[0].Comment= +done + +# Export an image on the local +t GET libpod/images/nonesuch/get 404 +t GET libpod/images/$iid/get?format=foo 500 +t GET libpod/images/$PODMAN_TEST_IMAGE_NAME/get?compress=bar 400 + +for i in $iid ${iid:0:12} $PODMAN_TEST_IMAGE_NAME; do + t GET "libpod/images/$i/get" 200 '[POSIX tar archive]' + t GET "libpod/images/$i/get?compress=true" 200 '[POSIX tar archive]' + t GET "libpod/images/$i/get?compress=false" 200 '[POSIX tar archive]' +done + # vim: filetype=sh diff --git a/test/apiv2/40-pods.at b/test/apiv2/40-pods.at index 26877a102..2dea1918a 100644 --- a/test/apiv2/40-pods.at +++ b/test/apiv2/40-pods.at @@ -5,8 +5,8 @@ t GET "libpod/pods/json (clean slate at start)" 200 null -t POST libpod/pods/create name=foo 201 .id~[0-9a-f]\\{64\\} -pod_id=$(jq -r .id <<<"$output") +t POST libpod/pods/create name=foo 201 .Id~[0-9a-f]\\{64\\} +pod_id=$(jq -r .Id <<<"$output") t GET libpod/pods/foo/exists 204 t GET libpod/pods/$pod_id/exists 204 t GET libpod/pods/notfoo/exists 404 diff --git a/test/apiv2/rest_api/__init__.py b/test/apiv2/rest_api/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/test/apiv2/rest_api/__init__.py diff --git a/test/apiv2/rest_api/test_rest_v1_0_0.py b/test/apiv2/rest_api/test_rest_v1_0_0.py new file mode 100644 index 000000000..7c53623cb --- /dev/null +++ b/test/apiv2/rest_api/test_rest_v1_0_0.py @@ -0,0 +1,219 @@ +import json +import os +import shlex +import signal +import string +import subprocess +import sys +import time +import unittest +from collections.abc import Iterable +from multiprocessing import Process + +import requests +from dateutil.parser import parse + + +def _url(path): + return "http://localhost:8080/v1.0.0/libpod" + path + + +def podman(): + binary = os.getenv("PODMAN_BINARY") + if binary is None: + binary = "bin/podman" + return binary + + +def ctnr(path): + r = requests.get(_url("/containers/json?all=true")) + try: + ctnrs = json.loads(r.text) + except Exception as e: + sys.stderr.write("Bad container response: {}/{}".format(r.text, e)) + raise e + return path.format(ctnrs[0]["Id"]) + + +class TestApi(unittest.TestCase): + podman = None + + def setUp(self): + super().setUp() + if TestApi.podman.poll() is not None: + sys.stderr.write("podman service returned {}", + TestApi.podman.returncode) + sys.exit(2) + requests.get( + _url("/images/create?fromSrc=docker.io%2Falpine%3Alatest")) + # calling out to podman is easier than the API for running a container + subprocess.run([podman(), "run", "alpine", "/bin/ls"], + check=True, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL) + + @classmethod + def setUpClass(cls): + super().setUpClass() + + TestApi.podman = subprocess.Popen( + [ + podman(), "system", "service", "tcp:localhost:8080", + "--log-level=debug", "--time=0" + ], + shell=False, + stdin=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + time.sleep(2) + + @classmethod + def tearDownClass(cls): + TestApi.podman.terminate() + stdout, stderr = TestApi.podman.communicate(timeout=0.5) + if stdout: + print("\nService Stdout:\n" + stdout.decode('utf-8')) + if stderr: + print("\nService Stderr:\n" + stderr.decode('utf-8')) + + if TestApi.podman.returncode > 0: + sys.stderr.write("podman exited with error code {}\n".format( + TestApi.podman.returncode)) + sys.exit(2) + + return super().tearDownClass() + + def test_info(self): + r = requests.get(_url("/info")) + self.assertEqual(r.status_code, 200) + self.assertIsNotNone(r.content) + _ = json.loads(r.text) + + def test_events(self): + r = requests.get(_url("/events?stream=false")) + self.assertEqual(r.status_code, 200, r.text) + self.assertIsNotNone(r.content) + for line in r.text.splitlines(): + obj = json.loads(line) + # Actor.ID is uppercase for compatibility + _ = obj["Actor"]["ID"] + + def test_containers(self): + r = requests.get(_url("/containers/json"), timeout=5) + self.assertEqual(r.status_code, 200, r.text) + obj = json.loads(r.text) + self.assertEqual(len(obj), 0) + + def test_containers_all(self): + r = requests.get(_url("/containers/json?all=true")) + self.assertEqual(r.status_code, 200, r.text) + self.validateObjectFields(r.text) + + def test_inspect_container(self): + r = requests.get(_url(ctnr("/containers/{}/json"))) + self.assertEqual(r.status_code, 200, r.text) + obj = self.validateObjectFields(r.content) + _ = parse(obj["Created"]) + + def test_stats(self): + r = requests.get(_url(ctnr("/containers/{}/stats?stream=false"))) + self.assertIn(r.status_code, (200, 409), r.text) + if r.status_code == 200: + self.validateObjectFields(r.text) + + def test_delete_containers(self): + r = requests.delete(_url(ctnr("/containers/{}"))) + self.assertEqual(r.status_code, 204, r.text) + + def test_stop_containers(self): + r = requests.post(_url(ctnr("/containers/{}/start"))) + self.assertIn(r.status_code, (204, 304), r.text) + + r = requests.post(_url(ctnr("/containers/{}/stop"))) + self.assertIn(r.status_code, (204, 304), r.text) + + def test_start_containers(self): + r = requests.post(_url(ctnr("/containers/{}/stop"))) + self.assertIn(r.status_code, (204, 304), r.text) + + r = requests.post(_url(ctnr("/containers/{}/start"))) + self.assertIn(r.status_code, (204, 304), r.text) + + def test_restart_containers(self): + r = requests.post(_url(ctnr("/containers/{}/start"))) + self.assertIn(r.status_code, (204, 304), r.text) + + r = requests.post(_url(ctnr("/containers/{}/restart")), timeout=5) + self.assertEqual(r.status_code, 204, r.text) + + def test_resize(self): + r = requests.post(_url(ctnr("/containers/{}/resize?h=43&w=80"))) + self.assertIn(r.status_code, (200, 409), r.text) + if r.status_code == 200: + self.assertIsNone(r.text) + + def test_attach_containers(self): + r = requests.post(_url(ctnr("/containers/{}/attach"))) + self.assertIn(r.status_code, (101, 409), r.text) + + def test_logs_containers(self): + r = requests.get(_url(ctnr("/containers/{}/logs?stdout=true"))) + self.assertEqual(r.status_code, 200, r.text) + + def test_post_create(self): + self.skipTest("TODO: create request body") + r = requests.post(_url("/containers/create?args=True")) + self.assertEqual(r.status_code, 200, r.text) + json.loads(r.text) + + def test_commit(self): + r = requests.post(_url(ctnr("/commit?container={}"))) + self.assertEqual(r.status_code, 200, r.text) + self.validateObjectFields(r.text) + + def test_images(self): + r = requests.get(_url("/images/json")) + self.assertEqual(r.status_code, 200, r.text) + self.validateObjectFields(r.content) + + def test_inspect_image(self): + r = requests.get(_url("/images/alpine/json")) + self.assertEqual(r.status_code, 200, r.text) + obj = self.validateObjectFields(r.content) + _ = parse(obj["Created"]) + + def test_delete_image(self): + r = requests.delete(_url("/images/alpine?force=true")) + self.assertEqual(r.status_code, 200, r.text) + json.loads(r.text) + + def test_pull(self): + r = requests.post(_url("/images/pull?reference=alpine"), timeout=5) + self.assertEqual(r.status_code, 200, r.text) + json.loads(r.text) + + def test_search(self): + # Had issues with this test hanging when repositories not happy + def do_search(): + r = requests.get(_url("/images/search?term=alpine"), timeout=5) + self.assertEqual(r.status_code, 200, r.text) + json.loads(r.text) + + search = Process(target=do_search) + search.start() + search.join(timeout=10) + self.assertFalse(search.is_alive(), "/images/search took too long") + + def validateObjectFields(self, buffer): + objs = json.loads(buffer) + if not isinstance(objs, dict): + for o in objs: + _ = o["Id"] + else: + _ = objs["Id"] + return objs + + +if __name__ == '__main__': + unittest.main() diff --git a/test/apiv2/test-apiv2 b/test/apiv2/test-apiv2 index 11c914704..7a3518df2 100755 --- a/test/apiv2/test-apiv2 +++ b/test/apiv2/test-apiv2 @@ -207,13 +207,21 @@ function t() { fi cat $WORKDIR/curl.headers.out >>$LOG 2>/dev/null || true - output=$(< $WORKDIR/curl.result.out) - # Log results. If JSON, filter through jq for readability - if egrep -qi '^Content-Type: application/json' $WORKDIR/curl.headers.out; then - jq . <<<"$output" >>$LOG - else + # Log results, if text. If JSON, filter through jq for readability. + content_type=$(sed -ne 's/^Content-Type:[ ]\+//pi' <$WORKDIR/curl.headers.out) + + if [[ $content_type =~ /octet ]]; then + output="[$(file --brief $WORKDIR/curl.result.out)]" echo "$output" >>$LOG + else + output=$(< $WORKDIR/curl.result.out) + + if [[ $content_type =~ application/json ]]; then + jq . <<<"$output" >>$LOG + else + echo "$output" >>$LOG + fi fi # Test return code @@ -232,6 +240,7 @@ function t() { return fi + local i for i; do case "$i" in # Exact match on json field diff --git a/test/e2e/attach_test.go b/test/e2e/attach_test.go index 7233d169c..e9050b53b 100644 --- a/test/e2e/attach_test.go +++ b/test/e2e/attach_test.go @@ -33,7 +33,6 @@ var _ = Describe("Podman attach", func() { podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) - }) It("podman attach to bogus container", func() { diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 80ee83f44..e12edad49 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -21,6 +21,7 @@ import ( "github.com/containers/storage/pkg/reexec" "github.com/containers/storage/pkg/stringid" jsoniter "github.com/json-iterator/go" + "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gexec" @@ -573,3 +574,10 @@ func (p *PodmanTestIntegration) CreateSeccompJson(in []byte) (string, error) { } return jsonFile, nil } + +func SkipIfNotFedora() { + info := GetHostDistributionInfo() + if info.Distribution != "fedora" { + ginkgo.Skip("Test can only run on Fedora") + } +} diff --git a/test/e2e/events_test.go b/test/e2e/events_test.go index 460554b77..8c496872f 100644 --- a/test/e2e/events_test.go +++ b/test/e2e/events_test.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "strings" + "time" . "github.com/containers/libpod/test/utils" . "github.com/onsi/ginkgo" @@ -24,23 +25,26 @@ var _ = Describe("Podman events", func() { os.Exit(1) } podmanTest = PodmanTestCreate(tempdir) + podmanTest.Setup() podmanTest.SeedImages() }) AfterEach(func() { podmanTest.Cleanup() f := CurrentGinkgoTestDescription() - timedResult := fmt.Sprintf("Test: %s completed in %f seconds", f.TestText, f.Duration.Seconds()) - GinkgoWriter.Write([]byte(timedResult)) - + processTestResult(f) }) // For most, all, of these tests we do not "live" test following a log because it may make a fragile test // system more complex. Instead we run the "events" and then verify that the events are processed correctly. // Perhaps a future version of this test would put events in a go func and send output back over a channel // while events occur. + + // These tests are only known to work on Fedora ATM. Other distributions + // will be skipped. It("podman events", func() { - Skip("need to verify images have correct packages for journald") + SkipIfRootless() + SkipIfNotFedora() _, ec, _ := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) result := podmanTest.Podman([]string{"events", "--stream=false"}) @@ -49,7 +53,8 @@ var _ = Describe("Podman events", func() { }) It("podman events with an event filter", func() { - Skip("need to verify images have correct packages for journald") + SkipIfRootless() + SkipIfNotFedora() _, ec, _ := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=start"}) @@ -59,11 +64,14 @@ var _ = Describe("Podman events", func() { }) It("podman events with an event filter and container=cid", func() { - Skip("need to verify images have correct packages for journald") + Skip("Does not work on v2") + SkipIfRootless() + SkipIfNotFedora() _, ec, cid := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) _, ec2, cid2 := podmanTest.RunLsContainer("") Expect(ec2).To(Equal(0)) + time.Sleep(5 * time.Second) result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=start", "--filter", fmt.Sprintf("container=%s", cid)}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(0)) @@ -72,7 +80,8 @@ var _ = Describe("Podman events", func() { }) It("podman events with a type and filter container=id", func() { - Skip("need to verify images have correct packages for journald") + SkipIfRootless() + SkipIfNotFedora() _, ec, cid := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "type=pod", "--filter", fmt.Sprintf("container=%s", cid)}) @@ -82,7 +91,8 @@ var _ = Describe("Podman events", func() { }) It("podman events with a type", func() { - Skip("need to verify images have correct packages for journald") + SkipIfRootless() + SkipIfNotFedora() setup := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:foobarpod", ALPINE, "top"}) setup.WaitWithDefaultTimeout() stop := podmanTest.Podman([]string{"pod", "stop", "foobarpod"}) @@ -97,7 +107,8 @@ var _ = Describe("Podman events", func() { }) It("podman events --since", func() { - Skip("need to verify images have correct packages for journald") + SkipIfRootless() + SkipIfNotFedora() _, ec, _ := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) result := podmanTest.Podman([]string{"events", "--stream=false", "--since", "1m"}) @@ -106,7 +117,8 @@ var _ = Describe("Podman events", func() { }) It("podman events --until", func() { - Skip("need to verify images have correct packages for journald") + SkipIfRootless() + SkipIfNotFedora() _, ec, _ := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) test := podmanTest.Podman([]string{"events", "--help"}) @@ -118,37 +130,28 @@ var _ = Describe("Podman events", func() { }) It("podman events format", func() { - Skip(v2remotefail) - info := GetHostDistributionInfo() - if info.Distribution != "fedora" { - Skip("need to verify images have correct packages for journald") - } + SkipIfRootless() + SkipIfNotFedora() _, ec, _ := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) test := podmanTest.Podman([]string{"events", "--stream=false", "--format", "json"}) test.WaitWithDefaultTimeout() - fmt.Println(test.OutputToStringArray()) jsonArr := test.OutputToStringArray() Expect(len(jsonArr)).To(Not(BeZero())) eventsMap := make(map[string]string) err := json.Unmarshal([]byte(jsonArr[0]), &eventsMap) - if err != nil { - os.Exit(1) - } + Expect(err).To(BeNil()) _, exist := eventsMap["Status"] Expect(exist).To(BeTrue()) Expect(test.ExitCode()).To(BeZero()) test = podmanTest.Podman([]string{"events", "--stream=false", "--format", "{{json.}}"}) test.WaitWithDefaultTimeout() - fmt.Println(test.OutputToStringArray()) jsonArr = test.OutputToStringArray() Expect(len(jsonArr)).To(Not(BeZero())) eventsMap = make(map[string]string) err = json.Unmarshal([]byte(jsonArr[0]), &eventsMap) - if err != nil { - os.Exit(1) - } + Expect(err).To(BeNil()) _, exist = eventsMap["Status"] Expect(exist).To(BeTrue()) Expect(test.ExitCode()).To(BeZero()) diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index 8965ce297..12ce4661f 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -114,6 +114,17 @@ var _ = Describe("Podman ps", func() { It("podman ps last flag", func() { Skip("--last flag nonfunctional and disabled") + // Make sure that non-running containers are being counted as + // well. + session := podmanTest.Podman([]string{"create", "alpine", "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + result := podmanTest.Podman([]string{"ps", "--last", "2"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(len(result.OutputToStringArray())).Should(Equal(2)) // 1 container + _, ec, _ := podmanTest.RunLsContainer("test1") Expect(ec).To(Equal(0)) @@ -123,10 +134,20 @@ var _ = Describe("Podman ps", func() { _, ec, _ = podmanTest.RunLsContainer("test3") Expect(ec).To(Equal(0)) - result := podmanTest.Podman([]string{"ps", "--last", "2"}) + result = podmanTest.Podman([]string{"ps", "--last", "2"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(len(result.OutputToStringArray())).Should(Equal(3)) // 2 containers + + result = podmanTest.Podman([]string{"ps", "--last", "3"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(len(result.OutputToStringArray())).Should(Equal(4)) // 3 containers + + result = podmanTest.Podman([]string{"ps", "--last", "100"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(0)) - Expect(len(result.OutputToStringArray())).Should(Equal(3)) + Expect(len(result.OutputToStringArray())).Should(Equal(5)) // 4 containers (3 running + 1 created) }) It("podman ps no-trunc", func() { diff --git a/test/system/010-images.bats b/test/system/010-images.bats index 6957d4830..2b1845d72 100644 --- a/test/system/010-images.bats +++ b/test/system/010-images.bats @@ -28,7 +28,7 @@ load helpers # 'created': podman includes fractional seconds, podman-remote does not tests=" Names[0] | $PODMAN_TEST_IMAGE_FQN -ID | [0-9a-f]\\\{64\\\} +Id | [0-9a-f]\\\{64\\\} Digest | sha256:[0-9a-f]\\\{64\\\} CreatedAt | [0-9-]\\\+T[0-9:.]\\\+Z Size | [0-9]\\\+ diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats index e3643a3bd..f34cd0707 100644 --- a/test/system/200-pod.bats +++ b/test/system/200-pod.bats @@ -170,4 +170,16 @@ function random_ip() { is "$output" ".*options $dns_opt" "--dns-opt was added" } +@test "podman pod inspect - format" { + skip_if_remote "podman-pod does not work with podman-remote" + + run_podman pod create --name podtest + podid=$output + + run_podman pod inspect --format '-> {{.Name}}: {{.NumContainers}}' podtest + is "$output" "-> podtest: 1" + + run_podman pod rm -f podtest +} + # vim: filetype=sh |