diff --git a/tests/upload_test.go b/tests/upload_test.go index 44c27bd8ab..ba8d5d2ee4 100644 --- a/tests/upload_test.go +++ b/tests/upload_test.go @@ -9,7 +9,6 @@ import ( "net/http" "os" "os/exec" - "reflect" "strconv" "time" @@ -19,6 +18,7 @@ import ( v1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" + apiequality "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cdiv1 "kubevirt.io/containerized-data-importer/pkg/apis/core/v1beta1" @@ -275,6 +275,11 @@ func binaryRequestFunc(url, fileName string) (*http.Request, error) { return req, nil } +// XXX todo +//func uploadImageFile(portForwardURL, token, string, expectedStatus int) { +// return uploadFileNameToPath(binaryRequestFunc, utils.UploadFile, portForwardURL, syncUploadPath, token, expectedStatus) +//} + func uploadImage(portForwardURL, token string, expectedStatus int) error { return uploadFileNameToPath(binaryRequestFunc, utils.UploadFile, portForwardURL, syncUploadPath, token, expectedStatus) } @@ -425,19 +430,20 @@ var _ = Describe("Block PV upload Test", func() { ) }) -var _ = Describe("Namespace with quota", func() { +var _ = Describe("CDIConfig manipulation upload tests", func() { f := framework.NewFramework(namespacePrefix) var ( - orgConfig *v1.ResourceRequirements + origSpec *cdiv1.CDIConfigSpec pvc *v1.PersistentVolumeClaim portForwardCmd *exec.Cmd + uploadProxyURL string ) BeforeEach(func() { By("Capturing original CDIConfig state") config, err := f.CdiClient.CdiV1beta1().CDIConfigs().Get(context.TODO(), common.ConfigName, metav1.GetOptions{}) Expect(err).ToNot(HaveOccurred()) - orgConfig = config.Spec.PodResourceRequirements.DeepCopy() + origSpec = config.Spec.DeepCopy() if pvc != nil { By("Making sure no pvc exists") Eventually(func() bool { @@ -446,20 +452,26 @@ var _ = Describe("Namespace with quota", func() { return err != nil }, timeout, pollingInterval).Should(BeTrue()) } + + By("Set up port forwarding") + uploadProxyURL, portForwardCmd, err = startUploadProxyPortForward(f) + Expect(err).ToNot(HaveOccurred()) }) AfterEach(func() { By("Restoring CDIConfig to original state") config, err := f.CdiClient.CdiV1beta1().CDIConfigs().Get(context.TODO(), common.ConfigName, metav1.GetOptions{}) Expect(err).ToNot(HaveOccurred()) - config.Spec.PodResourceRequirements = orgConfig + config.Spec = *origSpec _, err = f.CdiClient.CdiV1beta1().CDIConfigs().Update(context.TODO(), config, metav1.UpdateOptions{}) Eventually(func() bool { config, err := f.CdiClient.CdiV1beta1().CDIConfigs().Get(context.TODO(), common.ConfigName, metav1.GetOptions{}) Expect(err).ToNot(HaveOccurred()) - return reflect.DeepEqual(config.Spec.PodResourceRequirements, orgConfig) + return apiequality.Semantic.DeepEqual(config.Spec, *origSpec) }, timeout, pollingInterval).Should(BeTrue(), "CDIConfig not properly restored to original value") + By(fmt.Sprintf("config spec is now %v\n filesystem overhead is %v\n", config.Spec, config.Spec.FilesystemOverhead)) + Expect(err).ToNot(HaveOccurred()) By("Stop port forwarding") if portForwardCmd != nil { @@ -565,6 +577,67 @@ var _ = Describe("Namespace with quota", func() { Expect(err).ToNot(HaveOccurred()) Expect(token).ToNot(BeEmpty()) }) + + FDescribeTable("Upload with filesystem overhead", func(expectedStatus int, globalOverhead, scOverhead string) { + testedFilesystemOverhead := &cdiv1.FilesystemOverhead{} + if globalOverhead != "" { + testedFilesystemOverhead.Global = cdiv1.Percent(globalOverhead) + } + if scOverhead != "" { + defaultSCName := utils.DefaultStorageClass.GetName() + testedFilesystemOverhead.StorageClass = map[string]cdiv1.Percent{ defaultSCName: cdiv1.Percent(scOverhead) } + } + config, err := f.CdiClient.CdiV1beta1().CDIConfigs().Get(context.TODO(), common.ConfigName, metav1.GetOptions{}) + Expect(err).ToNot(HaveOccurred()) + config.Spec.FilesystemOverhead = testedFilesystemOverhead.DeepCopy() + By(fmt.Sprintf("Updating CDIConfig filesystem overhead to %v", config.Spec.FilesystemOverhead)) + _, err = f.CdiClient.CdiV1beta1().CDIConfigs().Update(context.TODO(), config, metav1.UpdateOptions{}) + Expect(err).ToNot(HaveOccurred()) + By(fmt.Sprintf("Waiting for filsystem overhead to be set to %v", testedFilesystemOverhead)) + Eventually(func() bool { + config, err := f.CdiClient.CdiV1beta1().CDIConfigs().Get(context.TODO(), common.ConfigName, metav1.GetOptions{}) + Expect(err).ToNot(HaveOccurred()) + By(fmt.Sprintf("CDIConfig spec filesystem looks like: %v", *config.Spec.FilesystemOverhead)) + By(fmt.Sprintf("Hoping it looks like: %v", *testedFilesystemOverhead)) + return apiequality.Semantic.DeepEqual(*config.Status.FilesystemOverhead, *testedFilesystemOverhead) + }, timeout, pollingInterval).Should(BeTrue(), "CDIConfig filesystem overhead wasn't set") + + dvName := "upload-dv" + By(fmt.Sprintf("Creating new datavolume %s", dvName)) + dv := utils.NewDataVolumeForUpload(dvName, "100Mi") + dataVolume, err := utils.CreateDataVolumeFromDefinition(f.CdiClient, f.Namespace.Name, dv) + pvc = utils.PersistentVolumeClaimFromDataVolume(dataVolume) + + By("verifying pvc was created, force bind if needed") + pvc, err := utils.WaitForPVC(f.K8sClient, pvc.Namespace, pvc.Name) + Expect(err).ToNot(HaveOccurred()) + f.ForceBindIfWaitForFirstConsumer(pvc) + + phase := cdiv1.UploadReady + By(fmt.Sprintf("Waiting for datavolume to match phase %s", string(phase))) + err = utils.WaitForDataVolumePhase(f.CdiClient, f.Namespace.Name, phase, dataVolume.Name) + if err != nil { + dv, dverr := f.CdiClient.CdiV1beta1().DataVolumes(f.Namespace.Name).Get(context.TODO(), dataVolume.Name, metav1.GetOptions{}) + if dverr != nil { + Fail(fmt.Sprintf("datavolume %s phase %s", dv.Name, dv.Status.Phase)) + } + } + Expect(err).ToNot(HaveOccurred()) + + By("Get an upload token") + token, err := utils.RequestUploadToken(f.CdiClient, pvc) + Expect(err).ToNot(HaveOccurred()) + Expect(token).ToNot(BeEmpty()) + + By("Do upload") + err = uploadImageAsync(uploadProxyURL, token, expectedStatus) + Expect(err).ToNot(HaveOccurred()) + }, + Entry("Succeed with low global overhead", http.StatusOK, "0.1", ""), + Entry("Fail with high global overhead", http.StatusBadRequest, "0.99", ""), + FEntry("Succeed with low per-storageclass overhead", http.StatusOK, "", "0.1"), + Entry("Fail with high per-storageclass overhead", http.StatusBadRequest, "", "0.99"), + ) }) var _ = Describe("[rfe_id:138][crit:high][vendor:cnv-qe@redhat.com][level:component] Upload tests", func() {