diff options
Diffstat (limited to 'test')
86 files changed, 2022 insertions, 448 deletions
diff --git a/test/apiv2/01-basic.at b/test/apiv2/01-basic.at index 0e94ddb7a..18ec9bbe8 100644 --- a/test/apiv2/01-basic.at +++ b/test/apiv2/01-basic.at @@ -10,13 +10,13 @@ t HEAD /_ping 200 t GET /libpod/_ping 200 OK for i in /version version; do - t GET $i 200 \ - .Components[0].Name="Podman Engine" \ - .Components[0].Details.APIVersion=1.40 \ - .Components[0].Details.MinAPIVersion=1.24 \ - .Components[0].Details.Os=linux \ - .ApiVersion=1.40 \ - .MinAPIVersion=1.24 \ + t GET $i 200 \ + .Components[0].Name="Podman Engine" \ + .Components[0].Details.APIVersion=1.0.0 \ + .Components[0].Details.MinAPIVersion=1.0.0 \ + .Components[0].Details.Os=linux \ + .ApiVersion=1.0.0 \ + .MinAPIVersion=1.0.0 \ .Os=linux done 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 1af76b4be..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 @@ -270,7 +279,7 @@ function start_service() { die "Cannot start service on non-localhost ($HOST)" fi - $PODMAN_BIN --root $WORKDIR system service --timeout 15 tcp:127.0.0.1:$PORT \ + $PODMAN_BIN --root $WORKDIR system service --time 15 tcp:127.0.0.1:$PORT \ &> $WORKDIR/server.log & service_pid=$! diff --git a/test/e2e/attach_test.go b/test/e2e/attach_test.go index 6ca8a537c..e9050b53b 100644 --- a/test/e2e/attach_test.go +++ b/test/e2e/attach_test.go @@ -20,7 +20,6 @@ var _ = Describe("Podman attach", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) @@ -34,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/build_test.go b/test/e2e/build_test.go index 76651283a..9e41fd231 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -177,7 +177,6 @@ var _ = Describe("Podman build", func() { }) It("podman Test PATH in built image", func() { - Skip(v2fail) // Run error - we don't set data from the image (i.e., PATH) yet path := "/tmp:/bin:/usr/bin:/usr/sbin" session := podmanTest.PodmanNoCache([]string{ "build", "-f", "build/basicalpine/Containerfile.path", "-t", "test-path", diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 160af1bd5..e12edad49 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -1,7 +1,6 @@ package integration import ( - "encoding/json" "fmt" "io/ioutil" "math/rand" @@ -21,9 +20,11 @@ import ( "github.com/containers/storage" "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" + . "github.com/onsi/gomega/gexec" "github.com/pkg/errors" ) @@ -35,7 +36,7 @@ var ( INTEGRATION_ROOT string CGROUP_MANAGER = "systemd" ARTIFACT_DIR = "/tmp/.artifacts" - RESTORE_IMAGES = []string{ALPINE, BB} + RESTORE_IMAGES = []string{ALPINE, BB, nginx} defaultWaitTimeout = 90 ) @@ -53,6 +54,7 @@ type PodmanTestIntegration struct { Host HostOS Timings []string TmpDir string + RemoteStartErr error } var LockTmpDir string @@ -259,12 +261,12 @@ func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration { p.PodmanTest.RemotePodmanBinary = podmanRemoteBinary uuid := stringid.GenerateNonCryptoID() if !rootless.IsRootless() { - p.VarlinkEndpoint = fmt.Sprintf("unix:/run/podman/io.podman-%s", uuid) + p.RemoteSocket = fmt.Sprintf("unix:/run/podman/podman-%s.sock", uuid) } else { runtimeDir := os.Getenv("XDG_RUNTIME_DIR") - socket := fmt.Sprintf("io.podman-%s", uuid) + socket := fmt.Sprintf("podman-%s.sock", uuid) fqpath := filepath.Join(runtimeDir, socket) - p.VarlinkEndpoint = fmt.Sprintf("unix:%s", fqpath) + p.RemoteSocket = fmt.Sprintf("unix:%s", fqpath) } } @@ -314,7 +316,7 @@ func (p *PodmanTestIntegration) createArtifact(image string) { // image and returns json func (s *PodmanSessionIntegration) InspectImageJSON() []inspect.ImageData { var i []inspect.ImageData - err := json.Unmarshal(s.Out.Contents(), &i) + err := jsoniter.Unmarshal(s.Out.Contents(), &i) Expect(err).To(BeNil()) return i } @@ -324,7 +326,7 @@ func (p *PodmanTestIntegration) InspectContainer(name string) []define.InspectCo cmd := []string{"inspect", name} session := p.Podman(cmd) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) return session.InspectContainerToJSON() } @@ -419,7 +421,7 @@ func (p *PodmanTestIntegration) PodmanPID(args []string) (*PodmanSessionIntegrat podmanOptions := p.MakeOptions(args, false, false) fmt.Printf("Running: %s %s\n", p.PodmanBinary, strings.Join(podmanOptions, " ")) command := exec.Command(p.PodmanBinary, podmanOptions...) - session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter) + session, err := Start(command, GinkgoWriter, GinkgoWriter) if err != nil { Fail(fmt.Sprintf("unable to run podman command: %s", strings.Join(podmanOptions, " "))) } @@ -441,7 +443,7 @@ func (p *PodmanTestIntegration) Cleanup() { session := p.Podman([]string{"rm", "-fa"}) session.Wait(90) - p.StopVarlink() + p.StopRemoteService() // Nuke tempdir if err := os.RemoveAll(p.TempDir); err != nil { fmt.Printf("%q\n", err) @@ -451,17 +453,6 @@ func (p *PodmanTestIntegration) Cleanup() { resetRegistriesConfigEnv() } -// CleanupPod cleans up the temporary store -func (p *PodmanTestIntegration) CleanupPod() { - // Remove all containers - session := p.Podman([]string{"pod", "rm", "-fa"}) - session.Wait(90) - // Nuke tempdir - if err := os.RemoveAll(p.TempDir); err != nil { - fmt.Printf("%q\n", err) - } -} - // CleanupVolume cleans up the temporary store func (p *PodmanTestIntegration) CleanupVolume() { // Remove all containers @@ -494,7 +485,7 @@ func (p *PodmanTestIntegration) PullImage(image string) error { // container and returns json func (s *PodmanSessionIntegration) InspectContainerToJSON() []define.InspectContainerData { var i []define.InspectContainerData - err := json.Unmarshal(s.Out.Contents(), &i) + err := jsoniter.Unmarshal(s.Out.Contents(), &i) Expect(err).To(BeNil()) return i } @@ -502,7 +493,7 @@ func (s *PodmanSessionIntegration) InspectContainerToJSON() []define.InspectCont // InspectPodToJSON takes the sessions output from a pod inspect and returns json func (s *PodmanSessionIntegration) InspectPodToJSON() define.InspectPodData { var i define.InspectPodData - err := json.Unmarshal(s.Out.Contents(), &i) + err := jsoniter.Unmarshal(s.Out.Contents(), &i) Expect(err).To(BeNil()) return i } @@ -583,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/config.go b/test/e2e/config.go index 0e1850614..71c4dee31 100644 --- a/test/e2e/config.go +++ b/test/e2e/config.go @@ -27,4 +27,8 @@ var ( // v2fail is a temporary variable to help us track // tests that fail in v2 v2fail = "does not pass integration tests with v2 podman" + + // v2remotefail is a temporary variable to help us track + // tests that fail in v2 remote + v2remotefail = "does not pass integration tests with v2 podman remote" ) diff --git a/test/e2e/config/containers.conf b/test/e2e/config/containers.conf index 55d18f5e8..a3bdde786 100644 --- a/test/e2e/config/containers.conf +++ b/test/e2e/config/containers.conf @@ -38,7 +38,7 @@ shm_size = "201k" # If it is empty or commented out, only the default devices will be used # devices = [ - "/dev/zero:/dev/notone,rwm", + "/dev/zero:/dev/notone:rwm", ] default_sysctls = [ diff --git a/test/e2e/container_inspect_test.go b/test/e2e/container_inspect_test.go index 91c025197..9cbcbbc7c 100644 --- a/test/e2e/container_inspect_test.go +++ b/test/e2e/container_inspect_test.go @@ -27,7 +27,7 @@ var _ = Describe("Podman container inspect", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) }) diff --git a/test/e2e/containers_conf_test.go b/test/e2e/containers_conf_test.go index b984a35f3..a2ef7eb4a 100644 --- a/test/e2e/containers_conf_test.go +++ b/test/e2e/containers_conf_test.go @@ -23,7 +23,6 @@ var _ = Describe("Podman run", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) diff --git a/test/e2e/cp_test.go b/test/e2e/cp_test.go index 2ff6fe65e..f95f8646c 100644 --- a/test/e2e/cp_test.go +++ b/test/e2e/cp_test.go @@ -22,7 +22,6 @@ var _ = Describe("Podman cp", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) @@ -96,7 +95,7 @@ var _ = Describe("Podman cp", func() { }) It("podman cp dir to dir", func() { - testDirPath := filepath.Join(podmanTest.RunRoot, "TestDir") + testDirPath := filepath.Join(podmanTest.RunRoot, "TestDir1") session := podmanTest.Podman([]string{"create", ALPINE, "ls", "/foodir"}) session.WaitWithDefaultTimeout() @@ -105,6 +104,7 @@ var _ = Describe("Podman cp", func() { err := os.Mkdir(testDirPath, 0755) Expect(err).To(BeNil()) + defer os.RemoveAll(testDirPath) session = podmanTest.Podman([]string{"cp", testDirPath, name + ":/foodir"}) session.WaitWithDefaultTimeout() @@ -138,8 +138,6 @@ var _ = Describe("Podman cp", func() { res, err := cmd.Output() Expect(err).To(BeNil()) Expect(len(res)).To(Equal(0)) - - os.RemoveAll(testDirPath) }) It("podman cp stdin/stdout", func() { @@ -148,9 +146,10 @@ var _ = Describe("Podman cp", func() { Expect(session.ExitCode()).To(Equal(0)) name := session.OutputToString() - testDirPath := filepath.Join(podmanTest.RunRoot, "TestDir") + testDirPath := filepath.Join(podmanTest.RunRoot, "TestDir2") err := os.Mkdir(testDirPath, 0755) Expect(err).To(BeNil()) + defer os.RemoveAll(testDirPath) cmd := exec.Command("tar", "-zcvf", "file.tar.gz", testDirPath) _, err = cmd.Output() Expect(err).To(BeNil()) @@ -169,7 +168,6 @@ var _ = Describe("Podman cp", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - os.RemoveAll(testDirPath) os.Remove("file.tar.gz") }) @@ -185,9 +183,10 @@ var _ = Describe("Podman cp", func() { path, err := os.Getwd() Expect(err).To(BeNil()) - testDirPath := filepath.Join(path, "TestDir") + testDirPath := filepath.Join(path, "TestDir3") err = os.Mkdir(testDirPath, 0777) Expect(err).To(BeNil()) + defer os.RemoveAll(testDirPath) cmd := exec.Command("tar", "-cvf", "file.tar", testDirPath) _, err = cmd.Output() Expect(err).To(BeNil()) @@ -202,7 +201,6 @@ var _ = Describe("Podman cp", func() { Expect(session.OutputToString()).To(ContainSubstring("file.tar")) os.Remove("file.tar") - os.RemoveAll(testDirPath) }) It("podman cp symlink", func() { diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index 82346823a..0a6373bfa 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -18,7 +18,6 @@ var _ = Describe("Podman create", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) @@ -36,13 +35,13 @@ var _ = Describe("Podman create", func() { }) It("podman create container based on a local image", func() { - session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"create", "--name", "local_image_test", ALPINE, "ls"}) session.WaitWithDefaultTimeout() cid := session.OutputToString() Expect(session.ExitCode()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) - check := podmanTest.Podman([]string{"inspect", "-l"}) + check := podmanTest.Podman([]string{"inspect", "local_image_test"}) check.WaitWithDefaultTimeout() data := check.InspectContainerToJSON() Expect(data[0].ID).To(ContainSubstring(cid)) @@ -81,12 +80,12 @@ var _ = Describe("Podman create", func() { }) It("podman create adds annotation", func() { - session := podmanTest.Podman([]string{"create", "--annotation", "HELLO=WORLD", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"create", "--annotation", "HELLO=WORLD", "--name", "annotate_test", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) - check := podmanTest.Podman([]string{"inspect", "-l"}) + check := podmanTest.Podman([]string{"inspect", "annotate_test"}) check.WaitWithDefaultTimeout() data := check.InspectContainerToJSON() value, ok := data[0].Config.Annotations["HELLO"] @@ -95,12 +94,12 @@ var _ = Describe("Podman create", func() { }) It("podman create --entrypoint command", func() { - session := podmanTest.Podman([]string{"create", "--entrypoint", "/bin/foobar", ALPINE}) + session := podmanTest.Podman([]string{"create", "--name", "entrypoint_test", "--entrypoint", "/bin/foobar", ALPINE}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) - result := podmanTest.Podman([]string{"inspect", "-l", "--format", "{{.Config.Entrypoint}}"}) + result := podmanTest.Podman([]string{"inspect", "entrypoint_test", "--format", "{{.Config.Entrypoint}}"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(0)) Expect(result.OutputToString()).To(Equal("/bin/foobar")) @@ -120,18 +119,19 @@ var _ = Describe("Podman create", func() { It("podman create --entrypoint json", func() { jsonString := `[ "/bin/foo", "-c"]` - session := podmanTest.Podman([]string{"create", "--entrypoint", jsonString, ALPINE}) + session := podmanTest.Podman([]string{"create", "--name", "entrypoint_json", "--entrypoint", jsonString, ALPINE}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) - result := podmanTest.Podman([]string{"inspect", "-l", "--format", "{{.Config.Entrypoint}}"}) + result := podmanTest.Podman([]string{"inspect", "entrypoint_json", "--format", "{{.Config.Entrypoint}}"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(0)) Expect(result.OutputToString()).To(Equal("/bin/foo -c")) }) It("podman create --mount flag with multiple mounts", func() { + Skip(v2remotefail) vol1 := filepath.Join(podmanTest.TempDir, "vol-test1") err := os.MkdirAll(vol1, 0755) Expect(err).To(BeNil()) @@ -157,6 +157,7 @@ var _ = Describe("Podman create", func() { if podmanTest.Host.Arch == "ppc64le" { Skip("skip failing test on ppc64le") } + Skip(v2remotefail) mountPath := filepath.Join(podmanTest.TempDir, "secrets") os.Mkdir(mountPath, 0755) session := podmanTest.Podman([]string{"create", "--name", "test", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) @@ -206,7 +207,7 @@ var _ = Describe("Podman create", func() { session = podmanTest.Podman([]string{"logs", "test_tmpfs"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - Expect(session.OutputToString()).To(ContainSubstring("/create/test rw,nosuid,nodev,noexec,relatime - tmpfs")) + Expect(session.OutputToString()).To(ContainSubstring("/create/test rw,nosuid,nodev,relatime - tmpfs")) }) It("podman create --pod automatically", func() { @@ -234,11 +235,11 @@ var _ = Describe("Podman create", func() { }) It("podman create --pull", func() { - session := podmanTest.PodmanNoCache([]string{"create", "--pull", "never", "--name=foo", "nginx"}) + session := podmanTest.PodmanNoCache([]string{"create", "--pull", "never", "--name=foo", "debian"}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) - session = podmanTest.PodmanNoCache([]string{"create", "--pull", "always", "--name=foo", "nginx"}) + session = podmanTest.PodmanNoCache([]string{"create", "--pull", "always", "--name=foo", "debian"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) }) @@ -343,4 +344,53 @@ var _ = Describe("Podman create", func() { Expect(ok2).To(BeTrue()) Expect(val2).To(Equal("bar")) }) + + It("podman create with --restart=on-failure:5 parses correctly", func() { + ctrName := "testctr" + session := podmanTest.Podman([]string{"create", "-t", "--restart", "on-failure:5", "--name", ctrName, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + inspect := podmanTest.Podman([]string{"inspect", ctrName}) + inspect.WaitWithDefaultTimeout() + data := inspect.InspectContainerToJSON() + Expect(len(data)).To(Equal(1)) + Expect(data[0].HostConfig.RestartPolicy.Name).To(Equal("on-failure")) + Expect(data[0].HostConfig.RestartPolicy.MaximumRetryCount).To(Equal(uint(5))) + }) + + It("podman create with --restart-policy=always:5 fails", func() { + session := podmanTest.Podman([]string{"create", "-t", "--restart", "always:5", ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Not(Equal(0))) + }) + + It("podman create with -m 1000000 sets swap to 2000000", func() { + numMem := 1000000 + ctrName := "testCtr" + session := podmanTest.Podman([]string{"create", "-t", "-m", fmt.Sprintf("%db", numMem), "--name", ctrName, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + inspect := podmanTest.Podman([]string{"inspect", ctrName}) + inspect.WaitWithDefaultTimeout() + data := inspect.InspectContainerToJSON() + Expect(len(data)).To(Equal(1)) + Expect(data[0].HostConfig.MemorySwap).To(Equal(int64(2 * numMem))) + }) + + It("podman create --cpus 5 sets nanocpus", func() { + numCpus := 5 + nanoCPUs := numCpus * 1000000000 + ctrName := "testCtr" + session := podmanTest.Podman([]string{"create", "-t", "--cpus", fmt.Sprintf("%d", numCpus), "--name", ctrName, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + inspect := podmanTest.Podman([]string{"inspect", ctrName}) + inspect.WaitWithDefaultTimeout() + data := inspect.InspectContainerToJSON() + Expect(len(data)).To(Equal(1)) + Expect(data[0].HostConfig.NanoCpus).To(Equal(int64(nanoCPUs))) + }) }) diff --git a/test/e2e/events_test.go b/test/e2e/events_test.go index 0636af74c..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,24 +130,30 @@ var _ = Describe("Podman events", func() { }) It("podman events format", func() { - 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() + jsonArr = test.OutputToStringArray() + Expect(len(jsonArr)).To(Not(BeZero())) + eventsMap = make(map[string]string) + err = json.Unmarshal([]byte(jsonArr[0]), &eventsMap) + Expect(err).To(BeNil()) + _, exist = eventsMap["Status"] + Expect(exist).To(BeTrue()) + Expect(test.ExitCode()).To(BeZero()) }) }) diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go index 8b95794d2..87dddb233 100644 --- a/test/e2e/exec_test.go +++ b/test/e2e/exec_test.go @@ -18,6 +18,7 @@ var _ = Describe("Podman exec", func() { ) BeforeEach(func() { + Skip(v2remotefail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) @@ -282,4 +283,31 @@ var _ = Describe("Podman exec", func() { Expect(exec.ExitCode()).To(Equal(0)) Expect(strings.Contains(exec.OutputToString(), fmt.Sprintf("%s(%s)", gid, groupName))).To(BeTrue()) }) + + It("podman exec --detach", func() { + ctrName := "testctr" + ctr := podmanTest.Podman([]string{"run", "-t", "-i", "-d", "--name", ctrName, ALPINE, "top"}) + ctr.WaitWithDefaultTimeout() + Expect(ctr.ExitCode()).To(Equal(0)) + + exec1 := podmanTest.Podman([]string{"exec", "-t", "-i", "-d", ctrName, "top"}) + exec1.WaitWithDefaultTimeout() + Expect(ctr.ExitCode()).To(Equal(0)) + + data := podmanTest.InspectContainer(ctrName) + Expect(len(data)).To(Equal(1)) + Expect(len(data[0].ExecIDs)).To(Equal(1)) + Expect(strings.Contains(exec1.OutputToString(), data[0].ExecIDs[0])).To(BeTrue()) + + exec2 := podmanTest.Podman([]string{"exec", "-t", "-i", ctrName, "ps", "-a"}) + exec2.WaitWithDefaultTimeout() + Expect(ctr.ExitCode()).To(Equal(0)) + Expect(strings.Count(exec2.OutputToString(), "top")).To(Equal(2)) + + // Ensure that stop with a running detached exec session is + // clean. + stop := podmanTest.Podman([]string{"stop", ctrName}) + stop.WaitWithDefaultTimeout() + Expect(stop.ExitCode()).To(Equal(0)) + }) }) diff --git a/test/e2e/export_test.go b/test/e2e/export_test.go index 1c84c6f4d..fb2582796 100644 --- a/test/e2e/export_test.go +++ b/test/e2e/export_test.go @@ -34,7 +34,6 @@ var _ = Describe("Podman export", func() { }) It("podman export output flag", func() { - SkipIfRemote() _, ec, cid := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) @@ -50,7 +49,6 @@ var _ = Describe("Podman export", func() { }) It("podman container export output flag", func() { - SkipIfRemote() _, ec, cid := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go index e4f487634..389f2c822 100644 --- a/test/e2e/generate_kube_test.go +++ b/test/e2e/generate_kube_test.go @@ -21,7 +21,6 @@ var _ = Describe("Podman generate kube", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go index abfca4db9..d5ae441e2 100644 --- a/test/e2e/generate_systemd_test.go +++ b/test/e2e/generate_systemd_test.go @@ -233,4 +233,96 @@ var _ = Describe("Podman generate systemd", func() { Expect(session.ExitCode()).To(Equal(125)) }) + It("podman generate systemd --container-prefix con", func() { + n := podmanTest.Podman([]string{"create", "--name", "foo", "alpine", "top"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + session := podmanTest.Podman([]string{"generate", "systemd", "--name", "--container-prefix", "con", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Grepping the output (in addition to unit tests) + found, _ := session.GrepString("# con-foo.service") + Expect(found).To(BeTrue()) + }) + + It("podman generate systemd --separator _", func() { + n := podmanTest.Podman([]string{"create", "--name", "foo", "alpine", "top"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + session := podmanTest.Podman([]string{"generate", "systemd", "--name", "--separator", "_", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Grepping the output (in addition to unit tests) + found, _ := session.GrepString("# container_foo.service") + Expect(found).To(BeTrue()) + }) + + It("podman generate systemd pod --pod-prefix p", func() { + n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-1", "alpine", "top"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-2", "alpine", "top"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + session := podmanTest.Podman([]string{"generate", "systemd", "--pod-prefix", "p", "--name", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Grepping the output (in addition to unit tests) + found, _ := session.GrepString("# p-foo.service") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("Requires=container-foo-1.service container-foo-2.service") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("# container-foo-1.service") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("BindsTo=p-foo.service") + Expect(found).To(BeTrue()) + }) + + It("podman generate systemd pod --pod-prefix p --container-prefix con --separator _ change all prefixes/separator", func() { + n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-1", "alpine", "top"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-2", "alpine", "top"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + session := podmanTest.Podman([]string{"generate", "systemd", "--container-prefix", "con", "--pod-prefix", "p", "--separator", "_", "--name", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Grepping the output (in addition to unit tests) + found, _ := session.GrepString("# p_foo.service") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("Requires=con_foo-1.service con_foo-2.service") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("# con_foo-1.service") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("# con_foo-2.service") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("BindsTo=p_foo.service") + Expect(found).To(BeTrue()) + }) }) diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go index 19a8658ac..8e63d9f4c 100644 --- a/test/e2e/healthcheck_run_test.go +++ b/test/e2e/healthcheck_run_test.go @@ -176,6 +176,7 @@ var _ = Describe("Podman healthcheck run", func() { }) It("podman healthcheck single healthy result changes failed to healthy", func() { + Skip(v2remotefail) session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-retries", "2", "--health-cmd", "ls /foo || exit 1", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go index c0165e060..1b23aba36 100644 --- a/test/e2e/images_test.go +++ b/test/e2e/images_test.go @@ -10,6 +10,7 @@ import ( "github.com/docker/go-units" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman images", func() { @@ -20,7 +21,6 @@ var _ = Describe("Podman images", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) @@ -39,7 +39,7 @@ var _ = Describe("Podman images", func() { It("podman images", func() { session := podmanTest.Podman([]string{"images"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 2)) Expect(session.LineInOuputStartsWith("docker.io/library/alpine")).To(BeTrue()) Expect(session.LineInOuputStartsWith("docker.io/library/busybox")).To(BeTrue()) @@ -48,11 +48,11 @@ var _ = Describe("Podman images", func() { It("podman images with no images prints header", func() { rmi := podmanTest.PodmanNoCache([]string{"rmi", "-a"}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(Equal(0)) + Expect(rmi).Should(Exit(0)) session := podmanTest.PodmanNoCache([]string{"images"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(1)) Expect(session.LineInOutputContains("REPOSITORY")).To(BeTrue()) }) @@ -60,7 +60,7 @@ var _ = Describe("Podman images", func() { It("podman image List", func() { session := podmanTest.Podman([]string{"image", "list"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 2)) Expect(session.LineInOuputStartsWith("docker.io/library/alpine")).To(BeTrue()) Expect(session.LineInOuputStartsWith("docker.io/library/busybox")).To(BeTrue()) @@ -71,15 +71,15 @@ var _ = Describe("Podman images", func() { podmanTest.RestoreAllArtifacts() session := podmanTest.PodmanNoCache([]string{"tag", ALPINE, "foo:a", "foo:b", "foo:c"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // tag "foo:c" to "bar:{a,b}" session = podmanTest.PodmanNoCache([]string{"tag", "foo:c", "bar:a", "bar:b"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // check all previous and the newly tagged images session = podmanTest.PodmanNoCache([]string{"images"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session.LineInOutputContainsTag("docker.io/library/alpine", "latest") session.LineInOutputContainsTag("docker.io/library/busybox", "glibc") session.LineInOutputContainsTag("foo", "a") @@ -89,14 +89,14 @@ var _ = Describe("Podman images", func() { session.LineInOutputContainsTag("bar", "b") session = podmanTest.PodmanNoCache([]string{"images", "-qn"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) - Expect(len(session.OutputToStringArray())).To(BeNumerically("==", 2)) + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(BeNumerically("==", 3)) }) It("podman images with digests", func() { session := podmanTest.Podman([]string{"images", "--digests"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 2)) Expect(session.LineInOuputStartsWith("docker.io/library/alpine")).To(BeTrue()) Expect(session.LineInOuputStartsWith("docker.io/library/busybox")).To(BeTrue()) @@ -105,14 +105,14 @@ var _ = Describe("Podman images", func() { It("podman empty images list in JSON format", func() { session := podmanTest.Podman([]string{"images", "--format=json", "not-existing-image"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) }) It("podman images in JSON format", func() { session := podmanTest.Podman([]string{"images", "--format=json"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) }) @@ -120,13 +120,13 @@ var _ = Describe("Podman images", func() { formatStr := "{{.ID}}\t{{.Created}}\t{{.CreatedAt}}\t{{.CreatedSince}}\t{{.CreatedTime}}" session := podmanTest.Podman([]string{"images", fmt.Sprintf("--format=%s", formatStr)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman images with short options", func() { session := podmanTest.Podman([]string{"images", "-qn"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 1)) }) @@ -134,111 +134,101 @@ var _ = Describe("Podman images", func() { podmanTest.RestoreAllArtifacts() session := podmanTest.PodmanNoCache([]string{"images", "-q", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(1)) session = podmanTest.PodmanNoCache([]string{"tag", ALPINE, "foo:a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.PodmanNoCache([]string{"tag", BB, "foo:b"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.PodmanNoCache([]string{"images", "-q", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) }) It("podman images filter reference", func() { - if podmanTest.RemoteTest { - Skip("Does not work on remote client") - } + SkipIfRemote() podmanTest.RestoreAllArtifacts() result := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "reference=docker.io*"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(Equal(2)) retapline := podmanTest.PodmanNoCache([]string{"images", "-f", "reference=a*pine"}) retapline.WaitWithDefaultTimeout() - Expect(retapline.ExitCode()).To(Equal(0)) - Expect(len(retapline.OutputToStringArray())).To(Equal(2)) + Expect(retapline).Should(Exit(0)) + Expect(len(retapline.OutputToStringArray())).To(Equal(3)) Expect(retapline.LineInOutputContains("alpine")).To(BeTrue()) retapline = podmanTest.PodmanNoCache([]string{"images", "-f", "reference=alpine"}) retapline.WaitWithDefaultTimeout() - Expect(retapline.ExitCode()).To(Equal(0)) - Expect(len(retapline.OutputToStringArray())).To(Equal(2)) + Expect(retapline).Should(Exit(0)) + Expect(len(retapline.OutputToStringArray())).To(Equal(3)) Expect(retapline.LineInOutputContains("alpine")).To(BeTrue()) retnone := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "reference=bogus"}) retnone.WaitWithDefaultTimeout() - Expect(retnone.ExitCode()).To(Equal(0)) + Expect(retnone).Should(Exit(0)) Expect(len(retnone.OutputToStringArray())).To(Equal(0)) }) It("podman images filter before image", func() { - if podmanTest.RemoteTest { - Skip("Does not work on remote client") - } + SkipIfRemote() dockerfile := `FROM docker.io/library/alpine:latest RUN apk update && apk add man ` podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false") result := podmanTest.Podman([]string{"images", "-q", "-f", "before=foobar.com/before:latest"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray()) >= 1).To(BeTrue()) }) It("podman images filter after image", func() { - if podmanTest.RemoteTest { - Skip("Does not work on remote client") - } + SkipIfRemote() podmanTest.RestoreAllArtifacts() rmi := podmanTest.PodmanNoCache([]string{"rmi", "busybox"}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(Equal(0)) + Expect(rmi).Should(Exit(0)) dockerfile := `FROM docker.io/library/alpine:latest ` podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false") result := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "after=docker.io/library/alpine:latest"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(Equal(0)) }) It("podman image list filter after image", func() { - if podmanTest.RemoteTest { - Skip("Does not work on remote client") - } + SkipIfRemote() podmanTest.RestoreAllArtifacts() rmi := podmanTest.PodmanNoCache([]string{"image", "rm", "busybox"}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(Equal(0)) + Expect(rmi).Should(Exit(0)) dockerfile := `FROM docker.io/library/alpine:latest ` podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false") result := podmanTest.PodmanNoCache([]string{"image", "list", "-q", "-f", "after=docker.io/library/alpine:latest"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(Equal(0)) }) It("podman images filter dangling", func() { - if podmanTest.RemoteTest { - Skip("Does not work on remote client") - } + SkipIfRemote() dockerfile := `FROM docker.io/library/alpine:latest ` podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false") podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false") result := podmanTest.Podman([]string{"images", "-q", "-f", "dangling=true"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(Equal(0)) }) @@ -248,13 +238,13 @@ RUN apk update && apk add man } session := podmanTest.Podman([]string{"inspect", "--format=json", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) imageData := session.InspectImageJSON() - result := podmanTest.Podman([]string{"images", fmt.Sprintf("sha256:%s", imageData[0].ID)}) + result := podmanTest.Podman([]string{"images", "sha256:" + imageData[0].ID}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman check for image with sha256: prefix", func() { @@ -263,13 +253,13 @@ RUN apk update && apk add man } session := podmanTest.Podman([]string{"image", "inspect", "--format=json", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) imageData := session.InspectImageJSON() result := podmanTest.Podman([]string{"image", "ls", fmt.Sprintf("sha256:%s", imageData[0].ID)}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman images sort by values", func() { @@ -277,7 +267,7 @@ RUN apk update && apk add man f := fmt.Sprintf("{{.%s}}", format) session := podmanTest.Podman([]string{"images", "--sort", value, "--format", f}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(result)) + Expect(session).Should(Exit(result)) return session.OutputToStringArray() } @@ -298,16 +288,16 @@ RUN apk update && apk add man return size1 < size2 })).To(BeTrue()) sortedArr = sortValueTest("tag", 0, "Tag") - Expect(sort.SliceIsSorted(sortedArr, func(i, j int) bool { return sortedArr[i] < sortedArr[j] })).To(BeTrue()) + Expect(sort.SliceIsSorted(sortedArr, + func(i, j int) bool { return sortedArr[i] < sortedArr[j] })). + To(BeTrue()) sortValueTest("badvalue", 125, "Tag") sortValueTest("id", 125, "badvalue") }) It("podman images --all flag", func() { - if podmanTest.RemoteTest { - Skip("Does not work on remote client") - } + SkipIfRemote() podmanTest.RestoreAllArtifacts() dockerfile := `FROM docker.io/library/alpine:latest RUN mkdir hello @@ -317,13 +307,13 @@ ENV foo=bar podmanTest.BuildImage(dockerfile, "test", "true") session := podmanTest.PodmanNoCache([]string{"images"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) - Expect(len(session.OutputToStringArray())).To(Equal(4)) + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(5)) session2 := podmanTest.PodmanNoCache([]string{"images", "--all"}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) - Expect(len(session2.OutputToStringArray())).To(Equal(6)) + Expect(session2).Should(Exit(0)) + Expect(len(session2.OutputToStringArray())).To(Equal(7)) }) It("podman images filter by label", func() { @@ -335,15 +325,12 @@ LABEL "com.example.vendor"="Example Vendor" podmanTest.BuildImage(dockerfile, "test", "true") session := podmanTest.Podman([]string{"images", "-f", "label=version=1.0"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) }) It("podman with images with no layers", func() { - if podmanTest.RemoteTest { - Skip("Does not work on remote client") - } - + SkipIfRemote() dockerfile := strings.Join([]string{ `FROM scratch`, `LABEL org.opencontainers.image.authors="<somefolks@example.org>"`, @@ -357,52 +344,52 @@ LABEL "com.example.vendor"="Example Vendor" session := podmanTest.Podman([]string{"images", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(output).To(Not(MatchRegexp("<missing>"))) Expect(output).To(Not(MatchRegexp("error"))) session = podmanTest.Podman([]string{"image", "tree", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output = session.OutputToString() Expect(output).To(MatchRegexp("No Image Layers")) session = podmanTest.Podman([]string{"history", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output = session.OutputToString() Expect(output).To(Not(MatchRegexp("error"))) session = podmanTest.Podman([]string{"history", "--quiet", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(6)) session = podmanTest.Podman([]string{"image", "list", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output = session.OutputToString() Expect(output).To(Not(MatchRegexp("<missing>"))) Expect(output).To(Not(MatchRegexp("error"))) session = podmanTest.Podman([]string{"image", "list"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output = session.OutputToString() Expect(output).To(Not(MatchRegexp("<missing>"))) Expect(output).To(Not(MatchRegexp("error"))) session = podmanTest.Podman([]string{"inspect", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output = session.OutputToString() Expect(output).To(Not(MatchRegexp("<missing>"))) Expect(output).To(Not(MatchRegexp("error"))) session = podmanTest.Podman([]string{"inspect", "--format", "{{.RootFS.Layers}}", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output = session.OutputToString() Expect(output).To(Equal("[]")) }) @@ -414,11 +401,11 @@ LABEL "com.example.vendor"="Example Vendor" podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false") result := podmanTest.Podman([]string{"images", "-f", "readonly=true"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result1 := podmanTest.Podman([]string{"images", "--filter", "readonly=false"}) result1.WaitWithDefaultTimeout() - Expect(result1.ExitCode()).To(Equal(0)) + Expect(result1).Should(Exit(0)) Expect(result.OutputToStringArray()).To(Not(Equal(result1.OutputToStringArray()))) }) diff --git a/test/e2e/info_test.go b/test/e2e/info_test.go index 7cb299e0f..dbdaa05a7 100644 --- a/test/e2e/info_test.go +++ b/test/e2e/info_test.go @@ -33,7 +33,6 @@ var _ = Describe("Podman Info", func() { podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) - }) It("podman info json output", func() { diff --git a/test/e2e/init_test.go b/test/e2e/init_test.go index 919fe4abf..721017d0c 100644 --- a/test/e2e/init_test.go +++ b/test/e2e/init_test.go @@ -75,6 +75,7 @@ var _ = Describe("Podman init", func() { }) It("podman init latest container", func() { + SkipIfRemote() session := podmanTest.Podman([]string{"create", "-d", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -119,10 +120,10 @@ var _ = Describe("Podman init", func() { }) It("podman init running container errors", func() { - session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top"}) + session := podmanTest.Podman([]string{"run", "--name", "init_test", "-d", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - init := podmanTest.Podman([]string{"init", "--latest"}) + init := podmanTest.Podman([]string{"init", "init_test"}) init.WaitWithDefaultTimeout() Expect(init.ExitCode()).To(Equal(125)) }) diff --git a/test/e2e/inspect_test.go b/test/e2e/inspect_test.go index ebac087ac..77cfe4fd3 100644 --- a/test/e2e/inspect_test.go +++ b/test/e2e/inspect_test.go @@ -43,7 +43,6 @@ var _ = Describe("Podman inspect", func() { }) It("podman inspect bogus container", func() { - SkipIfRemote() session := podmanTest.Podman([]string{"inspect", "foobar4321"}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) @@ -67,7 +66,6 @@ var _ = Describe("Podman inspect", func() { }) It("podman inspect container with GO format for ConmonPidFile", func() { - SkipIfRemote() session, ec, _ := podmanTest.RunLsContainer("test1") Expect(ec).To(Equal(0)) @@ -77,11 +75,10 @@ var _ = Describe("Podman inspect", func() { }) It("podman inspect container with size", func() { - SkipIfRemote() - _, ec, _ := podmanTest.RunLsContainer("") + _, ec, _ := podmanTest.RunLsContainer("sizetest") Expect(ec).To(Equal(0)) - result := podmanTest.Podman([]string{"inspect", "--size", "-l"}) + result := podmanTest.Podman([]string{"inspect", "--size", "sizetest"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(0)) conData := result.InspectContainerToJSON() @@ -90,7 +87,6 @@ var _ = Describe("Podman inspect", func() { }) It("podman inspect container and image", func() { - SkipIfRemote() ls, ec, _ := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) cid := ls.OutputToString() @@ -102,7 +98,6 @@ var _ = Describe("Podman inspect", func() { }) It("podman inspect container and filter for Image{ID}", func() { - SkipIfRemote() ls, ec, _ := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) cid := ls.OutputToString() @@ -119,7 +114,6 @@ var _ = Describe("Podman inspect", func() { }) It("podman inspect container and filter for CreateCommand", func() { - SkipIfRemote() ls, ec, _ := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) cid := ls.OutputToString() diff --git a/test/e2e/kill_test.go b/test/e2e/kill_test.go index 834f86b77..3f192fb55 100644 --- a/test/e2e/kill_test.go +++ b/test/e2e/kill_test.go @@ -100,6 +100,7 @@ var _ = Describe("Podman kill", func() { }) It("podman kill latest container", func() { + SkipIfRemote() session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/libpod_suite_remote_test.go b/test/e2e/libpod_suite_remote_test.go new file mode 100644 index 000000000..dde853413 --- /dev/null +++ b/test/e2e/libpod_suite_remote_test.go @@ -0,0 +1,221 @@ +// +build remoteclient + +package integration + +import ( + "bytes" + "errors" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "syscall" + "time" + + "github.com/containers/libpod/pkg/rootless" + "github.com/onsi/ginkgo" +) + +func SkipIfRemote() { + ginkgo.Skip("This function is not enabled for remote podman") +} + +func SkipIfRootless() { + if os.Geteuid() != 0 { + ginkgo.Skip("This function is not enabled for rootless podman") + } +} +func SkipIfRootlessV2() { + if os.Geteuid() != 0 { + ginkgo.Skip("This function is not enabled for v2 rootless podman") + } +} + +// Podman is the exec call to podman on the filesystem +func (p *PodmanTestIntegration) Podman(args []string) *PodmanSessionIntegration { + var remoteArgs = []string{"--remote", p.RemoteSocket} + remoteArgs = append(remoteArgs, args...) + podmanSession := p.PodmanBase(remoteArgs, false, false) + return &PodmanSessionIntegration{podmanSession} +} + +// PodmanExtraFiles is the exec call to podman on the filesystem and passes down extra files +func (p *PodmanTestIntegration) PodmanExtraFiles(args []string, extraFiles []*os.File) *PodmanSessionIntegration { + var remoteArgs = []string{"--remote", p.RemoteSocket} + remoteArgs = append(remoteArgs, args...) + podmanSession := p.PodmanAsUserBase(remoteArgs, 0, 0, "", nil, false, false, extraFiles) + return &PodmanSessionIntegration{podmanSession} +} + +// PodmanNoCache calls podman with out adding the imagecache +func (p *PodmanTestIntegration) PodmanNoCache(args []string) *PodmanSessionIntegration { + var remoteArgs = []string{"--remote", p.RemoteSocket} + remoteArgs = append(remoteArgs, args...) + podmanSession := p.PodmanBase(remoteArgs, false, true) + return &PodmanSessionIntegration{podmanSession} +} + +// PodmanNoEvents calls the Podman command without an imagecache and without an +// events backend. It is used mostly for caching and uncaching images. +func (p *PodmanTestIntegration) PodmanNoEvents(args []string) *PodmanSessionIntegration { + podmanSession := p.PodmanBase(args, true, true) + return &PodmanSessionIntegration{podmanSession} +} + +func (p *PodmanTestIntegration) setDefaultRegistriesConfigEnv() { + defaultFile := filepath.Join(INTEGRATION_ROOT, "test/registries.conf") + os.Setenv("REGISTRIES_CONFIG_PATH", defaultFile) +} + +func (p *PodmanTestIntegration) setRegistriesConfigEnv(b []byte) { + outfile := filepath.Join(p.TempDir, "registries.conf") + os.Setenv("REGISTRIES_CONFIG_PATH", outfile) + ioutil.WriteFile(outfile, b, 0644) +} + +func resetRegistriesConfigEnv() { + os.Setenv("REGISTRIES_CONFIG_PATH", "") +} +func PodmanTestCreate(tempDir string) *PodmanTestIntegration { + pti := PodmanTestCreateUtil(tempDir, true) + pti.StartRemoteService() + return pti +} + +func (p *PodmanTestIntegration) StartRemoteService() { + if os.Geteuid() == 0 { + os.MkdirAll("/run/podman", 0755) + } + + args := []string{} + if _, found := os.LookupEnv("DEBUG_SERVICE"); found { + args = append(args, "--log-level", "debug") + } + remoteSocket := p.RemoteSocket + args = append(args, "system", "service", "--time", "0", remoteSocket) + podmanOptions := getRemoteOptions(p, args) + command := exec.Command(p.PodmanBinary, podmanOptions...) + command.Stdout = os.Stdout + command.Stderr = os.Stderr + fmt.Printf("Running: %s %s\n", p.PodmanBinary, strings.Join(podmanOptions, " ")) + command.Start() + command.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} + p.RemoteCommand = command + p.RemoteSession = command.Process + err := p.DelayForService() + p.RemoteStartErr = err +} + +func (p *PodmanTestIntegration) StopRemoteService() { + var out bytes.Buffer + var pids []int + remoteSession := p.RemoteSession + + if !rootless.IsRootless() { + if err := remoteSession.Kill(); err != nil { + fmt.Fprintf(os.Stderr, "error on remote stop-kill %q", err) + } + if _, err := remoteSession.Wait(); err != nil { + fmt.Fprintf(os.Stderr, "error on remote stop-wait %q", err) + } + + } else { + //p.ResetVarlinkAddress() + parentPid := fmt.Sprintf("%d", p.RemoteSession.Pid) + pgrep := exec.Command("pgrep", "-P", parentPid) + fmt.Printf("running: pgrep %s\n", parentPid) + pgrep.Stdout = &out + err := pgrep.Run() + if err != nil { + fmt.Fprint(os.Stderr, "unable to find remote pid") + } + + for _, s := range strings.Split(out.String(), "\n") { + if len(s) == 0 { + continue + } + p, err := strconv.Atoi(s) + if err != nil { + fmt.Fprintf(os.Stderr, "unable to convert %s to int", s) + } + if p != 0 { + pids = append(pids, p) + } + } + + pids = append(pids, p.RemoteSession.Pid) + for _, pid := range pids { + syscall.Kill(pid, syscall.SIGKILL) + } + } + socket := strings.Split(p.RemoteSocket, ":")[1] + if err := os.Remove(socket); err != nil { + fmt.Println(err) + } +} + +//MakeOptions assembles all the podman main options +func (p *PodmanTestIntegration) makeOptions(args []string, noEvents, noCache bool) []string { + return args +} + +//MakeOptions assembles all the podman main options +func getRemoteOptions(p *PodmanTestIntegration, args []string) []string { + podmanOptions := strings.Split(fmt.Sprintf("--root %s --runroot %s --runtime %s --conmon %s --cni-config-dir %s --cgroup-manager %s", + p.CrioRoot, p.RunRoot, p.OCIRuntime, p.ConmonBinary, p.CNIConfigDir, p.CgroupManager), " ") + if os.Getenv("HOOK_OPTION") != "" { + podmanOptions = append(podmanOptions, os.Getenv("HOOK_OPTION")) + } + podmanOptions = append(podmanOptions, strings.Split(p.StorageOptions, " ")...) + podmanOptions = append(podmanOptions, args...) + return podmanOptions +} + +func (p *PodmanTestIntegration) RestoreArtifactToCache(image string) error { + fmt.Printf("Restoring %s...\n", image) + dest := strings.Split(image, "/") + destName := fmt.Sprintf("/tmp/%s.tar", strings.Replace(strings.Join(strings.Split(dest[len(dest)-1], "/"), ""), ":", "-", -1)) + p.CrioRoot = p.ImageCacheDir + restore := p.PodmanNoEvents([]string{"load", "-q", "-i", destName}) + restore.WaitWithDefaultTimeout() + return nil +} + +// SeedImages restores all the artifacts into the main store for remote tests +func (p *PodmanTestIntegration) SeedImages() error { + return p.RestoreAllArtifacts() +} + +// RestoreArtifact puts the cached image into our test store +func (p *PodmanTestIntegration) RestoreArtifact(image string) error { + fmt.Printf("Restoring %s...\n", image) + dest := strings.Split(image, "/") + destName := fmt.Sprintf("/tmp/%s.tar", strings.Replace(strings.Join(strings.Split(dest[len(dest)-1], "/"), ""), ":", "-", -1)) + args := []string{"load", "-q", "-i", destName} + podmanOptions := getRemoteOptions(p, args) + command := exec.Command(p.PodmanBinary, podmanOptions...) + fmt.Printf("Running: %s %s\n", p.PodmanBinary, strings.Join(podmanOptions, " ")) + command.Start() + command.Wait() + return nil +} + +func (p *PodmanTestIntegration) DelayForService() error { + for i := 0; i < 5; i++ { + session := p.Podman([]string{"info"}) + session.WaitWithDefaultTimeout() + if session.ExitCode() == 0 { + return nil + } else if i == 4 { + break + } + time.Sleep(2 * time.Second) + } + return errors.New("Service not detected") +} + +func populateCache(podman *PodmanTestIntegration) {} +func removeCache() {} diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go index 29a55980c..009f70914 100644 --- a/test/e2e/libpod_suite_test.go +++ b/test/e2e/libpod_suite_test.go @@ -21,6 +21,12 @@ func SkipIfRootless() { } } +func SkipIfRootlessV2() { + if os.Geteuid() != 0 { + ginkgo.Skip("This function is not enabled for v2 rootless podman") + } +} + // Podman is the exec call to podman on the filesystem func (p *PodmanTestIntegration) Podman(args []string) *PodmanSessionIntegration { podmanSession := p.PodmanBase(args, false, false) @@ -121,8 +127,8 @@ func (p *PodmanTestIntegration) RestoreArtifactToCache(image string) error { return nil } -func (p *PodmanTestIntegration) StopVarlink() {} -func (p *PodmanTestIntegration) DelayForVarlink() {} +func (p *PodmanTestIntegration) StopRemoteService() {} +func (p *PodmanTestIntegration) DelayForVarlink() {} func populateCache(podman *PodmanTestIntegration) { for _, image := range CACHE_IMAGES { @@ -145,5 +151,5 @@ func (p *PodmanTestIntegration) SeedImages() error { } // We don't support running Varlink when local -func (p *PodmanTestIntegration) StartVarlink() { +func (p *PodmanTestIntegration) StartRemoteService() { } diff --git a/test/e2e/libpod_suite_remoteclient_test.go b/test/e2e/libpod_suite_varlink_test.go index b5da041ab..92c815b39 100644 --- a/test/e2e/libpod_suite_remoteclient_test.go +++ b/test/e2e/libpod_suite_varlink_test.go @@ -1,11 +1,10 @@ -// +build remoteclient +// +build remoteclientvarlink package integration import ( "bytes" "fmt" - "github.com/containers/libpod/pkg/rootless" "io/ioutil" "os" "os/exec" @@ -15,6 +14,8 @@ import ( "syscall" "time" + "github.com/containers/libpod/pkg/rootless" + "github.com/onsi/ginkgo" ) @@ -69,40 +70,40 @@ func resetRegistriesConfigEnv() { } func PodmanTestCreate(tempDir string) *PodmanTestIntegration { pti := PodmanTestCreateUtil(tempDir, true) - pti.StartVarlink() + pti.StartRemoteService() return pti } func (p *PodmanTestIntegration) ResetVarlinkAddress() { - os.Unsetenv("PODMAN_VARLINK_ADDRESS") + //os.Unsetenv("PODMAN_VARLINK_ADDRESS") } func (p *PodmanTestIntegration) SetVarlinkAddress(addr string) { - os.Setenv("PODMAN_VARLINK_ADDRESS", addr) + //os.Setenv("PODMAN_VARLINK_ADDRESS", addr) } func (p *PodmanTestIntegration) StartVarlink() { if os.Geteuid() == 0 { os.MkdirAll("/run/podman", 0755) } - varlinkEndpoint := p.VarlinkEndpoint - p.SetVarlinkAddress(p.VarlinkEndpoint) + varlinkEndpoint := p.RemoteSocket + p.SetVarlinkAddress(p.RemoteSocket) - args := []string{"varlink", "--timeout", "0", varlinkEndpoint} + args := []string{"varlink", "--time", "0", varlinkEndpoint} podmanOptions := getVarlinkOptions(p, args) command := exec.Command(p.PodmanBinary, podmanOptions...) fmt.Printf("Running: %s %s\n", p.PodmanBinary, strings.Join(podmanOptions, " ")) command.Start() command.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} - p.VarlinkCommand = command - p.VarlinkSession = command.Process - p.DelayForVarlink() + p.RemoteCommand = command + p.RemoteSession = command.Process + p.DelayForService() } func (p *PodmanTestIntegration) StopVarlink() { var out bytes.Buffer var pids []int - varlinkSession := p.VarlinkSession + varlinkSession := p.RemoteSession if !rootless.IsRootless() { if err := varlinkSession.Kill(); err != nil { @@ -114,7 +115,7 @@ func (p *PodmanTestIntegration) StopVarlink() { } else { p.ResetVarlinkAddress() - parentPid := fmt.Sprintf("%d", p.VarlinkSession.Pid) + parentPid := fmt.Sprintf("%d", p.RemoteSession.Pid) pgrep := exec.Command("pgrep", "-P", parentPid) fmt.Printf("running: pgrep %s\n", parentPid) pgrep.Stdout = &out @@ -136,12 +137,12 @@ func (p *PodmanTestIntegration) StopVarlink() { } } - pids = append(pids, p.VarlinkSession.Pid) + pids = append(pids, p.RemoteSession.Pid) for _, pid := range pids { syscall.Kill(pid, syscall.SIGKILL) } } - socket := strings.Split(p.VarlinkEndpoint, ":")[1] + socket := strings.Split(p.RemoteSocket, ":")[1] if err := os.Remove(socket); err != nil { fmt.Println(err) } diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go index dd35d8489..3f76daa67 100644 --- a/test/e2e/login_logout_test.go +++ b/test/e2e/login_logout_test.go @@ -32,7 +32,6 @@ var _ = Describe("Podman login and logout", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go index 0438a31cb..f36163ccc 100644 --- a/test/e2e/logs_test.go +++ b/test/e2e/logs_test.go @@ -9,6 +9,7 @@ import ( . "github.com/containers/libpod/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman logs", func() { @@ -35,97 +36,99 @@ var _ = Describe("Podman logs", func() { }) - It("podman logs for container", func() { + It("all lines", func() { logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) - cid := logc.OutputToString() + Expect(logc).To(Exit(0)) + cid := logc.OutputToString() results := podmanTest.Podman([]string{"logs", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(3)) }) - It("podman logs tail two lines", func() { + It("tail two lines", func() { logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() results := podmanTest.Podman([]string{"logs", "--tail", "2", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(2)) }) - It("podman logs tail zero lines", func() { + It("tail zero lines", func() { logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() results := podmanTest.Podman([]string{"logs", "--tail", "0", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(0)) }) - It("podman logs tail 99 lines", func() { + It("tail 99 lines", func() { logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() results := podmanTest.Podman([]string{"logs", "--tail", "99", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(3)) }) - It("podman logs tail 2 lines with timestamps", func() { + It("tail 2 lines with timestamps", func() { logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() results := podmanTest.Podman([]string{"logs", "--tail", "2", "-t", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(2)) }) - It("podman logs latest with since time", func() { + It("since time 2017-08-07", func() { logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() results := podmanTest.Podman([]string{"logs", "--since", "2017-08-07T10:10:09.056611202-04:00", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(3)) }) - It("podman logs latest with since duration", func() { + It("since duration 10m", func() { logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() results := podmanTest.Podman([]string{"logs", "--since", "10m", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(3)) }) - It("podman logs latest and container name should fail", func() { + It("latest and container name should fail", func() { + SkipIfRemote() // -l not supported results := podmanTest.Podman([]string{"logs", "-l", "foobar"}) results.WaitWithDefaultTimeout() Expect(results).To(ExitWithError()) }) - It("podman logs two containers and should display short container IDs", func() { + It("two containers showing short container IDs", func() { + SkipIfRemote() // remote does not support multiple containers log1 := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) log1.WaitWithDefaultTimeout() Expect(log1.ExitCode()).To(Equal(0)) @@ -138,7 +141,7 @@ var _ = Describe("Podman logs", func() { results := podmanTest.Podman([]string{"logs", cid1, cid2}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) output := results.OutputToStringArray() Expect(len(output)).To(Equal(6)) @@ -148,23 +151,24 @@ var _ = Describe("Podman logs", func() { It("podman logs on a created container should result in 0 exit code", func() { session := podmanTest.Podman([]string{"create", "-dt", "--name", "log", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).To(Exit(0)) results := podmanTest.Podman([]string{"logs", "log"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(BeZero()) + Expect(results).To(Exit(0)) }) - It("podman journald logs for container with container tag", func() { + It("using journald for container with container tag", func() { + SkipIfRemote() Skip("need to verify images have correct packages for journald") logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "--log-opt=tag={{.ImageName}}", "-d", ALPINE, "sh", "-c", "echo podman; sleep 0.1; echo podman; sleep 0.1; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() wait := podmanTest.Podman([]string{"wait", "-l"}) wait.WaitWithDefaultTimeout() - Expect(wait.ExitCode()).To(BeZero()) + Expect(wait).To(Exit(0)) cmd := exec.Command("journalctl", "--no-pager", "-o", "json", "--output-fields=CONTAINER_TAG", "-u", fmt.Sprintf("libpod-conmon-%s.scope", cid)) out, err := cmd.CombinedOutput() @@ -172,98 +176,116 @@ var _ = Describe("Podman logs", func() { Expect(string(out)).To(ContainSubstring("alpine")) }) - It("podman journald logs for container", func() { + It("using journald for container name", func() { + Skip("need to verify images have correct packages for journald") + SkipIfRemote() + containerName := "inside-journal" + logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-d", "--name", containerName, ALPINE, "sh", "-c", "echo podman; sleep 0.1; echo podman; sleep 0.1; echo podman"}) + logc.WaitWithDefaultTimeout() + Expect(logc).To(Exit(0)) + cid := logc.OutputToString() + + wait := podmanTest.Podman([]string{"wait", "-l"}) + wait.WaitWithDefaultTimeout() + Expect(wait).To(Exit(0)) + + cmd := exec.Command("journalctl", "--no-pager", "-o", "json", "--output-fields=CONTAINER_NAME", "-u", fmt.Sprintf("libpod-conmon-%s.scope", cid)) + out, err := cmd.CombinedOutput() + Expect(err).To(BeNil()) + Expect(string(out)).To(ContainSubstring(containerName)) + }) + + It("using journald for container", func() { Skip("need to verify images have correct packages for journald") logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() results := podmanTest.Podman([]string{"logs", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(3)) }) - It("podman journald logs tail two lines", func() { + It("using journald tail two lines", func() { Skip("need to verify images have correct packages for journald") logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() - results := podmanTest.Podman([]string{"logs", "--tail", "2", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(2)) }) - It("podman journald logs tail 99 lines", func() { + It("using journald tail 99 lines", func() { Skip("need to verify images have correct packages for journald") logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() results := podmanTest.Podman([]string{"logs", "--tail", "99", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(3)) }) - It("podman journald logs tail 2 lines with timestamps", func() { + It("using journald tail 2 lines with timestamps", func() { Skip("need to verify images have correct packages for journald") logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() results := podmanTest.Podman([]string{"logs", "--tail", "2", "-t", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(2)) }) - It("podman journald logs latest with since time", func() { + It("using journald since time 2017-08-07", func() { Skip("need to verify images have correct packages for journald") logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() results := podmanTest.Podman([]string{"logs", "--since", "2017-08-07T10:10:09.056611202-04:00", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(3)) }) - It("podman journald logs latest with since duration", func() { + It("using journald with duration 10m", func() { Skip("need to verify images have correct packages for journald") logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) cid := logc.OutputToString() results := podmanTest.Podman([]string{"logs", "--since", "10m", cid}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) Expect(len(results.OutputToStringArray())).To(Equal(3)) }) - It("podman logs -f two lines", func() { + It("streaming output", func() { containerName := "logs-f-rm" logc := podmanTest.Podman([]string{"run", "--rm", "--name", containerName, "-dt", ALPINE, "sh", "-c", "echo podman; sleep 1; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) results := podmanTest.Podman([]string{"logs", "-f", containerName}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).To(Exit(0)) // Verify that the cleanup process worked correctly and we can recreate a container with the same name logc = podmanTest.Podman([]string{"run", "--rm", "--name", containerName, "-dt", ALPINE, "true"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).To(Exit(0)) }) }) diff --git a/test/e2e/manifest_test.go b/test/e2e/manifest_test.go index 9b5a24771..1137ebe8e 100644 --- a/test/e2e/manifest_test.go +++ b/test/e2e/manifest_test.go @@ -2,6 +2,8 @@ package integration import ( "os" + "path/filepath" + "strings" . "github.com/containers/libpod/test/utils" . "github.com/onsi/ginkgo" @@ -98,4 +100,109 @@ var _ = Describe("Podman manifest", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring(`"os": "bar"`)) }) + + It("podman manifest annotate", func() { + SkipIfRemote() + session := podmanTest.Podman([]string{"manifest", "create", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"manifest", "add", "foo", imageListInstance}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"manifest", "annotate", "--arch", "bar", "foo", imageListARM64InstanceDigest}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(`"architecture": "bar"`)) + }) + + It("podman manifest remove", func() { + session := podmanTest.Podman([]string{"manifest", "create", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"manifest", "add", "--all", "foo", imageList}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(imageListARM64InstanceDigest)) + session = podmanTest.Podman([]string{"manifest", "remove", "foo", imageListARM64InstanceDigest}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(imageListAMD64InstanceDigest)) + Expect(session.OutputToString()).To(ContainSubstring(imageListARMInstanceDigest)) + Expect(session.OutputToString()).To(ContainSubstring(imageListPPC64LEInstanceDigest)) + Expect(session.OutputToString()).To(ContainSubstring(imageListS390XInstanceDigest)) + Expect(session.OutputToString()).To(Not(ContainSubstring(imageListARM64InstanceDigest))) + }) + + It("podman manifest remove not-found", func() { + session := podmanTest.Podman([]string{"manifest", "create", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"manifest", "add", "foo", imageList}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"manifest", "remove", "foo", "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Not(Equal(0))) + }) + + It("podman manifest push", func() { + session := podmanTest.Podman([]string{"manifest", "create", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"manifest", "add", "--all", "foo", imageList}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + dest := filepath.Join(podmanTest.TempDir, "pushed") + err := os.MkdirAll(dest, os.ModePerm) + Expect(err).To(BeNil()) + defer func() { + os.RemoveAll(dest) + }() + session = podmanTest.Podman([]string{"manifest", "push", "--all", "foo", "dir:" + dest}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + files, err := filepath.Glob(dest + string(os.PathSeparator) + "*") + Expect(err).To(BeNil()) + check := SystemExec("sha256sum", files) + check.WaitWithDefaultTimeout() + Expect(check.ExitCode()).To(Equal(0)) + prefix := "sha256:" + Expect(check.OutputToString()).To(ContainSubstring(strings.TrimPrefix(imageListAMD64InstanceDigest, prefix))) + Expect(check.OutputToString()).To(ContainSubstring(strings.TrimPrefix(imageListARMInstanceDigest, prefix))) + Expect(check.OutputToString()).To(ContainSubstring(strings.TrimPrefix(imageListPPC64LEInstanceDigest, prefix))) + Expect(check.OutputToString()).To(ContainSubstring(strings.TrimPrefix(imageListS390XInstanceDigest, prefix))) + Expect(check.OutputToString()).To(ContainSubstring(strings.TrimPrefix(imageListARM64InstanceDigest, prefix))) + }) + + It("podman manifest push purge", func() { + // remote does not support --purge + SkipIfRemote() + session := podmanTest.Podman([]string{"manifest", "create", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"manifest", "add", "foo", imageList}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + dest := filepath.Join(podmanTest.TempDir, "pushed") + err := os.MkdirAll(dest, os.ModePerm) + Expect(err).To(BeNil()) + defer func() { + os.RemoveAll(dest) + }() + session = podmanTest.Podman([]string{"manifest", "push", "--purge", "foo", "dir:" + dest}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Not(Equal(0))) + }) }) diff --git a/test/e2e/network_create_test.go b/test/e2e/network_create_test.go index 19dabced7..7eccaa9ab 100644 --- a/test/e2e/network_create_test.go +++ b/test/e2e/network_create_test.go @@ -76,7 +76,6 @@ var _ = Describe("Podman network create", func() { ) BeforeEach(func() { - Skip(v2fail) SkipIfRootless() tempdir, err = CreateTempDirInTempDir() if err != nil { diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go index 2cb7eb144..e293876b9 100644 --- a/test/e2e/network_test.go +++ b/test/e2e/network_test.go @@ -34,7 +34,7 @@ var _ = Describe("Podman network", func() { ) BeforeEach(func() { - Skip(v2fail) + SkipIfRootless() tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) @@ -80,7 +80,6 @@ var _ = Describe("Podman network", func() { ) It("podman network list", func() { - SkipIfRootless() // Setup, use uuid to prevent conflict with other tests uuid := stringid.GenerateNonCryptoID() secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid)) @@ -94,7 +93,6 @@ var _ = Describe("Podman network", func() { }) It("podman network list -q", func() { - SkipIfRootless() // Setup, use uuid to prevent conflict with other tests uuid := stringid.GenerateNonCryptoID() secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid)) @@ -107,15 +105,39 @@ var _ = Describe("Podman network", func() { Expect(session.LineInOutputContains("podman-integrationtest")).To(BeTrue()) }) + It("podman network list --filter success", func() { + // Setup, use uuid to prevent conflict with other tests + uuid := stringid.GenerateNonCryptoID() + secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid)) + writeConf([]byte(secondConf), secondPath) + defer removeConf(secondPath) + + session := podmanTest.Podman([]string{"network", "ls", "--filter", "plugin=bridge"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.LineInOutputContains("podman-integrationtest")).To(BeTrue()) + }) + + It("podman network list --filter failure", func() { + // Setup, use uuid to prevent conflict with other tests + uuid := stringid.GenerateNonCryptoID() + secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid)) + writeConf([]byte(secondConf), secondPath) + defer removeConf(secondPath) + + session := podmanTest.Podman([]string{"network", "ls", "--filter", "plugin=test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.LineInOutputContains("podman-integrationtest")).To(BeFalse()) + }) + It("podman network rm no args", func() { - SkipIfRootless() session := podmanTest.Podman([]string{"network", "rm"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).ToNot(BeZero()) }) It("podman network rm", func() { - SkipIfRootless() // Setup, use uuid to prevent conflict with other tests uuid := stringid.GenerateNonCryptoID() secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid)) @@ -138,14 +160,12 @@ var _ = Describe("Podman network", func() { }) It("podman network inspect no args", func() { - SkipIfRootless() session := podmanTest.Podman([]string{"network", "inspect"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).ToNot(BeZero()) }) It("podman network inspect", func() { - SkipIfRootless() // Setup, use uuid to prevent conflict with other tests uuid := stringid.GenerateNonCryptoID() secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid)) @@ -158,8 +178,20 @@ var _ = Describe("Podman network", func() { Expect(session.IsJSONOutputValid()).To(BeTrue()) }) + It("podman network inspect", func() { + // Setup, use uuid to prevent conflict with other tests + uuid := stringid.GenerateNonCryptoID() + secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid)) + writeConf([]byte(secondConf), secondPath) + defer removeConf(secondPath) + + session := podmanTest.Podman([]string{"network", "inspect", "podman-integrationtest", "--format", "{{.cniVersion}}"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.LineInOutputContains("0.3.0")).To(BeTrue()) + }) + It("podman inspect container single CNI network", func() { - SkipIfRootless() netName := "testNetSingleCNI" network := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.50.0/24", netName}) network.WaitWithDefaultTimeout() @@ -190,7 +222,6 @@ var _ = Describe("Podman network", func() { }) It("podman inspect container two CNI networks", func() { - SkipIfRootless() netName1 := "testNetTwoCNI1" network1 := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.51.0/25", netName1}) network1.WaitWithDefaultTimeout() diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 16f7af55e..9daf266b8 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -217,7 +217,6 @@ var _ = Describe("Podman generate kube", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go index e0a10c202..e56db54a2 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -2,7 +2,9 @@ package integration import ( "fmt" + "io/ioutil" "os" + "path/filepath" "strings" . "github.com/containers/libpod/test/utils" @@ -28,7 +30,7 @@ var _ = Describe("Podman pod create", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) @@ -282,4 +284,26 @@ var _ = Describe("Podman pod create", func() { podCreate.WaitWithDefaultTimeout() Expect(podCreate.ExitCode()).To(Equal(125)) }) + + It("podman create pod and print id to external file", func() { + // Switch to temp dir and restore it afterwards + cwd, err := os.Getwd() + Expect(err).To(BeNil()) + Expect(os.Chdir(os.TempDir())).To(BeNil()) + targetPath := filepath.Join(os.TempDir(), "dir") + Expect(os.MkdirAll(targetPath, 0755)).To(BeNil()) + targetFile := filepath.Join(targetPath, "idFile") + defer Expect(os.RemoveAll(targetFile)).To(BeNil()) + defer Expect(os.Chdir(cwd)).To(BeNil()) + + session := podmanTest.Podman([]string{"pod", "create", "--name=abc", "--pod-id-file", targetFile}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + id, _ := ioutil.ReadFile(targetFile) + check := podmanTest.Podman([]string{"pod", "inspect", "abc"}) + check.WaitWithDefaultTimeout() + data := check.InspectPodToJSON() + Expect(data.ID).To(Equal(string(id))) + }) }) diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go index 3cc6fa9e8..9b6f9b657 100644 --- a/test/e2e/pod_infra_container_test.go +++ b/test/e2e/pod_infra_container_test.go @@ -29,7 +29,7 @@ var _ = Describe("Podman pod create", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) diff --git a/test/e2e/pod_inspect_test.go b/test/e2e/pod_inspect_test.go index f87bbe047..8040adf1e 100644 --- a/test/e2e/pod_inspect_test.go +++ b/test/e2e/pod_inspect_test.go @@ -26,7 +26,7 @@ var _ = Describe("Podman pod inspect", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) diff --git a/test/e2e/pod_kill_test.go b/test/e2e/pod_kill_test.go index a3efec46c..af3d2af73 100644 --- a/test/e2e/pod_kill_test.go +++ b/test/e2e/pod_kill_test.go @@ -27,7 +27,7 @@ var _ = Describe("Podman pod kill", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) @@ -100,6 +100,7 @@ var _ = Describe("Podman pod kill", func() { }) It("podman pod kill latest pod", func() { + SkipIfRemote() _, ec, podid := podmanTest.CreatePod("") Expect(ec).To(Equal(0)) diff --git a/test/e2e/pod_pause_test.go b/test/e2e/pod_pause_test.go index 7067c9a87..df6e5482e 100644 --- a/test/e2e/pod_pause_test.go +++ b/test/e2e/pod_pause_test.go @@ -29,7 +29,7 @@ var _ = Describe("Podman pod pause", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) diff --git a/test/e2e/pod_pod_namespaces.go b/test/e2e/pod_pod_namespaces.go index 09f716806..806ec3884 100644 --- a/test/e2e/pod_pod_namespaces.go +++ b/test/e2e/pod_pod_namespaces.go @@ -29,7 +29,7 @@ var _ = Describe("Podman pod create", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) diff --git a/test/e2e/pod_prune_test.go b/test/e2e/pod_prune_test.go index d98383331..1711b55d4 100644 --- a/test/e2e/pod_prune_test.go +++ b/test/e2e/pod_prune_test.go @@ -26,7 +26,7 @@ var _ = Describe("Podman pod prune", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) diff --git a/test/e2e/pod_ps_test.go b/test/e2e/pod_ps_test.go index 5f8712a7a..81d97b72d 100644 --- a/test/e2e/pod_ps_test.go +++ b/test/e2e/pod_ps_test.go @@ -28,7 +28,7 @@ var _ = Describe("Podman ps", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) @@ -83,6 +83,7 @@ var _ = Describe("Podman ps", func() { }) It("podman pod ps latest", func() { + SkipIfRemote() _, ec, podid1 := podmanTest.CreatePod("") Expect(ec).To(Equal(0)) diff --git a/test/e2e/pod_restart_test.go b/test/e2e/pod_restart_test.go index 691fe5f0c..72e804353 100644 --- a/test/e2e/pod_restart_test.go +++ b/test/e2e/pod_restart_test.go @@ -26,7 +26,7 @@ var _ = Describe("Podman pod restart", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) @@ -134,6 +134,7 @@ var _ = Describe("Podman pod restart", func() { }) It("podman pod restart latest pod", func() { + SkipIfRemote() _, ec, _ := podmanTest.CreatePod("foobar99") Expect(ec).To(Equal(0)) diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go index 90f178be6..e10b3c98f 100644 --- a/test/e2e/pod_rm_test.go +++ b/test/e2e/pod_rm_test.go @@ -29,7 +29,7 @@ var _ = Describe("Podman pod rm", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) @@ -60,6 +60,7 @@ var _ = Describe("Podman pod rm", func() { }) It("podman pod rm latest pod", func() { + SkipIfRemote() _, ec, podid := podmanTest.CreatePod("") Expect(ec).To(Equal(0)) diff --git a/test/e2e/pod_start_test.go b/test/e2e/pod_start_test.go index 2722cb5b3..8e78cadfd 100644 --- a/test/e2e/pod_start_test.go +++ b/test/e2e/pod_start_test.go @@ -26,7 +26,7 @@ var _ = Describe("Podman pod start", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) @@ -103,6 +103,7 @@ var _ = Describe("Podman pod start", func() { }) It("podman pod start latest pod", func() { + SkipIfRemote() _, ec, _ := podmanTest.CreatePod("foobar99") Expect(ec).To(Equal(0)) diff --git a/test/e2e/pod_stats_test.go b/test/e2e/pod_stats_test.go index 347f33e62..9bba59073 100644 --- a/test/e2e/pod_stats_test.go +++ b/test/e2e/pod_stats_test.go @@ -35,7 +35,7 @@ var _ = Describe("Podman pod stats", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) diff --git a/test/e2e/pod_stop_test.go b/test/e2e/pod_stop_test.go index a61917adb..298f3da2f 100644 --- a/test/e2e/pod_stop_test.go +++ b/test/e2e/pod_stop_test.go @@ -26,7 +26,7 @@ var _ = Describe("Podman pod stop", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) @@ -144,6 +144,7 @@ var _ = Describe("Podman pod stop", func() { }) It("podman pod stop latest pod", func() { + SkipIfRemote() _, ec, _ := podmanTest.CreatePod("foobar99") Expect(ec).To(Equal(0)) diff --git a/test/e2e/pod_top_test.go b/test/e2e/pod_top_test.go index c313b0675..de011eda7 100644 --- a/test/e2e/pod_top_test.go +++ b/test/e2e/pod_top_test.go @@ -30,7 +30,7 @@ var _ = Describe("Podman top", func() { }) AfterEach(func() { - podmanTest.CleanupPod() + podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) diff --git a/test/e2e/port_test.go b/test/e2e/port_test.go index ce31c9ad2..5bb86d558 100644 --- a/test/e2e/port_test.go +++ b/test/e2e/port_test.go @@ -20,7 +20,6 @@ var _ = Describe("Podman port", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go index e8a208c3c..e77e6dd25 100644 --- a/test/e2e/prune_test.go +++ b/test/e2e/prune_test.go @@ -22,7 +22,6 @@ var _ = Describe("Podman prune", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) @@ -169,12 +168,13 @@ var _ = Describe("Podman prune", func() { session = podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + podid1 := session.OutputToString() - session = podmanTest.Podman([]string{"pod", "start", "-l"}) + session = podmanTest.Podman([]string{"pod", "start", podid1}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"pod", "stop", "-l"}) + session = podmanTest.Podman([]string{"pod", "stop", podid1}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -192,4 +192,161 @@ var _ = Describe("Podman prune", func() { Expect(pods.ExitCode()).To(Equal(0)) Expect(len(pods.OutputToStringArray())).To(Equal(2)) }) + + It("podman system prune - pod,container stopped", func() { + session := podmanTest.Podman([]string{"pod", "create"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + podid1 := session.OutputToString() + + // Start and stop a pod to get it in exited state. + session = podmanTest.Podman([]string{"pod", "start", podid1}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"pod", "stop", podid1}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Create a container. This container should be pruned. + create := podmanTest.Podman([]string{"create", "--name", "test", BB}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(Equal(0)) + + prune := podmanTest.Podman([]string{"system", "prune", "-f"}) + prune.WaitWithDefaultTimeout() + Expect(prune.ExitCode()).To(Equal(0)) + + pods := podmanTest.Podman([]string{"pod", "ps"}) + pods.WaitWithDefaultTimeout() + Expect(pods.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfPods()).To(Equal(0)) + + Expect(podmanTest.NumberOfContainers()).To(Equal(0)) + }) + + It("podman system prune with running, exited pod and volume prune set true", func() { + // Start and stop a pod to get it in exited state. + session := podmanTest.Podman([]string{"pod", "create"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + podid1 := session.OutputToString() + + session = podmanTest.Podman([]string{"pod", "start", podid1}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"pod", "stop", podid1}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Start a pod and leave it running + session = podmanTest.Podman([]string{"pod", "create"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + podid2 := session.OutputToString() + + session = podmanTest.Podman([]string{"pod", "start", podid2}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Number of pod should be 2. One exited one running. + Expect(podmanTest.NumberOfPods()).To(Equal(2)) + + // Create a container. This container should be pruned. + _, ec, _ := podmanTest.RunLsContainer("test1") + Expect(ec).To(Equal(0)) + + // Number of containers should be three now. + // Two as pods infra container and one newly created. + Expect(podmanTest.NumberOfContainers()).To(Equal(3)) + + // image list current count should not be pruned if all flag isnt enabled + session = podmanTest.Podman([]string{"images"}) + session.WaitWithDefaultTimeout() + numberOfImages := len(session.OutputToStringArray()) + + // Adding unused volume should be pruned + session = podmanTest.Podman([]string{"volume", "create"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"create", "-v", "myvol:/myvol", ALPINE, "ls"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"volume", "ls"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(len(session.OutputToStringArray())).To(Equal(3)) + + session = podmanTest.Podman([]string{"system", "prune", "--force", "--volumes"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Volumes should be pruned. + session = podmanTest.Podman([]string{"volume", "ls"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(len(session.OutputToStringArray())).To(Equal(0)) + + // One Pod should not be pruned as it was running + Expect(podmanTest.NumberOfPods()).To(Equal(1)) + + // Running pods infra container should not be pruned. + Expect(podmanTest.NumberOfContainers()).To(Equal(1)) + + // Image should not be pruned and number should be same. + images := podmanTest.Podman([]string{"images"}) + images.WaitWithDefaultTimeout() + Expect(len(images.OutputToStringArray())).To(Equal(numberOfImages)) + }) + + It("podman system prune - with dangling images true", func() { + session := podmanTest.Podman([]string{"pod", "create"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + podid1 := session.OutputToString() + + // Start and stop a pod to get it in exited state. + session = podmanTest.Podman([]string{"pod", "start", podid1}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"pod", "stop", podid1}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Create a container. This container should be pruned. + create := podmanTest.Podman([]string{"create", "--name", "test", BB}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(Equal(0)) + + // Adding unused volume should not be pruned as volumes not set + session = podmanTest.Podman([]string{"volume", "create"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + prune := podmanTest.Podman([]string{"system", "prune", "-f", "-a"}) + prune.WaitWithDefaultTimeout() + Expect(prune.ExitCode()).To(Equal(0)) + + pods := podmanTest.Podman([]string{"pod", "ps"}) + pods.WaitWithDefaultTimeout() + Expect(pods.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfPods()).To(Equal(0)) + + Expect(podmanTest.NumberOfContainers()).To(Equal(0)) + + // Volumes should not be pruned + session = podmanTest.Podman([]string{"volume", "ls"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(len(session.OutputToStringArray())).To(Equal(2)) + + images := podmanTest.PodmanNoCache([]string{"images", "-aq"}) + images.WaitWithDefaultTimeout() + // all images are unused, so they all should be deleted! + Expect(len(images.OutputToStringArray())).To(Equal(0)) + }) }) diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index b987c3ff4..12ce4661f 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -101,6 +101,7 @@ var _ = Describe("Podman ps", func() { }) It("podman ps latest flag", func() { + SkipIfRemote() _, ec, _ := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) @@ -113,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)) @@ -122,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/e2e/push_test.go b/test/e2e/push_test.go index 0991da867..0747257be 100644 --- a/test/e2e/push_test.go +++ b/test/e2e/push_test.go @@ -22,7 +22,6 @@ var _ = Describe("Podman push", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) diff --git a/test/e2e/restart_test.go b/test/e2e/restart_test.go index 2b515f53b..e72a20f2d 100644 --- a/test/e2e/restart_test.go +++ b/test/e2e/restart_test.go @@ -122,6 +122,7 @@ var _ = Describe("Podman restart", func() { }) It("Podman restart the latest container", func() { + SkipIfRemote() _, exitCode, _ := podmanTest.RunLsContainer("test1") Expect(exitCode).To(Equal(0)) diff --git a/test/e2e/rm_test.go b/test/e2e/rm_test.go index 4eb568879..87e3de922 100644 --- a/test/e2e/rm_test.go +++ b/test/e2e/rm_test.go @@ -123,6 +123,7 @@ var _ = Describe("Podman rm", func() { }) It("podman rm the latest container", func() { + SkipIfRemote() session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/rmi_test.go b/test/e2e/rmi_test.go index d556cbc72..b17c03d63 100644 --- a/test/e2e/rmi_test.go +++ b/test/e2e/rmi_test.go @@ -112,7 +112,6 @@ var _ = Describe("Podman rmi", func() { }) It("podman rmi image that is a parent of another image", func() { - SkipIfRemote() session := podmanTest.PodmanNoCache([]string{"rmi", "-fa"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -141,16 +140,16 @@ var _ = Describe("Podman rmi", func() { session = podmanTest.PodmanNoCache([]string{"images", "-q", "-a"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - Expect(len(session.OutputToStringArray())).To(Equal(2)) - untaggedImg := session.OutputToStringArray()[1] + Expect(len(session.OutputToStringArray())).To(Equal(2), + "Output from 'podman images -q -a':'%s'", session.Out.Contents()) + untaggedImg := session.OutputToStringArray()[0] session = podmanTest.PodmanNoCache([]string{"rmi", "-f", untaggedImg}) session.WaitWithDefaultTimeout() - Expect(session).Should(Exit(2)) + Expect(session).Should(Exit(2), "UntaggedImg is '%s'", untaggedImg) }) It("podman rmi image that is created from another named imaged", func() { - SkipIfRemote() session := podmanTest.PodmanNoCache([]string{"rmi", "-fa"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) diff --git a/test/e2e/run_entrypoint_test.go b/test/e2e/run_entrypoint_test.go index ebc06b36c..b1344a371 100644 --- a/test/e2e/run_entrypoint_test.go +++ b/test/e2e/run_entrypoint_test.go @@ -18,7 +18,6 @@ var _ = Describe("Podman run entrypoint", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) diff --git a/test/e2e/run_env_test.go b/test/e2e/run_env_test.go index 867913a08..2adf21171 100644 --- a/test/e2e/run_env_test.go +++ b/test/e2e/run_env_test.go @@ -91,7 +91,8 @@ var _ = Describe("Podman run", func() { Expect(match).Should(BeTrue()) }) - It("podman run --host-env environment test", func() { + It("podman run --env-host environment test", func() { + SkipIfRemote() env := append(os.Environ(), "FOO=BAR") session := podmanTest.PodmanAsUser([]string{"run", "--rm", "--env-host", ALPINE, "/bin/printenv", "FOO"}, 0, 0, "", env) @@ -109,6 +110,7 @@ var _ = Describe("Podman run", func() { }) It("podman run --http-proxy test", func() { + SkipIfRemote() os.Setenv("http_proxy", "1.2.3.4") session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "printenv", "http_proxy"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index 5946f3b7a..9db2f5d49 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -19,7 +19,6 @@ var _ = Describe("Podman run networking", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) @@ -65,6 +64,110 @@ var _ = Describe("Podman run networking", func() { Expect(results.OutputToString()).To(ContainSubstring("223")) }) + It("podman run -p 80", func() { + name := "testctr" + session := podmanTest.Podman([]string{"create", "-t", "-p", "80", "--name", name, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + inspectOut := podmanTest.InspectContainer(name) + Expect(len(inspectOut)).To(Equal(1)) + Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1)) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].ContainerPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].Protocol).To(Equal("tcp")) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("")) + }) + + It("podman run -p 8080:80", func() { + name := "testctr" + session := podmanTest.Podman([]string{"create", "-t", "-p", "8080:80", "--name", name, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + inspectOut := podmanTest.InspectContainer(name) + Expect(len(inspectOut)).To(Equal(1)) + Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1)) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostPort).To(Equal(int32(8080))) + Expect(inspectOut[0].NetworkSettings.Ports[0].ContainerPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].Protocol).To(Equal("tcp")) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("")) + }) + + It("podman run -p 80/udp", func() { + name := "testctr" + session := podmanTest.Podman([]string{"create", "-t", "-p", "80/udp", "--name", name, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + inspectOut := podmanTest.InspectContainer(name) + Expect(len(inspectOut)).To(Equal(1)) + Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1)) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].ContainerPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].Protocol).To(Equal("udp")) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("")) + }) + + It("podman run -p 127.0.0.1:8080:80", func() { + name := "testctr" + session := podmanTest.Podman([]string{"create", "-t", "-p", "127.0.0.1:8080:80", "--name", name, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + inspectOut := podmanTest.InspectContainer(name) + Expect(len(inspectOut)).To(Equal(1)) + Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1)) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostPort).To(Equal(int32(8080))) + Expect(inspectOut[0].NetworkSettings.Ports[0].ContainerPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].Protocol).To(Equal("tcp")) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("127.0.0.1")) + }) + + It("podman run -p 127.0.0.1:8080:80/udp", func() { + name := "testctr" + session := podmanTest.Podman([]string{"create", "-t", "-p", "127.0.0.1:8080:80/udp", "--name", name, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + inspectOut := podmanTest.InspectContainer(name) + Expect(len(inspectOut)).To(Equal(1)) + Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1)) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostPort).To(Equal(int32(8080))) + Expect(inspectOut[0].NetworkSettings.Ports[0].ContainerPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].Protocol).To(Equal("udp")) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("127.0.0.1")) + }) + + It("podman run --expose 80 -P", func() { + name := "testctr" + session := podmanTest.Podman([]string{"create", "-t", "--expose", "80", "-P", "--name", name, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + inspectOut := podmanTest.InspectContainer(name) + Expect(len(inspectOut)).To(Equal(1)) + Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1)) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostPort).To(Not(Equal(int32(0)))) + Expect(inspectOut[0].NetworkSettings.Ports[0].ContainerPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].Protocol).To(Equal("tcp")) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("")) + }) + + It("podman run --expose 80/udp -P", func() { + name := "testctr" + session := podmanTest.Podman([]string{"create", "-t", "--expose", "80/udp", "-P", "--name", name, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + inspectOut := podmanTest.InspectContainer(name) + Expect(len(inspectOut)).To(Equal(1)) + Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1)) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostPort).To(Not(Equal(int32(0)))) + Expect(inspectOut[0].NetworkSettings.Ports[0].ContainerPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].Protocol).To(Equal("udp")) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("")) + }) + + It("podman run --expose 80 -p 80", func() { + name := "testctr" + session := podmanTest.Podman([]string{"create", "-t", "--expose", "80", "-p", "80", "--name", name, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + inspectOut := podmanTest.InspectContainer(name) + Expect(len(inspectOut)).To(Equal(1)) + Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1)) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].ContainerPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].Protocol).To(Equal("tcp")) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("")) + }) + It("podman run network expose host port 80 to container port 8000", func() { SkipIfRootless() session := podmanTest.Podman([]string{"run", "-dt", "-p", "80:8000", ALPINE, "/bin/sh"}) @@ -89,6 +192,8 @@ var _ = Describe("Podman run networking", func() { }) It("podman run network expose duplicate host port results in error", func() { + SkipIfRootless() + session := podmanTest.Podman([]string{"run", "-dt", "-p", "80", ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -98,7 +203,7 @@ var _ = Describe("Podman run networking", func() { Expect(inspect.ExitCode()).To(Equal(0)) containerConfig := inspect.InspectContainerToJSON() - Expect(containerConfig[0].NetworkSettings.Ports[0].HostPort).ToNot(Equal("80")) + Expect(containerConfig[0].NetworkSettings.Ports[0].HostPort).ToNot(Equal(80)) }) It("podman run hostname test", func() { diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index d94c6c169..59215c7e5 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -634,7 +634,6 @@ USER mail` }) It("podman run --volumes-from flag with built-in volumes", func() { - Skip(v2fail) session := podmanTest.Podman([]string{"create", redis, "sh"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -729,7 +728,6 @@ USER mail` }) It("podman run --pod automatically", func() { - Skip(v2fail) session := podmanTest.Podman([]string{"run", "--pod", "new:foobar", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go index 1f892d9f8..7cd69f738 100644 --- a/test/e2e/run_volume_test.go +++ b/test/e2e/run_volume_test.go @@ -106,6 +106,11 @@ var _ = Describe("Podman run with volumes", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring(dest + " ro")) + session = podmanTest.Podman([]string{"run", "--rm", "--mount", mount + ",readonly", ALPINE, "grep", dest, "/proc/self/mountinfo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(dest + " ro")) + session = podmanTest.Podman([]string{"run", "--rm", "--mount", mount + ",shared", ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -117,7 +122,7 @@ var _ = Describe("Podman run with volumes", func() { session = podmanTest.Podman([]string{"run", "--rm", "--mount", "type=tmpfs,target=" + dest, ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - Expect(session.OutputToString()).To(ContainSubstring(dest + " rw,nosuid,nodev,noexec,relatime - tmpfs")) + Expect(session.OutputToString()).To(ContainSubstring(dest + " rw,nosuid,nodev,relatime - tmpfs")) session = podmanTest.Podman([]string{"run", "--rm", "--mount", "type=tmpfs,target=/etc/ssl,tmpcopyup", ALPINE, "ls", "/etc/ssl"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/runlabel_test.go b/test/e2e/runlabel_test.go index 83fdcabc9..41d61e9d9 100644 --- a/test/e2e/runlabel_test.go +++ b/test/e2e/runlabel_test.go @@ -31,7 +31,6 @@ var _ = Describe("podman container runlabel", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index 3c64fa05f..9ba0241fe 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -68,7 +68,6 @@ registries = ['{{.Host}}:{{.Port}}']` registryFileTwoTmpl := template.Must(template.New("registryFileTwo").Parse(regFileContents2)) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go index 5f6f5a8cf..b8198a3a9 100644 --- a/test/e2e/start_test.go +++ b/test/e2e/start_test.go @@ -17,7 +17,6 @@ var _ = Describe("Podman start", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) @@ -66,10 +65,11 @@ var _ = Describe("Podman start", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) cid := session.OutputToString() - session = podmanTest.Podman([]string{"container", "start", cid[0:10]}) + shortID := cid[0:10] + session = podmanTest.Podman([]string{"container", "start", shortID}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - Expect(session.OutputToString()).To(Equal(cid)) + Expect(session.OutputToString()).To(Equal(shortID)) }) It("podman start single container by name", func() { @@ -120,11 +120,11 @@ var _ = Describe("Podman start", func() { }) It("podman failed to start with --rm should delete the container", func() { - session := podmanTest.Podman([]string{"create", "-it", "--rm", ALPINE, "foo"}) + session := podmanTest.Podman([]string{"create", "--name", "test1", "-it", "--rm", ALPINE, "foo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - start := podmanTest.Podman([]string{"start", "-l"}) + start := podmanTest.Podman([]string{"start", "test1"}) start.WaitWithDefaultTimeout() Expect(start).To(ExitWithError()) @@ -136,7 +136,7 @@ var _ = Describe("Podman start", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - start := podmanTest.Podman([]string{"start", "-l"}) + start := podmanTest.Podman([]string{"start", session.OutputToString()}) start.WaitWithDefaultTimeout() Expect(start).To(ExitWithError()) diff --git a/test/e2e/stats_test.go b/test/e2e/stats_test.go index 32f7cc520..d3af44891 100644 --- a/test/e2e/stats_test.go +++ b/test/e2e/stats_test.go @@ -5,6 +5,7 @@ package integration import ( "fmt" "os" + "time" "github.com/containers/libpod/pkg/cgroups" . "github.com/containers/libpod/test/utils" @@ -21,7 +22,6 @@ var _ = Describe("Podman stats", func() { ) BeforeEach(func() { - Skip(v2fail) cgroupsv2, err := cgroups.IsCgroup2UnifiedMode() Expect(err).To(BeNil()) @@ -88,13 +88,24 @@ var _ = Describe("Podman stats", func() { }) It("podman stats with json output", func() { + var found bool session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"stats", "--all", "--no-stream", "--format", "json"}) - session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) - Expect(session.IsJSONOutputValid()).To(BeTrue()) + for i := 0; i < 5; i++ { + ps := podmanTest.Podman([]string{"ps", "-q"}) + ps.WaitWithDefaultTimeout() + if len(ps.OutputToStringArray()) == 1 { + found = true + break + } + time.Sleep(time.Second) + } + Expect(found).To(BeTrue()) + stats := podmanTest.Podman([]string{"stats", "--all", "--no-stream", "--format", "json"}) + stats.WaitWithDefaultTimeout() + Expect(stats.ExitCode()).To(Equal(0)) + Expect(stats.IsJSONOutputValid()).To(BeTrue()) }) It("podman stats on a container with no net ns", func() { diff --git a/test/e2e/stop_test.go b/test/e2e/stop_test.go index 54c64d66b..cd78a54e1 100644 --- a/test/e2e/stop_test.go +++ b/test/e2e/stop_test.go @@ -184,6 +184,7 @@ var _ = Describe("Podman stop", func() { }) It("podman stop latest containers", func() { + SkipIfRemote() session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/system_df_test.go b/test/e2e/system_df_test.go index 5f261fcbf..bbbdf30b0 100644 --- a/test/e2e/system_df_test.go +++ b/test/e2e/system_df_test.go @@ -20,7 +20,6 @@ var _ = Describe("podman system df", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) diff --git a/test/e2e/system_reset_test.go b/test/e2e/system_reset_test.go index f17747648..63e77af86 100644 --- a/test/e2e/system_reset_test.go +++ b/test/e2e/system_reset_test.go @@ -17,7 +17,6 @@ var _ = Describe("podman system reset", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) @@ -35,6 +34,7 @@ var _ = Describe("podman system reset", func() { }) It("podman system reset", func() { + SkipIfRemote() // system reset will not remove additional store images, so need to grab length session := podmanTest.Podman([]string{"rmi", "--force", "--all"}) @@ -64,7 +64,7 @@ var _ = Describe("podman system reset", func() { // If remote then the varlink service should have exited // On local tests this is a noop - podmanTest.StartVarlink() + podmanTest.StartRemoteService() session = podmanTest.Podman([]string{"images", "-n"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go index c56fb00f2..1275670eb 100644 --- a/test/e2e/systemd_test.go +++ b/test/e2e/systemd_test.go @@ -23,7 +23,6 @@ var _ = Describe("Podman systemd", func() { ) BeforeEach(func() { - Skip(v2fail) SkipIfRootless() tempdir, err = CreateTempDirInTempDir() if err != nil { @@ -86,6 +85,7 @@ WantedBy=multi-user.target cgroupsv2, err := cgroups.IsCgroup2UnifiedMode() Expect(err).To(BeNil()) if cgroupsv2 { + // TODO: Find a way to enable this for v2 Skip("systemd test does not work in cgroups V2 mode yet") } diff --git a/test/e2e/trust_test.go b/test/e2e/trust_test.go index 2da370194..8c97e6b28 100644 --- a/test/e2e/trust_test.go +++ b/test/e2e/trust_test.go @@ -21,7 +21,6 @@ var _ = Describe("Podman trust", func() { ) BeforeEach(func() { - Skip(v2fail) tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) diff --git a/test/e2e/untag_test.go b/test/e2e/untag_test.go index 17171cd41..dc1a6208e 100644 --- a/test/e2e/untag_test.go +++ b/test/e2e/untag_test.go @@ -58,7 +58,7 @@ var _ = Describe("Podman untag", func() { results := podmanTest.PodmanNoCache([]string{"images"}) results.WaitWithDefaultTimeout() Expect(results.ExitCode()).To(Equal(0)) - Expect(results.OutputToStringArray()).To(HaveLen(5)) + Expect(results.OutputToStringArray()).To(HaveLen(6)) Expect(results.LineInOuputStartsWith("docker.io/library/alpine")).To(BeTrue()) Expect(results.LineInOuputStartsWith("localhost/foo")).To(BeTrue()) Expect(results.LineInOuputStartsWith("localhost/bar")).To(BeTrue()) diff --git a/test/e2e/version_test.go b/test/e2e/version_test.go index 4d2e14589..e353b9f97 100644 --- a/test/e2e/version_test.go +++ b/test/e2e/version_test.go @@ -7,6 +7,7 @@ import ( "github.com/containers/libpod/version" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman version", func() { @@ -35,54 +36,49 @@ var _ = Describe("Podman version", func() { It("podman version", func() { session := podmanTest.Podman([]string{"version"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) - Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 2)) - ok, _ := session.GrepString(version.Version) - Expect(ok).To(BeTrue()) + Expect(session).Should(Exit(0)) + Expect(session.Out.Contents()).Should(ContainSubstring(version.Version)) }) It("podman -v", func() { - Skip(v2fail) session := podmanTest.Podman([]string{"-v"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) - ok, _ := session.GrepString(version.Version) - Expect(ok).To(BeTrue()) + Expect(session).Should(Exit(0)) + Expect(session.Out.Contents()).Should(ContainSubstring(version.Version)) }) It("podman --version", func() { session := podmanTest.Podman([]string{"--version"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) - ok, _ := session.GrepString(version.Version) - Expect(ok).To(BeTrue()) + Expect(session).Should(Exit(0)) + Expect(session.Out.Contents()).Should(ContainSubstring(version.Version)) }) It("podman version --format json", func() { session := podmanTest.Podman([]string{"version", "--format", "json"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) }) It("podman version --format json", func() { session := podmanTest.Podman([]string{"version", "--format", "{{ json .}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) }) It("podman version --format GO template", func() { session := podmanTest.Podman([]string{"version", "--format", "{{ .Client.Version }}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"version", "--format", "{{ .Server.Version }}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"version", "--format", "{{ .Version }}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) }) diff --git a/test/e2e/volume_prune_test.go b/test/e2e/volume_prune_test.go index b9ea90568..3049646b0 100644 --- a/test/e2e/volume_prune_test.go +++ b/test/e2e/volume_prune_test.go @@ -65,7 +65,6 @@ var _ = Describe("Podman volume prune", func() { }) It("podman system prune --volume", func() { - Skip(v2fail) session := podmanTest.Podman([]string{"volume", "create"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/endpoint/endpoint.go b/test/endpoint/endpoint.go index f1677ec5f..6f4ae6b1f 100644 --- a/test/endpoint/endpoint.go +++ b/test/endpoint/endpoint.go @@ -71,9 +71,9 @@ func (p *EndpointTestIntegration) startVarlink(useImageCache bool) { os.MkdirAll("/run/podman", 0755) } varlinkEndpoint := p.VarlinkEndpoint - //p.SetVarlinkAddress(p.VarlinkEndpoint) + //p.SetVarlinkAddress(p.RemoteSocket) - args := []string{"varlink", "--timeout", "0", varlinkEndpoint} + args := []string{"varlink", "--time", "0", varlinkEndpoint} podmanOptions := getVarlinkOptions(p, args) if useImageCache { cacheOptions := []string{"--storage-opt", fmt.Sprintf("%s.imagestore=%s", p.ImageCacheFS, p.ImageCacheDir)} diff --git a/test/system/001-basic.bats b/test/system/001-basic.bats index 5fc07acfb..71595f419 100644 --- a/test/system/001-basic.bats +++ b/test/system/001-basic.bats @@ -23,7 +23,7 @@ function setup() { is "${lines[0]}" "Version:[ ]\+[1-9][0-9.]\+" "Version line 1" is "$output" ".*Go Version: \+" "'Go Version' in output" - is "$output" ".*RemoteAPI Version: \+" "API version in output" + is "$output" ".*API Version: \+" "API version in output" } 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/015-help.bats b/test/system/015-help.bats index fd4be87b2..42d3bd3ec 100644 --- a/test/system/015-help.bats +++ b/test/system/015-help.bats @@ -28,13 +28,20 @@ function check_help() { local subcommands_found=0 for cmd in $(podman_commands "$@"); do - dprint "podman $@ $cmd --help" + # Human-readable podman command string, with multiple spaces collapsed + command_string="podman $* $cmd" + command_string=${command_string// / } # 'podman x' -> 'podman x' + + dprint "$command_string --help" run_podman "$@" $cmd --help # The line immediately after 'Usage:' gives us a 1-line synopsis usage=$(echo "$output" | grep -A1 '^Usage:' | tail -1) [ -n "$usage" ] || die "podman $cmd: no Usage message found" + # e.g. 'podman ps' should not show 'podman container ps' in usage + is "$usage" " $command_string .*" "Usage string matches command" + # If usage ends in '[command]', recurse into subcommands if expr "$usage" : '.*\[command\]$' >/dev/null; then subcommands_found=$(expr $subcommands_found + 1) @@ -46,20 +53,33 @@ function check_help() { # Confirm that by running with 'invalid-arg' and expecting failure. if expr "$usage" : '.*\[flags\]$' >/dev/null; then if [ "$cmd" != "help" ]; then - dprint "podman $@ $cmd invalid-arg" + dprint "$command_string invalid-arg" run_podman 125 "$@" $cmd invalid-arg is "$output" "Error: .* takes no arguments" \ - "'podman $@ $cmd' with extra (invalid) arguments" + "'$command_string' with extra (invalid) arguments" fi fi # If usage has required arguments, try running without them if expr "$usage" : '.*\[flags\] [A-Z]' >/dev/null; then - if [ "$cmd" != "stats"]; then - dprint "podman $@ $cmd (without required args)" - run_podman 125 "$@" $cmd - is "$output" "Error:" + # Exceptions: these commands don't work rootless + if is_rootless; then + # "pause is not supported for rootless containers" + if [ "$cmd" = "pause" -o "$cmd" = "unpause" ]; then + continue + fi + # "network rm" too + if [ "$@" = "network" -a "$cmd" = "rm" ]; then + continue + fi fi + + # The </dev/null protects us from 'podman login' which will + # try to read username/password from stdin. + dprint "$command_string (without required args)" + run_podman 125 "$@" $cmd </dev/null + is "$output" "Error:.* \(require\|specif\|must\|provide\|need\|choose\|accepts\)" \ + "'$command_string' without required arg" fi count=$(expr $count + 1) diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 56e9fed3b..1bcf3896f 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -8,8 +8,8 @@ load helpers # 2019-09 Fedora 31 and rawhide (32) are switching from runc to crun # because of cgroups v2; crun emits different error messages. # Default to runc: - err_no_such_cmd="Error: .*: starting container process caused .*exec:.*stat /no/such/command: no such file or directory" - err_no_exec_dir="Error: .*: starting container process caused .*exec:.* permission denied" + err_no_such_cmd="Error: .*: starting container process caused.*exec:.*stat /no/such/command: no such file or directory" + err_no_exec_dir="Error: .*: starting container process caused.*exec:.* permission denied" # ...but check the configured runtime engine, and switch to crun as needed run_podman info --format '{{ .Host.OCIRuntime.Path }}' @@ -158,4 +158,34 @@ echo $rand | 0 | $rand run_podman 1 image exists $NONLOCAL_IMAGE } +# 'run --conmon-pidfile --cid-file' makes sure we don't regress on these flags. +# Both are critical for systemd units. +@test "podman run --conmon-pidfile --cidfile" { + pidfile=${PODMAN_TMPDIR}/pidfile + cidfile=${PODMAN_TMPDIR}/cidfile + + cname=$(random_string) + run_podman run --name $cname \ + --conmon-pidfile=$pidfile \ + --cidfile=$cidfile \ + --detach \ + $IMAGE sleep infinity + cid="$output" + + is "$(< $cidfile)" "$cid" "contents of cidfile == container ID" + + conmon_pid=$(< $pidfile) + is "$(readlink /proc/$conmon_pid/exe)" ".*/conmon" \ + "conmon pidfile (= PID $conmon_pid) points to conmon process" + + # All OK. Kill container. + run_podman rm -f $cid + + # Podman must not overwrite existing cid file. + # (overwriting conmon-pidfile is OK, so don't test that) + run_podman 125 run --cidfile=$cidfile $IMAGE true + is "$output" "Error: container id file exists. .* delete $cidfile" \ + "podman will not overwrite existing cidfile" +} + # vim: filetype=sh diff --git a/test/system/150-login.bats b/test/system/150-login.bats index 611db8bcf..89ae30a18 100644 --- a/test/system/150-login.bats +++ b/test/system/150-login.bats @@ -166,8 +166,6 @@ function setup() { # Some push tests @test "podman push fail" { - skip "Not working for v2 yet" - # Create an invalid authfile authfile=${PODMAN_LOGIN_WORKDIR}/auth-$(random_string 10).json rm -f $authfile @@ -201,8 +199,6 @@ EOF # https://github.com/containers/skopeo/issues/651 # - skip "Not working for v2 yet" - run_podman pull busybox # Preserve its ID for later comparison against push/pulled image diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats new file mode 100644 index 000000000..3233e6f04 --- /dev/null +++ b/test/system/160-volumes.bats @@ -0,0 +1,244 @@ +#!/usr/bin/env bats -*- bats -*- +# +# podman volume-related tests +# + +load helpers + +function setup() { + basic_setup + + run_podman '?' volume rm -a +} + +function teardown() { + run_podman '?' rm -a --volumes + run_podman '?' volume rm -a -f + + basic_teardown +} + + +# Simple volume tests: share files between host and container +@test "podman run --volumes : basic" { + skip_if_remote "volumes cannot be shared across hosts" + + # Create three temporary directories + vol1=${PODMAN_TMPDIR}/v1_$(random_string) + vol2=${PODMAN_TMPDIR}/v2_$(random_string) + vol3=${PODMAN_TMPDIR}/v3_$(random_string) + mkdir $vol1 $vol2 $vol3 + + # In each directory, write a random string to a file + echo $(random_string) >$vol1/file1_in + echo $(random_string) >$vol2/file2_in + echo $(random_string) >$vol3/file3_in + + # Run 'cat' on each file, and compare against local files. Mix -v / --volume + # flags, and specify them out of order just for grins. The shell wildcard + # expansion must sort vol1/2/3 lexically regardless. + v_opts="-v $vol1:/vol1:z --volume $vol3:/vol3:z -v $vol2:/vol2:z" + run_podman run --rm $v_opts $IMAGE sh -c "cat /vol?/file?_in" + + for i in 1 2 3; do + eval voldir=\$vol${i} + is "${lines[$(($i - 1))]}" "$(< $voldir/file${i}_in)" \ + "contents of /vol${i}/file${i}_in" + done + + # Confirm that container sees vol1 as a mount point + run_podman run --rm $v_opts $IMAGE mount + is "$output" ".* on /vol1 type .*" "'mount' in container lists vol1" + + # Have the container do write operations, confirm them on host + out1=$(random_string) + run_podman run --rm $v_opts $IMAGE sh -c "echo $out1 >/vol1/file1_out; + cp /vol2/file2_in /vol3/file3_out" + is "$(<$vol1/file1_out)" "$out1" "contents of /vol1/file1_out" + is "$(<$vol3/file3_out)" "$(<$vol2/file2_in)" "contents of /vol3/file3_out" + + # Writing to read-only volumes: not allowed + run_podman 1 run --rm -v $vol1:/vol1ro:z,ro $IMAGE sh -c "touch /vol1ro/abc" + is "$output" ".*Read-only file system" "touch on read-only volume" +} + + +# Named volumes +@test "podman volume create / run" { + myvolume=myvol$(random_string) + mylabel=$(random_string) + + # Create a named volume + run_podman volume create --label l=$mylabel $myvolume + is "$output" "$myvolume" "output from volume create" + + # Confirm that it shows up in 'volume ls', and confirm values + run_podman volume ls --format json + tests=" +Name | $myvolume +Driver | local +Labels.l | $mylabel +" + parse_table "$tests" | while read field expect; do + actual=$(jq -r ".[0].$field" <<<"$output") + is "$actual" "$expect" "volume ls .$field" + done + + # Run a container that writes to a file in that volume + mountpoint=$(jq -r '.[0].Mountpoint' <<<"$output") + rand=$(random_string) + run_podman run --rm --volume $myvolume:/vol $IMAGE sh -c "echo $rand >/vol/myfile" + + # Confirm that the file is visible, with content, outside the container + is "$(<$mountpoint/myfile)" "$rand" "we see content created in container" + + # Clean up + run_podman volume rm $myvolume +} + + +# Running scripts (executables) from a volume +@test "podman volume: exec/noexec" { + myvolume=myvol$(random_string) + + run_podman volume create $myvolume + is "$output" "$myvolume" "output from volume create" + + run_podman volume inspect --format '{{.Mountpoint}}' $myvolume + mountpoint="$output" + + # Create a script, make it runnable + rand=$(random_string) + cat >$mountpoint/myscript <<EOF +#!/bin/sh +echo "got here -$rand-" +EOF + chmod 755 $mountpoint/myscript + + # By default, volumes are mounted exec, but we have manually added the + # noexec option. This should fail. + # ARGH. Unfortunately, runc (used for cgroups v1) produces a different error + local expect_rc=126 + local expect_msg='.* OCI runtime permission denied.*' + run_podman info --format '{{ .Host.OCIRuntime.Path }}' + if expr "$output" : ".*/runc"; then + expect_rc=1 + expect_msg='.* exec user process caused.*permission denied' + fi + + run_podman ${expect_rc} run --rm --volume $myvolume:/vol:noexec,z $IMAGE /vol/myscript + is "$output" "$expect_msg" "run on volume, noexec" + + # With the default, it should pass + run_podman run --rm -v $myvolume:/vol:z $IMAGE /vol/myscript + is "$output" "got here -$rand-" "script in volume is runnable with default (exec)" + + # Clean up + run_podman volume rm $myvolume +} + + +# Anonymous temporary volumes, and persistent autocreated named ones +@test "podman volume, implicit creation with run" { + + # No hostdir arg: create anonymous container with random name + rand=$(random_string) + run_podman run -v /myvol $IMAGE sh -c "echo $rand >/myvol/myfile" + + run_podman volume ls -q + tempvolume="$output" + + # We should see the file created in the container + run_podman volume inspect --format '{{.Mountpoint}}' $tempvolume + mountpoint="$output" + test -e "$mountpoint/myfile" + is "$(< $mountpoint/myfile)" "$rand" "file contents, anonymous volume" + + # Remove the container, using rm --volumes. Volume should now be gone. + run_podman rm -a --volumes + run_podman volume ls -q + is "$output" "" "anonymous volume is removed after container is rm'ed" + + # Create a *named* container. This one should persist after container ends + myvol=myvol$(random_string) + rand=$(random_string) + + run_podman run --rm -v $myvol:/myvol:z $IMAGE \ + sh -c "echo $rand >/myvol/myfile" + run_podman volume ls -q + is "$output" "$myvol" "autocreated named container persists" + + # ...and should be usable, read/write, by a second container + run_podman run --rm -v $myvol:/myvol:z $IMAGE \ + sh -c "cp /myvol/myfile /myvol/myfile2" + + run_podman volume rm $myvol + + # Autocreated volumes should also work with keep-id + # All we do here is check status; podman 1.9.1 would fail with EPERM + myvol=myvol$(random_string) + run_podman run --rm -v $myvol:/myvol:z --userns=keep-id $IMAGE \ + touch /myvol/myfile + + run_podman volume rm $myvol +} + + +# Confirm that container sees the correct id +@test "podman volume with --userns=keep-id" { + is_rootless || skip "only meaningful when run rootless" + + myvoldir=${PODMAN_TMPDIR}/volume_$(random_string) + mkdir $myvoldir + touch $myvoldir/myfile + + # With keep-id + run_podman run --rm -v $myvoldir:/vol:z --userns=keep-id $IMAGE \ + stat -c "%u:%s" /vol/myfile + is "$output" "$(id -u):0" "with keep-id: stat(file in container) == my uid" + + # Without + run_podman run --rm -v $myvoldir:/vol:z $IMAGE \ + stat -c "%u:%s" /vol/myfile + is "$output" "0:0" "w/o keep-id: stat(file in container) == root" +} + + +# 'volume prune' identifies and cleans up unused volumes +@test "podman volume prune" { + # Create four named volumes + local -a v=() + for i in 1 2 3 4;do + vol=myvol${i}$(random_string) + v[$i]=$vol + run_podman volume create $vol + done + + # Run two containers: one mounting v1, one mounting v2 & v3 + run_podman run --name c1 --volume ${v[1]}:/vol1 $IMAGE date + run_podman run --name c2 --volume ${v[2]}:/vol2 -v ${v[3]}:/vol3 \ + $IMAGE date + + # prune should remove v4 + run_podman volume prune --force + is "$output" "${v[4]}" "volume prune, with 1, 2, 3 in use, deletes only 4" + + # Remove the container using v2 and v3. Prune should now remove those. + # The 'echo sort' is to get the output sorted and in one line. + run_podman rm c2 + run_podman volume prune --force + is "$(echo $(sort <<<$output))" "${v[2]} ${v[3]}" \ + "volume prune, after rm c2, deletes volumes 2 and 3" + + # Remove the final container. Prune should now remove v1. + run_podman rm c1 + run_podman volume prune --force + is "$output" "${v[1]}" "volume prune, after rm c2 & c1, deletes volume 1" + + # Further prunes are NOPs + run_podman volume prune --force + is "$output" "" "no more volumes to prune" +} + + +# vim: filetype=sh diff --git a/test/system/200-pod-top.bats b/test/system/200-pod-top.bats deleted file mode 100644 index bba1e8d14..000000000 --- a/test/system/200-pod-top.bats +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bats - -load helpers - -@test "podman pod top - containers in different PID namespaces" { - skip_if_remote "podman-pod does not work with podman-remote" - - # With infra=false, we don't get a /pause container (we also - # don't pull k8s.gcr.io/pause ) - no_infra='--infra=false' - run_podman pod create $no_infra - podid="$output" - - # Start two containers... - run_podman run -d --pod $podid $IMAGE top -d 2 - cid1="$output" - run_podman run -d --pod $podid $IMAGE top -d 2 - cid2="$output" - - # ...and wait for them to actually start. - wait_for_output "PID \+PPID \+USER " $cid1 - wait_for_output "PID \+PPID \+USER " $cid2 - - # Both containers have emitted at least one top-like line. - # Now run 'pod top', and expect two 'top -d 2' processes running. - run_podman pod top $podid - is "$output" ".*root.*top -d 2.*root.*top -d 2" "two 'top' containers" - - # By default (podman pod create w/ default --infra) there should be - # a /pause container. - if [ -z "$no_infra" ]; then - is "$output" ".*0 \+1 \+0 \+[0-9. ?s]\+/pause" "there is a /pause container" - fi - - # Clean up - run_podman pod rm -f $podid -} - - -# vim: filetype=sh diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats new file mode 100644 index 000000000..f34cd0707 --- /dev/null +++ b/test/system/200-pod.bats @@ -0,0 +1,185 @@ +#!/usr/bin/env bats + +load helpers + +# This is a long ugly way to clean up pods and remove the pause image +function teardown() { + run_podman pod rm -f -a + run_podman rm -f -a + run_podman image list --format '{{.ID}} {{.Repository}}' + while read id name; do + if [[ "$name" =~ /pause ]]; then + run_podman rmi $id + fi + done <<<"$output" + + basic_teardown +} + + +@test "podman pod top - containers in different PID namespaces" { + skip_if_remote "podman-pod does not work with podman-remote" + + # With infra=false, we don't get a /pause container (we also + # don't pull k8s.gcr.io/pause ) + no_infra='--infra=false' + run_podman pod create $no_infra + podid="$output" + + # Start two containers... + run_podman run -d --pod $podid $IMAGE top -d 2 + cid1="$output" + run_podman run -d --pod $podid $IMAGE top -d 2 + cid2="$output" + + # ...and wait for them to actually start. + wait_for_output "PID \+PPID \+USER " $cid1 + wait_for_output "PID \+PPID \+USER " $cid2 + + # Both containers have emitted at least one top-like line. + # Now run 'pod top', and expect two 'top -d 2' processes running. + run_podman pod top $podid + is "$output" ".*root.*top -d 2.*root.*top -d 2" "two 'top' containers" + + # By default (podman pod create w/ default --infra) there should be + # a /pause container. + if [ -z "$no_infra" ]; then + is "$output" ".*0 \+1 \+0 \+[0-9. ?s]\+/pause" "there is a /pause container" + fi + + # Clean up + run_podman pod rm -f $podid +} + + +@test "podman pod - communicating between pods" { + skip_if_remote "podman-pod does not work with podman-remote" + + podname=pod$(random_string) + run_podman pod create --infra=true --name=$podname + + # Randomly-assigned port in the 5xxx range + for port in $(shuf -i 5000-5999);do + if ! { exec 3<> /dev/tcp/127.0.0.1/$port; } &>/dev/null; then + break + fi + done + + # Listener. This will exit as soon as it receives a message. + run_podman run -d --pod $podname $IMAGE nc -l -p $port + cid1="$output" + + # Talker: send the message via common port on localhost + message=$(random_string 15) + run_podman run --rm --pod $podname $IMAGE \ + sh -c "echo $message | nc 127.0.0.1 $port" + + # Back to the first (listener) container. Make sure message was received. + run_podman logs $cid1 + is "$output" "$message" "message sent from one container to another" + + # Clean up. First the nc -l container... + run_podman rm $cid1 + + # ...then, from pause container, find the image ID of the pause image... + # FIXME: if #6283 gets implemented, use 'inspect --format ...' + run_podman pod inspect $podname + pause_cid=$(jq -r '.Containers[0].Id' <<<"$output") + run_podman container inspect --format '{{.Image}}' $pause_cid + pause_iid="$output" + + # ...then rm the pod, then rmi the pause image so we don't leave strays. + run_podman pod rm $podname + run_podman rmi $pause_iid +} + +# Random byte +function octet() { + echo $(( $RANDOM & 255 )) +} + +# random MAC address: convention seems to be that 2nd lsb=1, lsb=0 +# (i.e. 0bxxxxxx10) in the first octet guarantees a private space. +# FIXME: I can't find a definitive reference for this though +# Generate the address IN CAPS (A-F), but we will test it in lowercase. +function random_mac() { + local mac=$(printf "%02X" $(( $(octet) & 242 | 2 )) ) + for i in $(seq 2 6); do + mac+=$(printf ":%02X" $(octet)) + done + + echo $mac +} + +# Random RFC1918 IP address +function random_ip() { + local ip="172.20" + for i in 1 2;do + ip+=$(printf ".%d" $(octet)) + done + echo $ip +} + +@test "podman pod create - hashtag AllTheOptions" { + mac=$(random_mac) + add_host_ip=$(random_ip) + add_host_n=$(random_string | tr A-Z a-z).$(random_string | tr A-Z a-z).xyz + + dns_server=$(random_ip) + dns_opt="ndots:$(octet)" + dns_search=$(random_string 15 | tr A-Z a-z).abc + + hostname=$(random_string | tr A-Z a-z).$(random_string | tr A-Z a-z).net + + pod_id_file=${PODMAN_TMPDIR}/pod-id-file + + # Create a pod with all the desired options + # FIXME: --ip=$ip fails: + # Error adding network: failed to allocate all requested IPs + run_podman pod create --name=mypod \ + --pod-id-file=$pod_id_file \ + --mac-address=$mac \ + --hostname=$hostname \ + --add-host "$add_host_n:$add_host_ip" \ + --dns "$dns_server" \ + --dns-search "$dns_search" \ + --dns-opt "$dns_opt" + pod_id="$output" + + # Check --pod-id-file + is "$(<$pod_id_file)" "$pod_id" "contents of pod-id-file" + + # Check each of the options + if ! is_rootless; then + run_podman run --rm --pod mypod $IMAGE ip link show + # 'ip' outputs hex in lower-case, ${expr,,} converts UC to lc + is "$output" ".* link/ether ${mac,,} " "requested MAC address was set" + fi + + run_podman run --rm --pod mypod $IMAGE hostname + is "$output" "$hostname" "--hostname set the hostname" + + run_podman run --rm --pod $pod_id $IMAGE cat /etc/hosts + is "$output" ".*$add_host_ip $add_host_n" "--add-host was added" + is "$output" ".* $hostname" "--hostname is in /etc/hosts" + # ^^^^ this must be a tab, not a space + + run_podman run --rm --pod mypod $IMAGE cat /etc/resolv.conf + is "$output" ".*nameserver $dns_server" "--dns [server] was added" + is "$output" ".*search $dns_search" "--dns-search was added" + 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 diff --git a/test/system/250-generate-systemd.bats b/test/system/250-generate-systemd.bats deleted file mode 100644 index 6155d6ace..000000000 --- a/test/system/250-generate-systemd.bats +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bats -*- bats -*- -# -# Tests generated configurations for systemd. -# - -load helpers - -# Be extra paranoid in naming to avoid collisions. -SERVICE_NAME="podman_test_$(random_string)" -UNIT_DIR="$HOME/.config/systemd/user" -UNIT_FILE="$UNIT_DIR/$SERVICE_NAME.service" - -# FIXME: the must run as root (because of CI). It's also broken... - -function setup() { - skip_if_not_systemd - skip_if_remote - - basic_setup - - if [ ! -d "$UNIT_DIR" ]; then - mkdir -p "$UNIT_DIR" - systemctl --user daemon-reload - fi -} - -function teardown() { - rm -f "$UNIT_FILE" - systemctl --user stop "$SERVICE_NAME" - basic_teardown -} - -@test "podman generate - systemd - basic" { - run_podman create $IMAGE echo "I'm alive!" - cid="$output" - - run_podman generate systemd $cid > "$UNIT_FILE" - - run systemctl --user start "$SERVICE_NAME" - if [ $status -ne 0 ]; then - die "The systemd service $SERVICE_NAME did not start correctly, output: $output" - fi - - run_podman logs $cid - is "$output" "I'm alive!" "Container output" -} - -# vim: filetype=sh diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats new file mode 100644 index 000000000..4bee13414 --- /dev/null +++ b/test/system/250-systemd.bats @@ -0,0 +1,77 @@ +#!/usr/bin/env bats -*- bats -*- +# +# Tests generated configurations for systemd. +# + +load helpers + +SERVICE_NAME="podman_test_$(random_string)" + +SYSTEMCTL="systemctl" +UNIT_DIR="/usr/lib/systemd/system" +if is_rootless; then + UNIT_DIR="$HOME/.config/systemd/user" + mkdir -p $UNIT_DIR + + SYSTEMCTL="$SYSTEMCTL --user" +fi +UNIT_FILE="$UNIT_DIR/$SERVICE_NAME.service" + +function setup() { + skip_if_remote + + basic_setup +} + +function teardown() { + run '?' $SYSTEMCTL stop "$SERVICE_NAME" + rm -f "$UNIT_FILE" + $SYSTEMCTL daemon-reload + basic_teardown +} + +# This test can fail in dev. environment because of SELinux. +# quick fix: chcon -t container_runtime_exec_t ./bin/podman +@test "podman generate - systemd - basic" { + # podman initializes this if unset, but systemctl doesn't + if is_rootless; then + if [ -z "$XDG_RUNTIME_DIR" ]; then + export XDG_RUNTIME_DIR=/run/user/$(id -u) + fi + fi + + cname=$(random_string) + run_podman create --name $cname --detach $IMAGE top + + run_podman generate systemd --new $cname + echo "$output" > "$UNIT_FILE" + run_podman rm $cname + + $SYSTEMCTL daemon-reload + + run $SYSTEMCTL start "$SERVICE_NAME" + if [ $status -ne 0 ]; then + die "Error starting systemd unit $SERVICE_NAME, output: $output" + fi + + run $SYSTEMCTL status "$SERVICE_NAME" + if [ $status -ne 0 ]; then + die "Non-zero status of systemd unit $SERVICE_NAME, output: $output" + fi + + # Give container time to start; make sure output looks top-like + sleep 2 + run_podman logs $cname + is "$output" ".*Load average:.*" "running container 'top'-like output" + + # All good. Stop service, clean up. + run $SYSTEMCTL stop "$SERVICE_NAME" + if [ $status -ne 0 ]; then + die "Error stopping systemd unit $SERVICE_NAME, output: $output" + fi + + rm -f "$UNIT_FILE" + $SYSTEMCTL daemon-reload +} + +# vim: filetype=sh diff --git a/test/system/helpers.bash b/test/system/helpers.bash index 51240edc9..7ec2105d1 100644 --- a/test/system/helpers.bash +++ b/test/system/helpers.bash @@ -252,17 +252,6 @@ function skip_if_remote() { fi } -######################### -# skip_if_not_systemd # ...with an optional message -######################### -function skip_if_not_systemd() { - if systemctl --user >/dev/null 2>&1; then - return - fi - - skip "${1:-no systemd or daemon does not respond}" -} - ######### # die # Abort with helpful message ######### diff --git a/test/utils/utils.go b/test/utils/utils.go index 6ab8604a4..1d59e5468 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -39,9 +39,9 @@ type PodmanTest struct { TempDir string RemoteTest bool RemotePodmanBinary string - VarlinkSession *os.Process - VarlinkEndpoint string - VarlinkCommand *exec.Cmd + RemoteSession *os.Process + RemoteSocket string + RemoteCommand *exec.Cmd ImageCacheDir string ImageCacheFS string } @@ -71,9 +71,10 @@ func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string podmanBinary := p.PodmanBinary if p.RemoteTest { podmanBinary = p.RemotePodmanBinary - env = append(env, fmt.Sprintf("PODMAN_VARLINK_ADDRESS=%s", p.VarlinkEndpoint)) } - + if p.RemoteTest { + podmanOptions = append([]string{"--remote", p.RemoteSocket}, podmanOptions...) + } if env == nil { fmt.Printf("Running: %s %s\n", podmanBinary, strings.Join(podmanOptions, " ")) } else { @@ -206,7 +207,7 @@ func WaitContainerReady(p PodmanTestCommon, id string, expStr string, timeout in // OutputToString formats session output to string func (s *PodmanSession) OutputToString() string { - fields := strings.Fields(fmt.Sprintf("%s", s.Out.Contents())) + fields := strings.Fields(string(s.Out.Contents())) return strings.Join(fields, " ") } |