Add --retry[-times] to test operations that tend to fail

... to decrease impact of flakes.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač 2025-05-26 21:27:22 +02:00
parent 8abee34d4b
commit 3618a76e92
3 changed files with 36 additions and 22 deletions

View File

@ -64,7 +64,7 @@ _run_setup() {
# things directly on the host VM. Fortunately they're all # things directly on the host VM. Fortunately they're all
# located in the container under /usr/local/bin # located in the container under /usr/local/bin
msg "Accessing contents of $SKOPEO_CIDEV_CONTAINER_FQIN" msg "Accessing contents of $SKOPEO_CIDEV_CONTAINER_FQIN"
podman pull --quiet $SKOPEO_CIDEV_CONTAINER_FQIN podman pull --retry 3 --quiet $SKOPEO_CIDEV_CONTAINER_FQIN
mnt=$(podman mount $(podman create $SKOPEO_CIDEV_CONTAINER_FQIN)) mnt=$(podman mount $(podman create $SKOPEO_CIDEV_CONTAINER_FQIN))
# The container and VM images are built in tandem in the same repo. # The container and VM images are built in tandem in the same repo.

View File

@ -107,7 +107,8 @@ func (s *skopeoSuite) TestCopyWithLocalAuth() {
"login", "--tls-verify=false", "--username="+s.regV2WithAuth.username, "--password="+s.regV2WithAuth.password, s.regV2WithAuth.url) "login", "--tls-verify=false", "--username="+s.regV2WithAuth.username, "--password="+s.regV2WithAuth.password, s.regV2WithAuth.url)
// copy to private registry using local authentication // copy to private registry using local authentication
imageName := fmt.Sprintf("docker://%s/busybox:mine", s.regV2WithAuth.url) imageName := fmt.Sprintf("docker://%s/busybox:mine", s.regV2WithAuth.url)
assertSkopeoSucceeds(t, "", "copy", "--dest-tls-verify=false", testFQIN+":latest", imageName) assertSkopeoSucceeds(t, "", "copy", "--dest-tls-verify=false", "--retry-times", "3",
testFQIN+":latest", imageName)
// inspect from private registry // inspect from private registry
assertSkopeoSucceeds(t, "", "inspect", "--tls-verify=false", imageName) assertSkopeoSucceeds(t, "", "inspect", "--tls-verify=false", imageName)
// logout from the registry // logout from the registry

View File

