summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/compose/ipam_set_ip/docker-compose.yml17
-rw-r--r--test/compose/ipam_set_ip/tests.sh4
-rw-r--r--test/e2e/commit_test.go24
-rw-r--r--test/e2e/common_test.go7
-rw-r--r--test/e2e/generate_kube_test.go50
-rw-r--r--test/e2e/play_kube_test.go84
-rw-r--r--test/e2e/ps_test.go2
-rw-r--r--test/e2e/run_test.go100
-rw-r--r--test/e2e/secret_test.go23
-rw-r--r--test/system/001-basic.bats25
-rw-r--r--test/system/045-start.bats17
-rw-r--r--test/system/410-selinux.bats13
-rw-r--r--test/upgrade/README.md2
13 files changed, 346 insertions, 22 deletions
diff --git a/test/compose/ipam_set_ip/docker-compose.yml b/test/compose/ipam_set_ip/docker-compose.yml
new file mode 100644
index 000000000..d220c02c0
--- /dev/null
+++ b/test/compose/ipam_set_ip/docker-compose.yml
@@ -0,0 +1,17 @@
+version: "3.2"
+services:
+ test:
+ image: alpine
+ networks:
+ net1:
+ ipv4_address: 10.123.0.253
+ tty: true
+ command: ["top"]
+
+networks:
+ net1:
+ driver: bridge
+ ipam:
+ driver: default
+ config:
+ - subnet: 10.123.0.0/24
diff --git a/test/compose/ipam_set_ip/tests.sh b/test/compose/ipam_set_ip/tests.sh
new file mode 100644
index 000000000..ecaf3167e
--- /dev/null
+++ b/test/compose/ipam_set_ip/tests.sh
@@ -0,0 +1,4 @@
+# -*- bash -*-
+
+podman container inspect ipam_set_ip_test_1 --format '{{ .NetworkSettings.Networks.ipam_set_ip_net1.IPAddress }}'
+like "$output" "10.123.0.253" "$testname : ip address is set"
diff --git a/test/e2e/commit_test.go b/test/e2e/commit_test.go
index 0d3f2bed7..70a66124a 100644
--- a/test/e2e/commit_test.go
+++ b/test/e2e/commit_test.go
@@ -304,4 +304,28 @@ var _ = Describe("Podman commit", func() {
Expect(session.ExitCode()).To(Not(Equal(0)))
})
+
+ It("podman commit should not commit env secret", func() {
+ secretsString := "somesecretdata"
+ secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
+ err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
+ Expect(err).To(BeNil())
+
+ session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env", "--name", "secr", ALPINE, "printenv", "mysecret"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal(secretsString))
+
+ session = podmanTest.Podman([]string{"commit", "secr", "foobar.com/test1-image:latest"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"run", "foobar.com/test1-image:latest", "printenv", "mysecret"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.OutputToString()).To(Not(ContainSubstring(secretsString)))
+ })
})
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index 8530d3dd3..359345096 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -605,13 +605,6 @@ func SkipIfRootlessCgroupsV1(reason string) {
}
}
-func SkipIfUnprivilegedCPULimits() {
- info := GetHostDistributionInfo()
- if isRootless() && info.Distribution == "fedora" {
- ginkgo.Skip("Rootless Fedora doesn't have permission to set CPU limits")
- }
-}
-
func SkipIfRootless(reason string) {
checkReason(reason)
if os.Geteuid() != 0 {
diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go
index 611e8ddac..4c0fc6db0 100644
--- a/test/e2e/generate_kube_test.go
+++ b/test/e2e/generate_kube_test.go
@@ -873,4 +873,54 @@ USER test1`
}
}
})
+
+ It("podman generate kube on container with auto update labels", func() {
+ top := podmanTest.Podman([]string{"run", "-dt", "--name", "top", "--label", "io.containers.autoupdate=local", ALPINE, "top"})
+ top.WaitWithDefaultTimeout()
+ Expect(top.ExitCode()).To(Equal(0))
+
+ kube := podmanTest.Podman([]string{"generate", "kube", "top"})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube.ExitCode()).To(Equal(0))
+
+ pod := new(v1.Pod)
+ err := yaml.Unmarshal(kube.Out.Contents(), pod)
+ Expect(err).To(BeNil())
+
+ v, ok := pod.GetAnnotations()["io.containers.autoupdate/top"]
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal("local"))
+ })
+
+ It("podman generate kube on pod with auto update labels in all containers", func() {
+ pod1 := podmanTest.Podman([]string{"pod", "create", "--name", "pod1"})
+ pod1.WaitWithDefaultTimeout()
+ Expect(pod1.ExitCode()).To(Equal(0))
+
+ top1 := podmanTest.Podman([]string{"run", "-dt", "--name", "top1", "--pod", "pod1", "--label", "io.containers.autoupdate=registry", "--label", "io.containers.autoupdate.authfile=/some/authfile.json", ALPINE, "top"})
+ top1.WaitWithDefaultTimeout()
+ Expect(top1.ExitCode()).To(Equal(0))
+
+ top2 := podmanTest.Podman([]string{"run", "-dt", "--name", "top2", "--pod", "pod1", "--label", "io.containers.autoupdate=registry", "--label", "io.containers.autoupdate.authfile=/some/authfile.json", ALPINE, "top"})
+ top2.WaitWithDefaultTimeout()
+ Expect(top2.ExitCode()).To(Equal(0))
+
+ kube := podmanTest.Podman([]string{"generate", "kube", "pod1"})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube.ExitCode()).To(Equal(0))
+
+ pod := new(v1.Pod)
+ err := yaml.Unmarshal(kube.Out.Contents(), pod)
+ Expect(err).To(BeNil())
+
+ for _, ctr := range []string{"top1", "top2"} {
+ v, ok := pod.GetAnnotations()["io.containers.autoupdate/"+ctr]
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal("registry"))
+
+ v, ok = pod.GetAnnotations()["io.containers.autoupdate.authfile/"+ctr]
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal("/some/authfile.json"))
+ }
+ })
})
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index 836fbe1ee..3908d4075 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -768,6 +768,12 @@ func getCtr(options ...ctrOption) *Ctr {
type ctrOption func(*Ctr)
+func withName(name string) ctrOption {
+ return func(c *Ctr) {
+ c.Name = name
+ }
+}
+
func withCmd(cmd []string) ctrOption {
return func(c *Ctr) {
c.Cmd = cmd
@@ -1999,8 +2005,7 @@ VOLUME %s`, ALPINE, hostPathDir+"/")
It("podman play kube allows setting resource limits", func() {
SkipIfContainerized("Resource limits require a running systemd")
- SkipIfRootlessCgroupsV1("Limits require root or cgroups v2")
- SkipIfUnprivilegedCPULimits()
+ SkipIfRootless("CPU limits require root")
podmanTest.CgroupManager = "systemd"
var (
@@ -2305,4 +2310,79 @@ invalid kube kind
kube.WaitWithDefaultTimeout()
Expect(kube.ExitCode()).To(Not(Equal(0)))
})
+
+ It("podman play kube with auto update annotations for all containers", func() {
+ ctr01Name := "ctr01"
+ ctr02Name := "ctr02"
+ podName := "foo"
+ autoUpdateRegistry := "io.containers.autoupdate"
+ autoUpdateRegistryValue := "registry"
+ autoUpdateAuthfile := "io.containers.autoupdate.authfile"
+ autoUpdateAuthfileValue := "/some/authfile.json"
+
+ ctr01 := getCtr(withName(ctr01Name))
+ ctr02 := getCtr(withName(ctr02Name))
+
+ pod := getPod(
+ withPodName(podName),
+ withCtr(ctr01),
+ withCtr(ctr02),
+ withAnnotation(autoUpdateRegistry, autoUpdateRegistryValue),
+ withAnnotation(autoUpdateAuthfile, autoUpdateAuthfileValue))
+
+ err = generateKubeYaml("pod", pod, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube.ExitCode()).To(Equal(0))
+
+ for _, ctr := range []string{podName + "-" + ctr01Name, podName + "-" + ctr02Name} {
+ inspect := podmanTest.Podman([]string{"inspect", ctr, "--format", "'{{.Config.Labels}}'"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(Equal(0))
+
+ Expect(inspect.OutputToString()).To(ContainSubstring(autoUpdateRegistry + ":" + autoUpdateRegistryValue))
+ Expect(inspect.OutputToString()).To(ContainSubstring(autoUpdateAuthfile + ":" + autoUpdateAuthfileValue))
+ }
+ })
+
+ It("podman play kube with auto update annotations for first container only", func() {
+ ctr01Name := "ctr01"
+ ctr02Name := "ctr02"
+ autoUpdateRegistry := "io.containers.autoupdate"
+ autoUpdateRegistryValue := "local"
+
+ ctr01 := getCtr(withName(ctr01Name))
+ ctr02 := getCtr(withName(ctr02Name))
+
+ pod := getPod(
+ withCtr(ctr01),
+ withCtr(ctr02),
+ )
+
+ deployment := getDeployment(
+ withPod(pod),
+ withDeploymentAnnotation(autoUpdateRegistry+"/"+ctr01Name, autoUpdateRegistryValue),
+ )
+
+ err = generateKubeYaml("deployment", deployment, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube.ExitCode()).To(Equal(0))
+
+ podName := getPodNamesInDeployment(deployment)[0].Name
+
+ inspect := podmanTest.Podman([]string{"inspect", podName + "-" + ctr01Name, "--format", "'{{.Config.Labels}}'"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(Equal(0))
+ Expect(inspect.OutputToString()).To(ContainSubstring(autoUpdateRegistry + ":" + autoUpdateRegistryValue))
+
+ inspect = podmanTest.Podman([]string{"inspect", podName + "-" + ctr02Name, "--format", "'{{.Config.Labels}}'"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(Equal(0))
+ Expect(inspect.OutputToString()).To(ContainSubstring(`map[]`))
+ })
})
diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go
index d5269f415..2d7d84005 100644
--- a/test/e2e/ps_test.go
+++ b/test/e2e/ps_test.go
@@ -270,7 +270,7 @@ var _ = Describe("Podman ps", func() {
Expect(result.ExitCode()).To(Equal(0))
Expect(result.OutputToString()).To(Equal(cid))
- // Query by trunctated image name should not match ( should return empty output )
+ // Query by truncated image name should not match ( should return empty output )
result = podmanTest.Podman([]string{"ps", "-q", "--no-trunc", "-a", "--filter", "ancestor=quay.io/libpod/alpi"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index d8d7dab07..59220cf01 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -921,6 +921,17 @@ USER mail`, BB)
Expect(session.OutputToString()).To(ContainSubstring("mail root"))
})
+ It("podman run with incorect VOLUME", func() {
+ dockerfile := fmt.Sprintf(`FROM %s
+VOLUME ['/etc/foo']
+WORKDIR /etc/foo`, BB)
+ podmanTest.BuildImage(dockerfile, "test", "false")
+ session := podmanTest.Podman([]string{"run", "--rm", "test", "echo", "test"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring("test"))
+ })
+
It("podman run --volumes-from flag", func() {
vol := filepath.Join(podmanTest.TempDir, "vol-test")
err := os.MkdirAll(vol, 0755)
@@ -1600,6 +1611,95 @@ WORKDIR /madethis`, BB)
})
+ It("podman run --secret source=mysecret,type=mount", func() {
+ secretsString := "somesecretdata"
+ secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
+ err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
+ Expect(err).To(BeNil())
+
+ session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=mount", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal(secretsString))
+
+ session = podmanTest.Podman([]string{"inspect", "secr", "--format", " {{(index .Config.Secrets 0).Name}}"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring("mysecret"))
+
+ })
+
+ It("podman run --secret source=mysecret,type=env", func() {
+ secretsString := "somesecretdata"
+ secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
+ err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
+ Expect(err).To(BeNil())
+
+ session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env", "--name", "secr", ALPINE, "printenv", "mysecret"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal(secretsString))
+ })
+
+ It("podman run --secret target option", func() {
+ secretsString := "somesecretdata"
+ secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
+ err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
+ Expect(err).To(BeNil())
+
+ session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ // target with mount type should fail
+ session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=mount,target=anotherplace", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+
+ session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env,target=anotherplace", "--name", "secr", ALPINE, "printenv", "anotherplace"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal(secretsString))
+ })
+
+ It("podman run invalid secret option", func() {
+ secretsString := "somesecretdata"
+ secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
+ err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
+ Expect(err).To(BeNil())
+
+ session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ // Invalid type
+ session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=other", "--name", "secr", ALPINE, "printenv", "mysecret"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+
+ // Invalid option
+ session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,invalid=invalid", "--name", "secr", ALPINE, "printenv", "mysecret"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+
+ // Option syntax not valid
+ session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type", "--name", "secr", ALPINE, "printenv", "mysecret"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+
+ // No source given
+ session = podmanTest.Podman([]string{"run", "--secret", "type=env", "--name", "secr", ALPINE, "printenv", "mysecret"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+ })
+
It("podman run --requires", func() {
depName := "ctr1"
depContainer := podmanTest.Podman([]string{"create", "--name", depName, ALPINE, "top"})
diff --git a/test/e2e/secret_test.go b/test/e2e/secret_test.go
index fbee18442..b54b959bf 100644
--- a/test/e2e/secret_test.go
+++ b/test/e2e/secret_test.go
@@ -199,4 +199,27 @@ var _ = Describe("Podman secret", func() {
Expect(len(session.OutputToStringArray())).To(Equal(1))
})
+ It("podman secret creates from environment variable", func() {
+ // no env variable set, should fail
+ session := podmanTest.Podman([]string{"secret", "create", "--env", "a", "MYENVVAR"})
+ session.WaitWithDefaultTimeout()
+ secrID := session.OutputToString()
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+
+ os.Setenv("MYENVVAR", "somedata")
+ if IsRemote() {
+ podmanTest.RestartRemoteService()
+ }
+
+ session = podmanTest.Podman([]string{"secret", "create", "--env", "a", "MYENVVAR"})
+ session.WaitWithDefaultTimeout()
+ secrID = session.OutputToString()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ inspect := podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.ID}}", secrID})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(Equal(0))
+ Expect(inspect.OutputToString()).To(Equal(secrID))
+ })
+
})
diff --git a/test/system/001-basic.bats b/test/system/001-basic.bats
index 35107f0a0..5d44c373f 100644
--- a/test/system/001-basic.bats
+++ b/test/system/001-basic.bats
@@ -10,16 +10,18 @@ function setup() {
:
}
-@test "podman --context emits reasonable output" {
- run_podman 125 --context=swarm version
- is "$output" "Error: Podman does not support swarm, the only --context value allowed is \"default\"" "--context=default or fail"
-
- run_podman --context=default version
-}
+#### DO NOT ADD ANY TESTS HERE! ADD NEW TESTS AT BOTTOM!
@test "podman version emits reasonable output" {
run_podman version
+ # FIXME FIXME FIXME: #10248: nasty message on Ubuntu cgroups v1, rootless
+ if [[ "$output" =~ "overlay test mount with multiple lowers failed" ]]; then
+ if is_rootless; then
+ lines=("${lines[@]:1}")
+ fi
+ fi
+
# First line of podman-remote is "Client:<blank>".
# Just delete it (i.e. remove the first entry from the 'lines' array)
if is_remote; then
@@ -41,6 +43,17 @@ function setup() {
}
+@test "podman --context emits reasonable output" {
+ # All we care about here is that the command passes
+ run_podman --context=default version
+
+ # This one must fail
+ run_podman 125 --context=swarm version
+ is "$output" \
+ "Error: Podman does not support swarm, the only --context value allowed is \"default\"" \
+ "--context=default or fail"
+}
+
@test "podman can pull an image" {
run_podman pull $IMAGE
}
diff --git a/test/system/045-start.bats b/test/system/045-start.bats
index ff818e51d..542f9d1c2 100644
--- a/test/system/045-start.bats
+++ b/test/system/045-start.bats
@@ -40,4 +40,21 @@ load helpers
fi
}
+@test "podman start --filter - start only containers that match the filter" {
+ run_podman run -d $IMAGE /bin/true
+ cid="$output"
+ run_podman start --filter restart-policy=always $cid "CID of restart-policy=always container"
+ is "$output" ""
+
+ run_podman start --filter restart-policy=none $cid "CID of restart-policy=none container"
+ is "$output" "$cid"
+}
+
+@test "podman start --filter invalid-restart-policy - return error" {
+ run_podman run -d $IMAGE /bin/true
+ cid="$output"
+ run_podman 125 start --filter restart-policy=fakepolicy $cid "CID of restart-policy=<not-exists> container"
+ is "$output" "Error: fakepolicy invalid restart policy"
+}
+
# vim: filetype=sh
diff --git a/test/system/410-selinux.bats b/test/system/410-selinux.bats
index 95233c1e6..f8cee0e59 100644
--- a/test/system/410-selinux.bats
+++ b/test/system/410-selinux.bats
@@ -198,20 +198,23 @@ function check_label() {
skip_if_no_selinux
LABEL="system_u:object_r:tmp_t:s0"
+ RELABEL="system_u:object_r:container_file_t:s0"
tmpdir=$PODMAN_TMPDIR/vol
touch $tmpdir
chcon -vR ${LABEL} $tmpdir
ls -Z $tmpdir
run_podman run -v $tmpdir:/test $IMAGE cat /proc/self/attr/current
- level=$(secon -l $output)
run ls -dZ ${tmpdir}
is "$output" ${LABEL} "No Relabel Correctly"
- run_podman run -v $tmpdir:/test:Z --security-opt label=disable $IMAGE cat /proc/self/attr/current
- level=$(secon -l $output)
+ run_podman run -v $tmpdir:/test:z --security-opt label=disable $IMAGE cat /proc/self/attr/current
+ run ls -dZ $tmpdir
+ is "$output" ${RELABEL} "Privileged Relabel Correctly"
+
+ run_podman run -v $tmpdir:/test:z --privileged $IMAGE cat /proc/self/attr/current
run ls -dZ $tmpdir
- is "$output" ${LABEL} "No Privileged Relabel Correctly"
+ is "$output" ${RELABEL} "Privileged Relabel Correctly"
run_podman run -v $tmpdir:/test:Z $IMAGE cat /proc/self/attr/current
level=$(secon -l $output)
@@ -220,7 +223,7 @@ function check_label() {
run_podman run -v $tmpdir:/test:z $IMAGE cat /proc/self/attr/current
run ls -dZ $tmpdir
- is "$output" "system_u:object_r:container_file_t:s0" "Shared Relabel Correctly"
+ is "$output" ${RELABEL} "Shared Relabel Correctly"
}
# vim: filetype=sh
diff --git a/test/upgrade/README.md b/test/upgrade/README.md
index 2979a66d7..6e5005134 100644
--- a/test/upgrade/README.md
+++ b/test/upgrade/README.md
@@ -84,4 +84,4 @@ Where To Go From Here
* Figuring out how/if to run variations with different config files
(e.g. running OLD-PODMAN that creates a user libpod.conf, tweaking
- that in the test, then running NEW-PODMAN upgrate tests)
+ that in the test, then running NEW-PODMAN upgrade tests)