<commit_before>/*
 * This file is part of the KubeVirt project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Copyright 2017 Red Hat, Inc.
 *
 */

package storage

import (
	"context"
	"fmt"
	"math"
	"strings"
	"time"

	expect "github.com/google/goexpect"
	storagev1 "k8s.io/api/storage/v1"

	. "github.com/onsi/ginkgo/v2"
	. "github.com/onsi/gomega"
	k8sv1 "k8s.io/api/core/v1"
	rbacv1 "k8s.io/api/rbac/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/rand"
	"k8s.io/utils/pointer"

	v1 "kubevirt.io/api/core/v1"
	"kubevirt.io/client-go/kubecli"
	cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1"
	virtconfig "kubevirt.io/kubevirt/pkg/virt-config"
	"kubevirt.io/kubevirt/tests"
	"kubevirt.io/kubevirt/tests/console"
	cd "kubevirt.io/kubevirt/tests/containerdisk"
	"kubevirt.io/kubevirt/tests/flags"
	"kubevirt.io/kubevirt/tests/framework/checks"
	. "kubevirt.io/kubevirt/tests/framework/matcher"
	"kubevirt.io/kubevirt/tests/util"
)

const (
	checkingVMInstanceConsoleExpectedOut = "Checking that the VirtualMachineInstance console has expected output"
	deletingDataVolume                   = "Deleting the DataVolume"
	creatingVMInvalidDataVolume          = "Creating a VM with an invalid DataVolume"
	creatingVMDataVolumeTemplateEntry    = "Creating VM with DataVolumeTemplate entry with k8s client binary"
	verifyingDataVolumeSuccess           = "Verifying DataVolume succeeded and is created with VM owner reference"
	verifyingPVCCreated                  = "Verifying PVC is created"
	verifyingVMICreated                  = "Verifying VMI is created with VM owner reference"
	syncName                             = "sync\n"
)

const InvalidDataVolumeUrl = "docker://127.0.0.1/invalid:latest"