@ -451,7 +451,8 @@ func (s *copySuite) TestCopySucceedsWhenImageDoesNotMatchRuntimeButWeOverride()
t := s.T() t := s.T()
storage := t.TempDir() storage := t.TempDir()
storage = fmt.Sprintf("[vfs@%s/root+%s/runroot]", storage, storage) storage = fmt.Sprintf("[vfs@%s/root+%s/runroot]", storage, storage)
assertSkopeoSucceeds(t, "", "--override-os=windows", "--override-arch=amd64", "copy", knownWindowsOnlyImage, "containers-storage:"+storage+"test") assertSkopeoSucceeds(t, "", "--override-os=windows", "--override-arch=amd64", "copy", knownWindowsOnlyImage, "--retry-times", "3",
"containers-storage:"+storage+"test")
} }
func (s *copySuite) TestCopySimpleAtomicRegistry() { func (s *copySuite) TestCopySimpleAtomicRegistry() {
@ -461,7 +462,7 @@ func (s *copySuite) TestCopySimpleAtomicRegistry() {
// FIXME: It would be nice to use one of the local Docker registries instead of needing an Internet connection. // FIXME: It would be nice to use one of the local Docker registries instead of needing an Internet connection.
// "pull": docker: → dir: // "pull": docker: → dir:
assertSkopeoSucceeds(t, "", "copy", testFQIN64, "dir:"+dir1) assertSkopeoSucceeds(t, "", "copy", testFQIN64, "--retry-times", "3", "dir:"+dir1)
// "push": dir: → atomic: // "push": dir: → atomic:
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", "dir:"+dir1, "atomic:localhost:5000/myns/unsigned:unsigned") assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", "dir:"+dir1, "atomic:localhost:5000/myns/unsigned:unsigned")
// The result of pushing and pulling is an equivalent image, except for schema1 embedded names. // The result of pushing and pulling is an equivalent image, except for schema1 embedded names.
@ -539,7 +540,8 @@ func (s *copySuite) TestCopyEncryption() {
"oci:"+encryptedImgDir+":encrypted", "oci:"+decryptedImgDir+":decrypted") "oci:"+encryptedImgDir+":encrypted", "oci:"+decryptedImgDir+":decrypted")
// Copy a standard busybox image locally // Copy a standard busybox image locally
assertSkopeoSucceeds(t, "", "copy", testFQIN+":1.30.1", "oci:"+originalImageDir+":latest") assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3",
testFQIN+":1.30.1", "oci:"+originalImageDir+":latest")
// Encrypt the image // Encrypt the image
assertSkopeoSucceeds(t, "", "copy", "--encryption-key", assertSkopeoSucceeds(t, "", "copy", "--encryption-key",
@ -570,7 +572,7 @@ func (s *copySuite) TestCopyEncryption() {
matchLayerBlobBinaryType(t, decryptedImgDir+"/blobs/sha256", "application/x-gzip", 1) matchLayerBlobBinaryType(t, decryptedImgDir+"/blobs/sha256", "application/x-gzip", 1)
// Copy a standard multi layer nginx image locally // Copy a standard multi layer nginx image locally
assertSkopeoSucceeds(t, "", "copy", testFQINMultiLayer, "oci:"+multiLayerImageDir+":latest") assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", testFQINMultiLayer, "oci:"+multiLayerImageDir+":latest")
// Partially encrypt the image // Partially encrypt the image
assertSkopeoSucceeds(t, "", "copy", "--encryption-key", "jwe:"+keysDir+"/public.key", assertSkopeoSucceeds(t, "", "copy", "--encryption-key", "jwe:"+keysDir+"/public.key",
@ -671,9 +673,10 @@ func (s *copySuite) TestCopyStreaming() {
// FIXME: It would be nice to use one of the local Docker registries instead of needing an Internet connection. // FIXME: It would be nice to use one of the local Docker registries instead of needing an Internet connection.
// streaming: docker: → atomic: // streaming: docker: → atomic:
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", testFQIN64, "atomic:localhost:5000/myns/unsigned:streaming") assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", "--retry-times", "3",
testFQIN64, "atomic:localhost:5000/myns/unsigned:streaming")
// Compare (copies of) the original and the copy: // Compare (copies of) the original and the copy:
assertSkopeoSucceeds(t, "", "copy", testFQIN64, "dir:"+dir1) assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", testFQIN64, "dir:"+dir1)
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "atomic:localhost:5000/myns/unsigned:streaming", "dir:"+dir2) assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "atomic:localhost:5000/myns/unsigned:streaming", "dir:"+dir2)
assertSchema1DirImagesAreEqualExceptNames(t, dir1, "libpod/busybox:amd64", dir2, "myns/unsigned:streaming") assertSchema1DirImagesAreEqualExceptNames(t, dir1, "libpod/busybox:amd64", dir2, "myns/unsigned:streaming")
// FIXME: Also check pushing to docker:// // FIXME: Also check pushing to docker://
@ -692,7 +695,8 @@ func (s *copySuite) TestCopyOCIRoundTrip() {
oci2 := t.TempDir() oci2 := t.TempDir()
// Docker -> OCI // Docker -> OCI
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", testFQIN, "oci:"+oci1+":latest") assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", "--retry-times", "3",
testFQIN, "oci:"+oci1+":latest")
// OCI -> Docker // OCI -> Docker
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", "oci:"+oci1+":latest", ourRegistry+"original/busybox:oci_copy") assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", "oci:"+oci1+":latest", ourRegistry+"original/busybox:oci_copy")
// Docker -> OCI // Docker -> OCI
@ -750,8 +754,10 @@ func (s *copySuite) TestCopySignatures() {
// type: signedBy // type: signedBy
// Sign the images // Sign the images
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--sign-by", "personal@example.com", testFQIN+":1.26", "atomic:localhost:5006/myns/personal:personal") assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--retry-times", "3", "--sign-by", "personal@example.com",
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--sign-by", "official@example.com", testFQIN+":1.26.1", "atomic:localhost:5006/myns/official:official") testFQIN+":1.26", "atomic:localhost:5006/myns/personal:personal")
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--retry-times", "3", "--sign-by", "official@example.com",
testFQIN+":1.26.1", "atomic:localhost:5006/myns/official:official")
// Verify that we can pull them // Verify that we can pull them
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--policy", policy, "copy", "atomic:localhost:5006/myns/personal:personal", dirDest) assertSkopeoSucceeds(t, "", "--tls-verify=false", "--policy", policy, "copy", "atomic:localhost:5006/myns/personal:personal", dirDest)
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--policy", policy, "copy", "atomic:localhost:5006/myns/official:official", dirDest) assertSkopeoSucceeds(t, "", "--tls-verify=false", "--policy", policy, "copy", "atomic:localhost:5006/myns/official:official", dirDest)
@ -804,8 +810,8 @@ func (s *copySuite) TestCopyDirSignatures() {
defer os.Remove(policy) defer os.Remove(policy)
// Get some images. // Get some images.
assertSkopeoSucceeds(t, "", "copy", testFQIN+":armfh", topDirDest+"/dir1") assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", testFQIN+":armfh", topDirDest+"/dir1")
assertSkopeoSucceeds(t, "", "copy", testFQIN+":s390x", topDirDest+"/dir2") assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", testFQIN+":s390x", topDirDest+"/dir2")
// Sign the images. By coping from a topDirDest/dirN, also test that non-/restricted paths // Sign the images. By coping from a topDirDest/dirN, also test that non-/restricted paths
// use the dir:"" default of insecureAcceptAnything. // use the dir:"" default of insecureAcceptAnything.
@ -919,7 +925,8 @@ func (s *copySuite) TestCopyDockerLookaside() {
require.NoError(t, err) require.NoError(t, err)
// Get an image to work with. Also verifies that we can use Docker repositories with no lookaside configured. // Get an image to work with. Also verifies that we can use Docker repositories with no lookaside configured.
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--registries.d", registriesDir, "copy", testFQIN, ourRegistry+"original/busybox") assertSkopeoSucceeds(t, "", "--tls-verify=false", "--registries.d", registriesDir, "copy", "--retry-times", "3",
testFQIN, ourRegistry+"original/busybox")
// Pulling an unsigned image fails. // Pulling an unsigned image fails.
assertSkopeoFails(t, ".*Source image rejected: A signature was required, but no signature exists.*", assertSkopeoFails(t, ".*Source image rejected: A signature was required, but no signature exists.*",
"--tls-verify=false", "--policy", policy, "--registries.d", registriesDir, "copy", ourRegistry+"original/busybox", dirDest) "--tls-verify=false", "--policy", policy, "--registries.d", registriesDir, "copy", ourRegistry+"original/busybox", dirDest)
@ -972,7 +979,8 @@ func (s *copySuite) TestCopyAtomicExtension() {
defer os.Remove(policy) defer os.Remove(policy)
// Get an image to work with to an atomic: destination. Also verifies that we can use Docker repositories without X-Registry-Supports-Signatures // Get an image to work with to an atomic: destination. Also verifies that we can use Docker repositories without X-Registry-Supports-Signatures
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--registries.d", registriesDir, "copy", testFQIN, "atomic:localhost:5000/myns/extension:unsigned") assertSkopeoSucceeds(t, "", "--tls-verify=false", "--registries.d", registriesDir, "copy", "--retry-times", "3",
testFQIN, "atomic:localhost:5000/myns/extension:unsigned")
// Pulling an unsigned image using atomic: fails. // Pulling an unsigned image using atomic: fails.
assertSkopeoFails(t, ".*Source image rejected: A signature was required, but no signature exists.*", assertSkopeoFails(t, ".*Source image rejected: A signature was required, but no signature exists.*",
"--tls-verify=false", "--policy", policy, "--tls-verify=false", "--policy", policy,
@ -996,7 +1004,8 @@ func (s *copySuite) TestCopyAtomicExtension() {
// Get another image (different so that they don't share signatures, and sign it using docker://) // Get another image (different so that they don't share signatures, and sign it using docker://)
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--registries.d", registriesDir, assertSkopeoSucceeds(t, "", "--tls-verify=false", "--registries.d", registriesDir,
"copy", "--sign-by", "personal@example.com", testFQIN+":ppc64le", "docker://localhost:5000/myns/extension:extension") "copy", "--retry-times", "3", "--sign-by", "personal@example.com",
testFQIN+":ppc64le", "docker://localhost:5000/myns/extension:extension")
t.Logf("%s", combinedOutputOfCommand(t, "oc", "get", "istag", "extension:extension", "-o", "json")) t.Logf("%s", combinedOutputOfCommand(t, "oc", "get", "istag", "extension:extension", "-o", "json"))
// Pulling the image using atomic: succeeds. // Pulling the image using atomic: succeeds.
assertSkopeoSucceeds(t, "", "--debug", "--tls-verify=false", "--policy", policy, assertSkopeoSucceeds(t, "", "--debug", "--tls-verify=false", "--policy", policy,
@ -1033,7 +1042,8 @@ func (s *copySuite) TestCopyVerifyingMirroredSignatures() {
// So, make sure to never create a signature that could be considered valid in a different part of the test (i.e. don't reuse tags). // So, make sure to never create a signature that could be considered valid in a different part of the test (i.e. don't reuse tags).
// Get an image to work with. // Get an image to work with.
assertSkopeoSucceeds(t, "", "copy", "--dest-tls-verify=false", testFQIN, regPrefix+"primary:unsigned") assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", "--dest-tls-verify=false",
testFQIN, regPrefix+"primary:unsigned")
// Verify that unsigned images are rejected // Verify that unsigned images are rejected
assertSkopeoFails(t, ".*Source image rejected: A signature was required, but no signature exists.*", assertSkopeoFails(t, ".*Source image rejected: A signature was required, but no signature exists.*",
"--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"primary:unsigned", dirDest) "--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"primary:unsigned", dirDest)
@ -1082,19 +1092,22 @@ func (s *copySuite) TestCopyVerifyingMirroredSignatures() {
func (s *skopeoSuite) TestCopySrcWithAuth() { func (s *skopeoSuite) TestCopySrcWithAuth() {
t := s.T() t := s.T()
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--dest-creds=testuser:testpassword", testFQIN, fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url)) assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--retry-times", "3", "--dest-creds=testuser:testpassword",
testFQIN, fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url))
dir1 := t.TempDir() dir1 := t.TempDir()
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--src-creds=testuser:testpassword", fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url), "dir:"+dir1) assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--src-creds=testuser:testpassword", fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url), "dir:"+dir1)
} }
func (s *skopeoSuite) TestCopyDestWithAuth() { func (s *skopeoSuite) TestCopyDestWithAuth() {
t := s.T() t := s.T()
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--dest-creds=testuser:testpassword", testFQIN, fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url)) assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--retry-times", "3", "--dest-creds=testuser:testpassword",
testFQIN, fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url))
} }
func (s *skopeoSuite) TestCopySrcAndDestWithAuth() { func (s *skopeoSuite) TestCopySrcAndDestWithAuth() {
t := s.T() t := s.T()
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--dest-creds=testuser:testpassword", testFQIN, fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url)) assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--retry-times", "3", "--dest-creds=testuser:testpassword",
testFQIN, fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url))
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--src-creds=testuser:testpassword", "--dest-creds=testuser:testpassword", fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url), fmt.Sprintf("docker://%s/test:auth", s.regV2WithAuth.url)) assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--src-creds=testuser:testpassword", "--dest-creds=testuser:testpassword", fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url), fmt.Sprintf("docker://%s/test:auth", s.regV2WithAuth.url))
} }
@ -1125,7 +1138,7 @@ func (s *copySuite) TestCopyManifestConversion() {
// oci to v2s1 and vice-versa not supported yet // oci to v2s1 and vice-versa not supported yet
// get v2s2 manifest type // get v2s2 manifest type
assertSkopeoSucceeds(t, "", "copy", testFQIN, "dir:"+srcDir) assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", testFQIN, "dir:"+srcDir)
verifyManifestMIMEType(t, srcDir, manifest.DockerV2Schema2MediaType) verifyManifestMIMEType(t, srcDir, manifest.DockerV2Schema2MediaType)
// convert from v2s2 to oci // convert from v2s2 to oci
assertSkopeoSucceeds(t, "", "copy", "--format=oci", "dir:"+srcDir, "dir:"+destDir1) assertSkopeoSucceeds(t, "", "copy", "--format=oci", "dir:"+srcDir, "dir:"+destDir1)
@ -1161,7 +1174,7 @@ func (s *copySuite) testCopySchemaConversionRegistries(t *testing.T, schema1Regi
// Ensure we are working with a schema2 image. // Ensure we are working with a schema2 image.
// dir: accepts any manifest format, i.e. this makes …/input2 a schema2 source which cannot be asked to produce schema1 like ordinary docker: registries can. // dir: accepts any manifest format, i.e. this makes …/input2 a schema2 source which cannot be asked to produce schema1 like ordinary docker: registries can.
assertSkopeoSucceeds(t, "", "copy", testFQIN, "dir:"+input2Dir) assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", testFQIN, "dir:"+input2Dir)
verifyManifestMIMEType(t, input2Dir, manifest.DockerV2Schema2MediaType) verifyManifestMIMEType(t, input2Dir, manifest.DockerV2Schema2MediaType)
// 2→2 (the "f2t2" in tag means "from 2 to 2") // 2→2 (the "f2t2" in tag means "from 2 to 2")
assertSkopeoSucceeds(t, "", "copy", "--dest-tls-verify=false", "dir:"+input2Dir, schema2Registry+":f2t2") assertSkopeoSucceeds(t, "", "copy", "--dest-tls-verify=false", "dir:"+input2Dir, schema2Registry+":f2t2")