Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle lost sparseness in non http data sources #3213

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions cmd/cdi-cloner/clone-source.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"crypto/x509"
"errors"
"flag"
"fmt"
"io"
"net/http"
"os"
Expand Down Expand Up @@ -55,7 +56,7 @@ func (er *execReader) Close() error {
}

func init() {
flag.StringVar(&contentType, "content-type", "", "filesystem-clone|blockdevice-clone")
flag.StringVar(&contentType, "content-type", "", fmt.Sprintf("%s|%s", common.FilesystemCloneContentType, common.BlockdeviceClone))
flag.StringVar(&mountPoint, "mount", "", "pvc mount point")
flag.Uint64Var(&uploadBytes, "upload-bytes", 0, "approx number of bytes in input")
klog.InitFlags(nil)
Expand Down Expand Up @@ -133,7 +134,7 @@ func pipeToSnappy(reader io.ReadCloser) io.ReadCloser {

func validateContentType() {
switch contentType {
case "filesystem-clone", "blockdevice-clone":
case common.FilesystemCloneContentType, common.BlockdeviceClone:
default:
klog.Fatalf("Invalid content-type %q", contentType)
}
Expand Down Expand Up @@ -198,13 +199,13 @@ func newTarReader(preallocation bool) (io.ReadCloser, error) {

func getInputStream(preallocation bool) io.ReadCloser {
switch contentType {
case "filesystem-clone":
case common.FilesystemCloneContentType:
rc, err := newTarReader(preallocation)
if err != nil {
klog.Fatalf("Error creating tar reader for %q: %+v", mountPoint, err)
}
return rc
case "blockdevice-clone":
case common.BlockdeviceClone:
rc, err := os.Open(mountPoint)
if err != nil {
klog.Fatalf("Error opening block device %q: %+v", mountPoint, err)
Expand Down
4 changes: 0 additions & 4 deletions pkg/importer/upload-datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ func (ud *UploadDataSource) Info() (ProcessingPhase, error) {
if ud.contentType == cdiv1.DataVolumeArchive {
return ProcessingPhaseTransferDataDir, nil
}
if !ud.readers.Convert {
// Uploading a raw file, we can write that directly to the target.
return ProcessingPhaseTransferDataFile, nil
}
return ProcessingPhaseTransferScratch, nil
}

Expand Down
16 changes: 8 additions & 8 deletions pkg/importer/upload-datasource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ var _ = Describe("Upload data source", func() {
Expect(ProcessingPhaseTransferDataDir).To(Equal(result))
})

It("Info should return TransferData, when passed in a valid raw image", func() {
It("Info should return TransferScratch, when passed in a valid raw image", func() {
// Don't need to defer close, since ud.Close will close the reader
file, err := os.Open(tinyCoreFilePath)
Expect(err).NotTo(HaveOccurred())
ud = NewUploadDataSource(file, dvKubevirt)
result, err := ud.Info()
Expect(err).NotTo(HaveOccurred())
Expect(ProcessingPhaseTransferDataFile).To(Equal(result))
Expect(ProcessingPhaseTransferScratch).To(Equal(result))
})

DescribeTable("calling transfer should", func(fileName string, dvContentType cdiv1.DataVolumeContentType, expectedPhase ProcessingPhase, scratchPath string, want []byte, wantErr bool) {
Expand Down Expand Up @@ -136,7 +136,7 @@ var _ = Describe("Upload data source", func() {
ud = NewUploadDataSource(sourceFile, dvKubevirt)
result, err := ud.Info()
Expect(err).NotTo(HaveOccurred())
Expect(ProcessingPhaseTransferDataFile).To(Equal(result))
Expect(ProcessingPhaseTransferScratch).To(Equal(result))
result, err = ud.TransferFile(filepath.Join(tmpDir, "file"))
Expect(err).ToNot(HaveOccurred())
Expect(ProcessingPhaseResize).To(Equal(result))
Expand All @@ -149,7 +149,7 @@ var _ = Describe("Upload data source", func() {
ud = NewUploadDataSource(sourceFile, dvKubevirt)
result, err := ud.Info()
Expect(err).NotTo(HaveOccurred())
Expect(ProcessingPhaseTransferDataFile).To(Equal(result))
Expect(ProcessingPhaseTransferScratch).To(Equal(result))
result, err = ud.TransferFile("/invalidpath/invalidfile")
Expect(err).To(HaveOccurred())
Expect(ProcessingPhaseError).To(Equal(result))
Expand Down Expand Up @@ -204,14 +204,14 @@ var _ = Describe("Async Upload data source", func() {
Expect(ProcessingPhaseTransferScratch).To(Equal(result))
})

It("Info should return TransferData, when passed in a valid raw image", func() {
It("Info should return TransferScratch, when passed in a valid raw image", func() {
// Don't need to defer close, since ud.Close will close the reader
file, err := os.Open(tinyCoreFilePath)
Expect(err).NotTo(HaveOccurred())
aud = NewAsyncUploadDataSource(file)
result, err := aud.Info()
Expect(err).NotTo(HaveOccurred())
Expect(ProcessingPhaseTransferDataFile).To(Equal(result))
Expect(ProcessingPhaseTransferScratch).To(Equal(result))
})

DescribeTable("calling transfer should", func(fileName, scratchPath string, want []byte, wantErr bool) {
Expand Down Expand Up @@ -260,7 +260,7 @@ var _ = Describe("Async Upload data source", func() {
aud = NewAsyncUploadDataSource(sourceFile)
result, err := aud.Info()
Expect(err).NotTo(HaveOccurred())
Expect(ProcessingPhaseTransferDataFile).To(Equal(result))
Expect(ProcessingPhaseTransferScratch).To(Equal(result))
result, err = aud.TransferFile(filepath.Join(tmpDir, "file"))
Expect(err).ToNot(HaveOccurred())
Expect(ProcessingPhaseValidatePause).To(Equal(result))
Expand All @@ -274,7 +274,7 @@ var _ = Describe("Async Upload data source", func() {
aud = NewAsyncUploadDataSource(sourceFile)
result, err := aud.Info()
Expect(err).NotTo(HaveOccurred())
Expect(ProcessingPhaseTransferDataFile).To(Equal(result))
Expect(ProcessingPhaseTransferScratch).To(Equal(result))
result, err = aud.TransferFile("/invalidpath/invalidfile")
Expect(err).To(HaveOccurred())
Expect(ProcessingPhaseError).To(Equal(result))
Expand Down
1 change: 1 addition & 0 deletions tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ go_test(
"//tests/framework:go_default_library",
"//tests/reporter:go_default_library",
"//tests/utils:go_default_library",
"//vendor/github.com/docker/go-units:go_default_library",
"//vendor/github.com/ghodss/yaml:go_default_library",
"//vendor/github.com/google/uuid:go_default_library",
"//vendor/github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumesnapshot/v1:go_default_library",
Expand Down
38 changes: 4 additions & 34 deletions tests/framework/pvc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"fmt"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -284,24 +283,15 @@ func (f *Framework) VerifyBlankDisk(namespace *k8sv1.Namespace, pvc *k8sv1.Persi
}

// VerifySparse checks a disk image being sparse after creation/resize.
func (f *Framework) VerifySparse(namespace *k8sv1.Namespace, pvc *k8sv1.PersistentVolumeClaim, imagePath string) (bool, error) {
func (f *Framework) VerifySparse(namespace *k8sv1.Namespace, pvc *k8sv1.PersistentVolumeClaim, imagePath string, originalVirtualSize int64) (bool, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not get rid of this function and check !VerifyImagePreallocated()?

Copy link
Collaborator Author

@akalenyu akalenyu Aug 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mainly because of the third point in the PR description

The third issue is that we almost always resize which results in significantly larger virtual size.
What we really care about is comparing against the original virtual size of the image.

We could get rid of one of them by negating the other but those additions have to stay

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What we really care about is comparing against the original virtual size of the image.

Why?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since current virtual size is post-resize you always end up comparing 1Gi or more (requested disk image size) versus a modest couple of megabytes, which is always going to pass as sort of a false negative

var info image.ImgInfo
var imageContentSize int64
err := f.GetImageInfo(namespace, pvc, imagePath, &info)
if err != nil {
return false, err
}
// qemu-img info gives us ActualSize but that is size on disk
// which isn't important to us in this comparison; we compare content size
err = f.GetImageContentSize(namespace, pvc, imagePath, &imageContentSize)
if err != nil {
return false, err
}
if info.ActualSize-imageContentSize >= units.MiB {
return false, fmt.Errorf("Diff between content size %d and size on disk %d is significant, something's not right", imageContentSize, info.ActualSize)
}
fmt.Fprintf(ginkgo.GinkgoWriter, "INFO: VerifySparse comparison: Virtual: %d vs Content: %d\n", info.VirtualSize, imageContentSize)
return info.VirtualSize >= imageContentSize, nil
fmt.Fprintf(ginkgo.GinkgoWriter, "INFO: VerifySparse comparison: OriginalVirtual: %d vs SizeOnDisk: %d\n", originalVirtualSize, info.ActualSize)
// The size on disk of a sparse image is significantly lower than the image's virtual size
return originalVirtualSize-info.ActualSize >= units.MB, nil
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably intentional but why use units.MB instead of the previously used MiB ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah intentional but it's been a while so I don't remember the exact reasoning, have to take a look

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the 1MB fudge factor all about?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its probably to ensure we align the size on 1Mib. qemu gets unhappy if the image is not aligned on the actual storage block size.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this check is a little too strict, wondering why current virtual size is not appropriate

Copy link
Collaborator Author

@akalenyu akalenyu Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I looked up the 1MiB->1MB switch.
It's because qemu-img convert only manages to shave off one megabyte (not mebi) for our test image
INFO: VerifySparse comparison: OriginalVirtual: 18874368 vs SizeOnDisk: 17829888

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this check is specific to a particular image?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you pass the virtual size of the used image as a parameter

}

// VerifyFSOverhead checks whether virtual size is smaller than actual size. That means FS Overhead has been accounted for.
Expand Down Expand Up @@ -548,26 +538,6 @@ func (f *Framework) GetImageInfo(namespace *k8sv1.Namespace, pvc *k8sv1.Persiste
return err
}

// GetImageContentSize returns the content size (as opposed to size on disk) of an image
func (f *Framework) GetImageContentSize(namespace *k8sv1.Namespace, pvc *k8sv1.PersistentVolumeClaim, imagePath string, imageSize *int64) error {
cmd := fmt.Sprintf("du -s --apparent-size -B 1 %s | cut -f 1", imagePath)

_, err := f.verifyInPod(namespace, pvc, cmd, func(output, stderr string) (bool, error) {
fmt.Fprintf(ginkgo.GinkgoWriter, "CMD (%s) output %s\n", cmd, output)

size, err := strconv.ParseInt(output, 10, 64)
if err != nil {
klog.Errorf("Invalid image content size:\n%s\n", output)
return false, err
}
*imageSize = size

return true, nil
})

return err
}

func (f *Framework) startVerifierPod(namespace *k8sv1.Namespace, pvc *k8sv1.PersistentVolumeClaim) (*k8sv1.Pod, error) {
var executorPod *k8sv1.Pod
var err error
Expand Down
46 changes: 28 additions & 18 deletions tests/import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"github.com/docker/go-units"
"github.com/google/uuid"

v1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -128,7 +129,7 @@ var _ = Describe("[rfe_id:1115][crit:high][vendor:[email protected]][level:compo
By("Verify the image contents")
Expect(f.VerifyBlankDisk(f.Namespace, pvc)).To(BeTrue())
By("Verifying the image is sparse")
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath)).To(BeTrue())
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath, utils.UploadFileSize)).To(BeTrue())
By("Verifying permissions are 660")
Expect(f.VerifyPermissions(f.Namespace, pvc)).To(BeTrue(), "Permissions on disk image are not 660")
if utils.DefaultStorageCSIRespectsFsGroup {
Expand Down Expand Up @@ -1636,7 +1637,11 @@ var _ = Describe("Import populator", func() {
tests.DisableWebhookPvcRendering(f.CrClient)
})

DescribeTable("should import fileSystem PVC", func(expectedMD5 string, volumeImportSourceFunc func(cdiv1.DataVolumeContentType, bool) error, preallocation, webhookRendering bool) {
DescribeTable("should import fileSystem PVC", func(expectedMD5 string, originalVirtualSize int, volumeImportSourceFunc func(cdiv1.DataVolumeContentType, bool) error, preallocation, webhookRendering bool) {
// ImageIO raw images are not passed through any sparsification mechanism
// VDDK ones do, but the fake plugin used for testing lies that they're not
skipSparseCheckIDs := []string{"[test_id:11007]", "[test_id:11009]"}

pvc = importPopulationPVCDefinition()

if webhookRendering {
Expand All @@ -1663,14 +1668,21 @@ var _ = Describe("Import populator", func() {
Expect(err).ToNot(HaveOccurred())
Expect(md5).To(Equal(expectedMD5))

var excluded bool
for _, id := range skipSparseCheckIDs {
if strings.Contains(CurrentSpecReport().LeafNodeText, id) {
excluded = true
break
}
}
if preallocation {
By("Verifying the image is preallocated")
ok, err := f.VerifyImagePreallocated(f.Namespace, pvc)
Expect(err).ToNot(HaveOccurred())
Expect(ok).To(BeTrue())
} else {
} else if !excluded {
By("Verifying the image is sparse")
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath)).To(BeTrue())
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath, int64(originalVirtualSize))).To(BeTrue())
}

if utils.DefaultStorageCSIRespectsFsGroup {
Expand All @@ -1695,17 +1707,17 @@ var _ = Describe("Import populator", func() {
return err != nil && k8serrors.IsNotFound(err)
}, timeout, pollingInterval).Should(BeTrue())
},
Entry("[test_id:11001]with HTTP image and preallocation", utils.TinyCoreMD5, createHTTPImportPopulatorCR, true, false),
Entry("[test_id:11002]with HTTP image without preallocation", utils.TinyCoreMD5, createHTTPImportPopulatorCR, false, false),
Entry("[rfe_id:10985][crit:high][test_id:11003]with HTTP image and preallocation, with incomplete PVC webhook rendering", Serial, utils.TinyCoreMD5, createHTTPImportPopulatorCR, true, true),
Entry("[test_id:11004]with Registry image and preallocation", utils.TinyCoreMD5, createRegistryImportPopulatorCR, true, false),
Entry("[test_id:11005]with Registry image without preallocation", utils.TinyCoreMD5, createRegistryImportPopulatorCR, false, false),
Entry("[test_id:11006]with ImageIO image with preallocation", Serial, utils.ImageioMD5, createImageIOImportPopulatorCR, true, false),
Entry("[test_id:11007]with ImageIO image without preallocation", Serial, utils.ImageioMD5, createImageIOImportPopulatorCR, false, false),
Entry("[test_id:11008]with VDDK image with preallocation", utils.VcenterMD5, createVDDKImportPopulatorCR, true, false),
Entry("[test_id:11009]with VDDK image without preallocation", utils.VcenterMD5, createVDDKImportPopulatorCR, false, false),
Entry("[test_id:11010]with Blank image with preallocation", utils.BlankMD5, createBlankImportPopulatorCR, true, false),
Entry("[test_id:11011]with Blank image without preallocation", utils.BlankMD5, createBlankImportPopulatorCR, false, false),
Entry("[test_id:11001]with HTTP image and preallocation", utils.TinyCoreMD5, utils.UploadFileSize, createHTTPImportPopulatorCR, true, false),
Entry("[test_id:11002]with HTTP image without preallocation", utils.TinyCoreMD5, utils.UploadFileSize, createHTTPImportPopulatorCR, false, false),
Entry("[rfe_id:10985][crit:high][test_id:11003]with HTTP image and preallocation, with incomplete PVC webhook rendering", Serial, utils.TinyCoreMD5, utils.UploadFileSize, createHTTPImportPopulatorCR, true, true),
Entry("[test_id:11004]with Registry image and preallocation", utils.TinyCoreMD5, utils.UploadFileSize, createRegistryImportPopulatorCR, true, false),
Entry("[test_id:11005]with Registry image without preallocation", utils.TinyCoreMD5, utils.UploadFileSize, createRegistryImportPopulatorCR, false, false),
Entry("[test_id:11006]with ImageIO image with preallocation", Serial, utils.ImageioMD5, utils.CirrosRawFileSize, createImageIOImportPopulatorCR, true, false),
Entry("[test_id:11007]with ImageIO image without preallocation", Serial, utils.ImageioMD5, utils.CirrosRawFileSize, createImageIOImportPopulatorCR, false, false),
Entry("[test_id:11008]with VDDK image with preallocation", utils.VcenterMD5, utils.CirrosRawFileSize, createVDDKImportPopulatorCR, true, false),
Entry("[test_id:11009]with VDDK image without preallocation", utils.VcenterMD5, utils.CirrosRawFileSize, createVDDKImportPopulatorCR, false, false),
Entry("[test_id:11010]with Blank image with preallocation", utils.BlankMD5, units.MiB, createBlankImportPopulatorCR, true, false),
Entry("[test_id:11011]with Blank image without preallocation", utils.BlankMD5, units.MiB, createBlankImportPopulatorCR, false, false),
)

DescribeTable("should import Block PVC", func(expectedMD5 string, volumeImportSourceFunc func(cdiv1.DataVolumeContentType, bool) error) {
Expand Down Expand Up @@ -1733,7 +1745,7 @@ var _ = Describe("Import populator", func() {
Expect(err).ToNot(HaveOccurred())
Expect(md5).To(Equal(expectedMD5))
By("Verifying the image is sparse")
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultPvcMountPath)).To(BeTrue())
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultPvcMountPath, utils.UploadFileSize)).To(BeTrue())

By("Verify 100.0% annotation")
progress, ok, err := utils.WaitForPVCAnnotation(f.K8sClient, f.Namespace.Name, pvc, controller.AnnPopulatorProgress)
Expand Down Expand Up @@ -1809,8 +1821,6 @@ var _ = Describe("Import populator", func() {
md5, err := f.GetMD5(f.Namespace, pvc, utils.DefaultImagePath, utils.MD5PrefixSize)
Expect(err).ToNot(HaveOccurred())
Expect(md5).To(Equal(utils.TinyCoreMD5))
By("Verifying the image is sparse")
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath)).To(BeTrue())
sourceMD5 := md5

By("Retaining PV")
Expand Down
2 changes: 1 addition & 1 deletion tests/transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ var _ = Describe("Transport Tests", func() {
}
}
By("Verifying the image is sparse")
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath)).To(BeTrue())
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath, utils.UploadFileSize)).To(BeTrue())
} else {
By("Verify PVC status annotation says failed")
found, err := utils.WaitPVCPodStatusRunning(f.K8sClient, pvc)
Expand Down
10 changes: 3 additions & 7 deletions tests/upload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ var _ = Describe("[rfe_id:138][crit:high][vendor:[email protected]][level:compon
Expect(err).ToNot(HaveOccurred())
Expect(same).To(BeTrue())
By("Verifying the image is sparse")
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath)).To(BeTrue())
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath, utils.UploadFileSize)).To(BeTrue())
if utils.DefaultStorageCSIRespectsFsGroup {
// CSI storage class, it should respect fsGroup
By("Checking that disk image group is qemu")
Expand Down Expand Up @@ -413,8 +413,6 @@ var _ = Describe("[rfe_id:138][crit:high][vendor:[email protected]][level:compon
same, err := f.VerifyTargetPVCContentMD5(f.Namespace, archivePVC, pathInPvc, expectedMd5)
Expect(err).ToNot(HaveOccurred())
Expect(same).To(BeTrue())
By("Verifying the image is sparse")
Expect(f.VerifySparse(f.Namespace, archivePVC, pathInPvc)).To(BeTrue())
}
} else {
checkFailureNoValidToken(archivePVC)
Expand Down Expand Up @@ -529,7 +527,7 @@ var _ = Describe("[rfe_id:138][crit:high][vendor:[email protected]][level:compon
Expect(err).ToNot(HaveOccurred())
Expect(same).To(BeTrue())
By("Verifying the image is sparse")
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath)).To(BeTrue())
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath, utils.UploadFileSize)).To(BeTrue())
if utils.DefaultStorageCSIRespectsFsGroup {
// CSI storage class, it should respect fsGroup
By("Checking that disk image group is qemu")
Expand Down Expand Up @@ -603,7 +601,7 @@ var _ = Describe("[rfe_id:138][crit:high][vendor:[email protected]][level:compon
Expect(err).ToNot(HaveOccurred())
Expect(same).To(BeTrue())
By("Verifying the image is sparse")
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath)).To(BeTrue())
Expect(f.VerifySparse(f.Namespace, pvc, utils.DefaultImagePath, utils.UploadFileSize)).To(BeTrue())
if utils.DefaultStorageCSIRespectsFsGroup {
// CSI storage class, it should respect fsGroup
By("Checking that disk image group is qemu")
Expand Down Expand Up @@ -733,8 +731,6 @@ var _ = Describe("[rfe_id:138][crit:high][vendor:[email protected]][level:compon
same, err := f.VerifyTargetPVCContentMD5(f.Namespace, pvc, pathInPvc, expectedMd5)
Expect(err).ToNot(HaveOccurred())
Expect(same).To(BeTrue())
By("Verifying the image is sparse")
Expect(f.VerifySparse(f.Namespace, pvc, pathInPvc)).To(BeTrue())
}
} else {
checkFailureNoValidToken(pvcPrime)
Expand Down
2 changes: 2 additions & 0 deletions tests/utils/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const (

// UploadFileSize is the size of UploadFile
UploadFileSize = 18874368
// CirrosRawFileSize is the size of cirros.raw
CirrosRawFileSize = 46137344

// UploadFileMD5 is the expected MD5 of the uploaded file
UploadFileMD5 = "2a7a52285c846314d1dbd79e9818270d"
Expand Down