var _ = SIGDescribe("DataVolume Integration", func() {

	var virtClient kubecli.KubevirtClient
	var err error

	BeforeEach(func() {
		virtClient, err = kubecli.GetKubevirtClient()
		util.PanicOnError(err)

		tests.BeforeTestCleanup()
		if !tests.HasCDI() {
			Skip("Skip DataVolume tests when CDI is not present")
		}
	})

	Context("[storage-req]PVC expansion", func() {
		DescribeTable("PVC expansion is detected by VM and can be fully used", func(volumeMode k8sv1.PersistentVolumeMode) {
			checks.SkipTestIfNoFeatureGate(virtconfig.ExpandDisksGate)
			if !tests.HasCDI() {
				Skip("Skip DataVolume tests when CDI is not present")
			}
			var sc string
			exists := false
			if volumeMode == k8sv1.PersistentVolumeBlock {
				sc, exists = tests.GetRWOBlockStorageClass()
				if !exists {
					Skip("Skip test when Block storage is not present")
				}
			} else {
				sc, exists = tests.GetRWOFileSystemStorageClass()
				if !exists {
					Skip("Skip test when Filesystem storage is not present")
				}
			}
			volumeExpansionAllowed := tests.VolumeExpansionAllowed(sc)
			if !volumeExpansionAllowed {
				Skip("Skip when volume expansion storage class not available")
			}
			vmi, dataVolume := tests.NewRandomVirtualMachineInstanceWithDisk(cd.DataVolumeImportUrlForContainerDisk(cd.ContainerDiskCirros), util.NamespaceTestDefault, sc, k8sv1.ReadWriteOnce, volumeMode)
			tests.AddUserData(vmi, "cloud-init", "#!/bin/bash\necho 'hello'\n")
			vmi = tests.RunVMIAndExpectLaunch(vmi, 500)

			By("Expecting the VirtualMachineInstance console")
			Expect(console.LoginToCirros(vmi)).To(Succeed())

			pvc, err := virtClient.CoreV1().PersistentVolumeClaims(util.NamespaceTestDefault).Get(context.Background(), dataVolume.Name, metav1.GetOptions{})
			Expect(err).ToNot(HaveOccurred())

			By("Expanding PVC")
			pvc.Spec.Resources.Requests[k8sv1.ResourceStorage] = resource.MustParse("2Gi")
			_, err = virtClient.CoreV1().PersistentVolumeClaims(util.NamespaceTestDefault).Update(context.Background(), pvc, metav1.UpdateOptions{})
			Expect(err).ToNot(HaveOccurred())

			By("Waiting for notification about size change")
			Eventually(func() error {
				err := console.SafeExpectBatch(vmi, []expect.Batcher{
					&expect.BSnd{S: "\n"},
					&expect.BExp{R: console.PromptExpression},
					&expect.BSnd{S: "dmesg |grep 'new size'\n"},
					&expect.BExp{R: console.PromptExpression},
					&expect.BSnd{S: "dmesg |grep -c 'new size: [34]'\n"},
					&expect.BExp{R: "1"},
				}, 10)
				return err
			}, 360).Should(BeNil())

			Expect(console.SafeExpectBatch(vmi, []expect.Batcher{
				&expect.BSnd{S: "sudo /sbin/resize-filesystem /dev/root /run/resize.rootfs /dev/console && echo $?\n"},
				&expect.BExp{R: "0"},
			}, 30)).To(Succeed(), "failed to resize root")

			By("Writing a 1.5G file after expansion, should succeed")
			Expect(console.SafeExpectBatch(vmi, []expect.Batcher{
				&expect.BSnd{S: "\n"},
				&expect.BExp{R: console.PromptExpression},
				&expect.BSnd{S: "dd if=/dev/zero of=largefile count=1500 bs=1M; echo $?\n"},
				&expect.BExp{R: "0"},
			}, 360)).To(Succeed(), "can use more space after expansion and resize")
		},
			Entry("with Block PVC", k8sv1.PersistentVolumeBlock),
			Entry("with Filesystem PVC", k8sv1.PersistentVolumeFilesystem),
		)
	})

	Describe("[rfe_id:3188][crit:high][vendor:<EMAIL>][level:system] Starting a VirtualMachineInstance with a DataVolume as a volume source", func() {

		Context("[Serial]without fsgroup support", func() {
			size := "1Gi"

			It("should succesfully start", func() {
				// Create DV and alter permission of disk.img
				url := "docker://" + cd.ContainerDiskFor(cd.ContainerDiskAlpine)
				dv := tests.NewRandomDataVolumeWithRegistryImport(url, util.NamespaceTestDefault, k8sv1.ReadWriteMany)
				tests.SetDataVolumeForceBindAnnotation(dv)
				dv.Spec.PVC.Resources.Requests["storage"] = resource.MustParse(size)
				_, err := virtClient.CdiClient().CdiV1beta1().DataVolumes(dv.Namespace).Create(context.Background(), dv, metav1.CreateOptions{})
				Expect(err).To(BeNil())
				var pvc *k8sv1.PersistentVolumeClaim
				Eventually(func() *k8sv1.PersistentVolumeClaim {
					pvc, err = virtClient.CoreV1().PersistentVolumeClaims(dv.Namespace).Get(context.Background(), dv.Name, metav1.GetOptions{})
					if err != nil {
						return nil
					}
					return pvc
				}, 30*time.Second).Should(Not(BeNil()))
				By("waiting for the dv import to pvc to finish")
				Eventually(ThisDV(dv), 180*time.Second).Should(HaveSucceeded())
				tests.ChangeImgFilePermissionsToNonQEMU(pvc)

				vmi := tests.NewRandomVMIWithDataVolume(dv.Name)

				By("Starting the VirtualMachineInstance")
				vmi = tests.RunVMIAndExpectLaunch(vmi, 120)

				By(checkingVMInstanceConsoleExpectedOut)
				Expect(console.LoginToAlpine(vmi)).To(Succeed())
			})
		})

		Context("Alpine import", func() {
			BeforeEach(func() {
				cdis, err := virtClient.CdiClient().CdiV1beta1().CDIs().List(context.Background(), metav1.ListOptions{})
				Expect(err).ToNot(HaveOccurred())
				Expect(cdis.Items).To(HaveLen(1))
				hasWaitForFirstConsumerGate := false
				for _, feature := range cdis.Items[0].Spec.Config.FeatureGates {
					if feature == "HonorWaitForFirstConsumer" {
						hasWaitForFirstConsumerGate = true
						break
					}
				}
				if !hasWaitForFirstConsumerGate {
					Skip("HonorWaitForFirstConsumer is disabled in CDI, skipping tests relying on it")
				}
			})

			It("[test_id:3189]should be successfully started and stopped multiple times", func() {

				dataVolume := tests.NewRandomDataVolumeWithRegistryImport(cd.DataVolumeImportUrlForContainerDisk(cd.ContainerDiskAlpine), util.NamespaceTestDefault, k8sv1.ReadWriteOnce)
				vmi := tests.NewRandomVMIWithDataVolume(dataVolume.Name)

				_, err := virtClient.CdiClient().CdiV1beta1().DataVolumes(dataVolume.Namespace).Create(context.Background(), dataVolume, metav1.CreateOptions{})
				Expect(err).To(BeNil())

				// This will only work on storage with binding mode WaitForFirstConsumer,
				if tests.IsStorageClassBindingModeWaitForFirstConsumer(tests.Config.StorageRWOFileSystem) {
					Eventually(ThisDV(dataVolume), 30).Should(BeInPhase(cdiv1.WaitForFirstConsumer))
				}
				num := 2
				By("Starting and stopping the VirtualMachineInstance a number of times")
				for i := 1; i <= num; i++ {
					vmi := tests.RunVMIAndExpectLaunchWithDataVolume(vmi, dataVolume, 500)
					// Verify console on last iteration to verify the VirtualMachineInstance is still booting properly
					// after being restarted multiple times
					if i == num {
						By(checkingVMInstanceConsoleExpectedOut)
						Expect(console.LoginToAlpine(vmi)).To(Succeed())
					}

					err = virtClient.VirtualMachineInstance(vmi.Namespace).Delete(vmi.Name, &metav1.DeleteOptions{})
					Expect(err).To(BeNil())
					tests.WaitForVirtualMachineToDisappearWithTimeout(vmi, 120)
				}
				err = virtClient.CdiClient().CdiV1beta1().DataVolumes(dataVolume.Namespace).Delete(context.Background(), dataVolume.Name, metav1.DeleteOptions{})
				Expect(err).To(BeNil())
			})

			It("[test_id:6686]should successfully start multiple concurrent VMIs", func() {

				numVmis := 5
				vmis := make([]*v1.VirtualMachineInstance, 0, numVmis)
				dvs := make([]*cdiv1.DataVolume, 0, numVmis)

				for idx := 0; idx < numVmis; idx++ {
					dataVolume := tests.NewRandomDataVolumeWithRegistryImport(cd.DataVolumeImportUrlForContainerDisk(cd.ContainerDiskAlpine), util.NamespaceTestDefault, k8sv1.ReadWriteOnce)
					vmi := tests.NewRandomVMIWithDataVolume(dataVolume.Name)

					_, err := virtClient.CdiClient().CdiV1beta1().DataVolumes(dataVolume.Namespace).Create(context.Background(), dataVolume, metav1.CreateOptions{})
					Expect(err).To(BeNil())

					vmi = tests.RunVMI(vmi, 60)
					vmis = append(vmis, vmi)
					dvs = append(dvs, dataVolume)
				}

				for idx := 0; idx < numVmis; idx++ {
					tests.WaitForSuccessfulVMIStartWithTimeoutIgnoreWarnings(vmis[idx], 500)
					By(checkingVMInstanceConsoleExpectedOut)
					Expect(console.LoginToAlpine(vmis[idx])).To(Succeed())

					err := virtClient.VirtualMachineInstance(vmis[idx].Namespace).Delete(vmis[idx].Name, &metav1.DeleteOptions{})
					Expect(err).To(BeNil())
					err = virtClient.CdiClient().CdiV1beta1().DataVolumes(dvs[idx].Namespace).Delete(context.Background(), dvs[idx].Name, metav1.DeleteOptions{})
					Expect(err).To(BeNil())
				}
			})<commit_msg>Fix flaky test with concurrent VMIs<commit_after>/*
 * This file is part of the KubeVirt project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Copyright 2017 Red Hat, Inc.
 *
 */

package storage

import (
	"context"
	"fmt"
	"math"
	"strings"
	"time"

	expect "github.com/google/goexpect"
	storagev1 "k8s.io/api/storage/v1"

	. "github.com/onsi/ginkgo/v2"
	. "github.com/onsi/gomega"
	k8sv1 "k8s.io/api/core/v1"
	rbacv1 "k8s.io/api/rbac/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/rand"
	"k8s.io/utils/pointer"

	v1 "kubevirt.io/api/core/v1"
	"kubevirt.io/client-go/kubecli"
	cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1"
	virtconfig "kubevirt.io/kubevirt/pkg/virt-config"
	"kubevirt.io/kubevirt/tests"
	"kubevirt.io/kubevirt/tests/console"
	cd "kubevirt.io/kubevirt/tests/containerdisk"
	"kubevirt.io/kubevirt/tests/flags"
	"kubevirt.io/kubevirt/tests/framework/checks"
	. "kubevirt.io/kubevirt/tests/framework/matcher"
	"kubevirt.io/kubevirt/tests/util"
)

const (
	checkingVMInstanceConsoleExpectedOut = "Checking that the VirtualMachineInstance console has expected output"
	deletingDataVolume                   = "Deleting the DataVolume"
	creatingVMInvalidDataVolume          = "Creating a VM with an invalid DataVolume"
	creatingVMDataVolumeTemplateEntry    = "Creating VM with DataVolumeTemplate entry with k8s client binary"
	verifyingDataVolumeSuccess           = "Verifying DataVolume succeeded and is created with VM owner reference"
	verifyingPVCCreated                  = "Verifying PVC is created"
	verifyingVMICreated                  = "Verifying VMI is created with VM owner reference"
	syncName                             = "sync\n"
)

const InvalidDataVolumeUrl = "docker://127.0.0.1/invalid:latest"

var _ = SIGDescribe("DataVolume Integration", func() {

	var virtClient kubecli.KubevirtClient
	var err error

	BeforeEach(func() {
		virtClient, err = kubecli.GetKubevirtClient()
		util.PanicOnError(err)

		tests.BeforeTestCleanup()
		if !tests.HasCDI() {
			Skip("Skip DataVolume tests when CDI is not present")
		}
	})

	Context("[storage-req]PVC expansion", func() {
		DescribeTable("PVC expansion is detected by VM and can be fully used", func(volumeMode k8sv1.PersistentVolumeMode) {
			checks.SkipTestIfNoFeatureGate(virtconfig.ExpandDisksGate)
			if !tests.HasCDI() {
				Skip("Skip DataVolume tests when CDI is not present")
			}
			var sc string
			exists := false
			if volumeMode == k8sv1.PersistentVolumeBlock {
				sc, exists = tests.GetRWOBlockStorageClass()
				if !exists {
					Skip("Skip test when Block storage is not present")
				}
			} else {
				sc, exists = tests.GetRWOFileSystemStorageClass()
				if !exists {
					Skip("Skip test when Filesystem storage is not present")
				}
			}
			volumeExpansionAllowed := tests.VolumeExpansionAllowed(sc)
			if !volumeExpansionAllowed {
				Skip("Skip when volume expansion storage class not available")
			}
			vmi, dataVolume := tests.NewRandomVirtualMachineInstanceWithDisk(cd.DataVolumeImportUrlForContainerDisk(cd.ContainerDiskCirros), util.NamespaceTestDefault, sc, k8sv1.ReadWriteOnce, volumeMode)
			tests.AddUserData(vmi, "cloud-init", "#!/bin/bash\necho 'hello'\n")
			vmi = tests.RunVMIAndExpectLaunch(vmi, 500)

			By("Expecting the VirtualMachineInstance console")
			Expect(console.LoginToCirros(vmi)).To(Succeed())

			pvc, err := virtClient.CoreV1().PersistentVolumeClaims(util.NamespaceTestDefault).Get(context.Background(), dataVolume.Name, metav1.GetOptions{})
			Expect(err).ToNot(HaveOccurred())

			By("Expanding PVC")
			pvc.Spec.Resources.Requests[k8sv1.ResourceStorage] = resource.MustParse("2Gi")
			_, err = virtClient.CoreV1().PersistentVolumeClaims(util.NamespaceTestDefault).Update(context.Background(), pvc, metav1.UpdateOptions{})
			Expect(err).ToNot(HaveOccurred())

			By("Waiting for notification about size change")
			Eventually(func() error {
				err := console.SafeExpectBatch(vmi, []expect.Batcher{
					&expect.BSnd{S: "\n"},
					&expect.BExp{R: console.PromptExpression},
					&expect.BSnd{S: "dmesg |grep 'new size'\n"},
					&expect.BExp{R: console.PromptExpression},
					&expect.BSnd{S: "dmesg |grep -c 'new size: [34]'\n"},
					&expect.BExp{R: "1"},
				}, 10)
				return err
			}, 360).Should(BeNil())

			Expect(console.SafeExpectBatch(vmi, []expect.Batcher{
				&expect.BSnd{S: "sudo /sbin/resize-filesystem /dev/root /run/resize.rootfs /dev/console && echo $?\n"},
				&expect.BExp{R: "0"},
			}, 30)).To(Succeed(), "failed to resize root")

			By("Writing a 1.5G file after expansion, should succeed")
			Expect(console.SafeExpectBatch(vmi, []expect.Batcher{
				&expect.BSnd{S: "\n"},
				&expect.BExp{R: console.PromptExpression},
				&expect.BSnd{S: "dd if=/dev/zero of=largefile count=1500 bs=1M; echo $?\n"},
				&expect.BExp{R: "0"},
			}, 360)).To(Succeed(), "can use more space after expansion and resize")
		},
			Entry("with Block PVC", k8sv1.PersistentVolumeBlock),
			Entry("with Filesystem PVC", k8sv1.PersistentVolumeFilesystem),
		)
	})

	Describe("[rfe_id:3188][crit:high][vendor:<EMAIL>][level:system] Starting a VirtualMachineInstance with a DataVolume as a volume source", func() {

		Context("[Serial]without fsgroup support", func() {
			size := "1Gi"

			It("should succesfully start", func() {
				// Create DV and alter permission of disk.img
				url := "docker://" + cd.ContainerDiskFor(cd.ContainerDiskAlpine)
				dv := tests.NewRandomDataVolumeWithRegistryImport(url, util.NamespaceTestDefault, k8sv1.ReadWriteMany)
				tests.SetDataVolumeForceBindAnnotation(dv)
				dv.Spec.PVC.Resources.Requests["storage"] = resource.MustParse(size)
				_, err := virtClient.CdiClient().CdiV1beta1().DataVolumes(dv.Namespace).Create(context.Background(), dv, metav1.CreateOptions{})
				Expect(err).To(BeNil())
				var pvc *k8sv1.PersistentVolumeClaim
				Eventually(func() *k8sv1.PersistentVolumeClaim {
					pvc, err = virtClient.CoreV1().PersistentVolumeClaims(dv.Namespace).Get(context.Background(), dv.Name, metav1.GetOptions{})
					if err != nil {
						return nil
					}
					return pvc
				}, 30*time.Second).Should(Not(BeNil()))
				By("waiting for the dv import to pvc to finish")
				Eventually(ThisDV(dv), 180*time.Second).Should(HaveSucceeded())
				tests.ChangeImgFilePermissionsToNonQEMU(pvc)

				vmi := tests.NewRandomVMIWithDataVolume(dv.Name)

				By("Starting the VirtualMachineInstance")
				vmi = tests.RunVMIAndExpectLaunch(vmi, 120)

				By(checkingVMInstanceConsoleExpectedOut)
				Expect(console.LoginToAlpine(vmi)).To(Succeed())
			})
		})

		Context("Alpine import", func() {
			BeforeEach(func() {
				cdis, err := virtClient.CdiClient().CdiV1beta1().CDIs().List(context.Background(), metav1.ListOptions{})
				Expect(err).ToNot(HaveOccurred())
				Expect(cdis.Items).To(HaveLen(1))
				hasWaitForFirstConsumerGate := false
				for _, feature := range cdis.Items[0].Spec.Config.FeatureGates {
					if feature == "HonorWaitForFirstConsumer" {
						hasWaitForFirstConsumerGate = true
						break
					}
				}
				if !hasWaitForFirstConsumerGate {
					Skip("HonorWaitForFirstConsumer is disabled in CDI, skipping tests relying on it")
				}
			})

			It("[test_id:3189]should be successfully started and stopped multiple times", func() {

				dataVolume := tests.NewRandomDataVolumeWithRegistryImport(cd.DataVolumeImportUrlForContainerDisk(cd.ContainerDiskAlpine), util.NamespaceTestDefault, k8sv1.ReadWriteOnce)
				vmi := tests.NewRandomVMIWithDataVolume(dataVolume.Name)

				_, err := virtClient.CdiClient().CdiV1beta1().DataVolumes(dataVolume.Namespace).Create(context.Background(), dataVolume, metav1.CreateOptions{})
				Expect(err).To(BeNil())

				// This will only work on storage with binding mode WaitForFirstConsumer,
				if tests.IsStorageClassBindingModeWaitForFirstConsumer(tests.Config.StorageRWOFileSystem) {
					Eventually(ThisDV(dataVolume), 30).Should(BeInPhase(cdiv1.WaitForFirstConsumer))
				}
				num := 2
				By("Starting and stopping the VirtualMachineInstance a number of times")
				for i := 1; i <= num; i++ {
					vmi := tests.RunVMIAndExpectLaunchWithDataVolume(vmi, dataVolume, 500)
					// Verify console on last iteration to verify the VirtualMachineInstance is still booting properly
					// after being restarted multiple times
					if i == num {
						By(checkingVMInstanceConsoleExpectedOut)
						Expect(console.LoginToAlpine(vmi)).To(Succeed())
					}

					err = virtClient.VirtualMachineInstance(vmi.Namespace).Delete(vmi.Name, &metav1.DeleteOptions{})
					Expect(err).To(BeNil())
					tests.WaitForVirtualMachineToDisappearWithTimeout(vmi, 120)
				}
				err = virtClient.CdiClient().CdiV1beta1().DataVolumes(dataVolume.Namespace).Delete(context.Background(), dataVolume.Name, metav1.DeleteOptions{})
				Expect(err).To(BeNil())
			})

			It("[test_id:6686]should successfully start multiple concurrent VMIs", func() {

				numVmis := 5
				vmis := make([]*v1.VirtualMachineInstance, 0, numVmis)
				dvs := make([]*cdiv1.DataVolume, 0, numVmis)

				for idx := 0; idx < numVmis; idx++ {
					dataVolume := tests.NewRandomDataVolumeWithRegistryImport(cd.DataVolumeImportUrlForContainerDisk(cd.ContainerDiskAlpine), util.NamespaceTestDefault, k8sv1.ReadWriteOnce)
					vmi := tests.NewRandomVMIWithDataVolume(dataVolume.Name)
					vmi.Spec.Domain.Resources.Requests[k8sv1.ResourceMemory] = resource.MustParse("128Mi")

					_, err := virtClient.CdiClient().CdiV1beta1().DataVolumes(dataVolume.Namespace).Create(context.Background(), dataVolume, metav1.CreateOptions{})
					Expect(err).To(BeNil())

					vmi = tests.RunVMI(vmi, 60)
					vmis = append(vmis, vmi)
					dvs = append(dvs, dataVolume)
				}

				for idx := 0; idx < numVmis; idx++ {
					tests.WaitForSuccessfulVMIStartWithTimeoutIgnoreWarnings(vmis[idx], 500)
					By(checkingVMInstanceConsoleExpectedOut)
					Expect(console.LoginToAlpine(vmis[idx])).To(Succeed())

					err := virtClient.VirtualMachineInstance(vmis[idx].Namespace).Delete(vmis[idx].Name, &metav1.DeleteOptions{})
					Expect(err).To(BeNil())
					err = virtClient.CdiClient().CdiV1beta1().DataVolumes(dvs[idx].Namespace).Delete(context.Background(), dvs[idx].Name, metav1.DeleteOptions{})
					Expect(err).To(BeNil())
				}
			})
{'fraction_non_alphanumeric': 0.12692879717419595, 'fraction_numerical': 0.014826175869120654, 'mean_word_length': 4.3207220573689415, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1179612', 'n_tokens_mistral': 8204, 'n_tokens_neox': 7004, 'n_words': 1383}