diff --git a/tests/e2e/common.go b/tests/e2e/common.go index f20ffdbcf..b7dfad4b9 100644 --- a/tests/e2e/common.go +++ b/tests/e2e/common.go @@ -28,6 +28,8 @@ import ( "github.com/Mirantis/virtlet/tests/e2e/framework" . "github.com/Mirantis/virtlet/tests/e2e/ginkgo-ext" + + "k8s.io/client-go/pkg/api/v1" ) var ( @@ -35,6 +37,7 @@ var ( sshUser = flag.String("sshuser", defaultSSHUser, "default SSH user for VMs") includeCloudInitTests = flag.Bool("include-cloud-init-tests", false, "include Cloud-Init tests") includeUnsafeTests = flag.Bool("include-unsafe-tests", false, "include tests that can be unsafe if they're run outside the build container") + includeDisruptive = flag.Bool("include-disruptive", false, "include tests that can disrupt other tests") memoryLimit = flag.Int("memoryLimit", 160, "default VM memory limit (in MiB)") junitOutput = flag.String("junitOutput", "", "JUnit XML output file") ) @@ -65,6 +68,25 @@ func waitSSH(vm *framework.VMInterface) framework.Executor { return ssh } +func waitVirtletPod(vm *framework.VMInterface) *framework.PodInterface { + var virtletPod *framework.PodInterface + Eventually( + func() error { + var err error + virtletPod, err = vm.VirtletPod() + if err != nil { + return err + } + for _, c := range virtletPod.Pod.Status.Conditions { + if c.Type == v1.PodReady && c.Status == v1.ConditionTrue { + return nil + } + } + return fmt.Errorf("Pod not ready yet: %+v", virtletPod.Pod.Status) + }, 60*5, 3).Should(Succeed()) + return virtletPod +} + func checkCPUCount(vm *framework.VMInterface, ssh framework.Executor, cpus int) { proc := do(framework.RunSimple(ssh, "cat", "/proc/cpuinfo")).(string) Expect(regexp.MustCompile(`(?m)^processor`).FindAllString(proc, -1)).To(HaveLen(cpus)) @@ -153,3 +175,9 @@ func includeUnsafe() { Skip("Tests that are unsafe outside the build container are disabled") } } + +func includeDisruptive() { + if !*includeDisruptive { + Skip("Tests that may disrupt another tests are disabled") + } +} diff --git a/tests/e2e/framework/pod_interface.go b/tests/e2e/framework/pod_interface.go index 6875419f5..908144535 100644 --- a/tests/e2e/framework/pod_interface.go +++ b/tests/e2e/framework/pod_interface.go @@ -26,7 +26,6 @@ import ( "time" "github.com/davecgh/go-spew/spew" - "k8s.io/apimachinery/pkg/api/errors" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -68,9 +67,9 @@ func (pi *PodInterface) Create() error { // Delete deletes the pod and associated service, which was earlier created by `controller.Run()` func (pi *PodInterface) Delete() error { if pi.hasService { - pi.controller.client.Services(pi.controller.Namespace()).Delete(pi.Pod.Name, nil) + pi.controller.client.Services(pi.Pod.Namespace).Delete(pi.Pod.Name, nil) } - return pi.controller.client.Pods(pi.controller.Namespace()).Delete(pi.Pod.Name, nil) + return pi.controller.client.Pods(pi.Pod.Namespace).Delete(pi.Pod.Name, nil) } // Wait waits for pod to start and checks that it doesn't fail immediately after that diff --git a/tests/e2e/restart_virtlet_test.go b/tests/e2e/restart_virtlet_test.go index c524eebc2..d49088913 100644 --- a/tests/e2e/restart_virtlet_test.go +++ b/tests/e2e/restart_virtlet_test.go @@ -17,6 +17,9 @@ limitations under the License. package e2e import ( + "bytes" + "context" + "fmt" "time" . "github.com/onsi/gomega" @@ -32,30 +35,53 @@ var _ = Describe("Virtlet restart", func() { ) BeforeAll(func() { + includeDisruptive() vm = controller.VM("cirros-vm") vm.Create(VMOptions{}.applyDefaults(), time.Minute*5, nil) var err error vmPod, err = vm.Pod() Expect(err).NotTo(HaveOccurred()) + + // restart virtlet before all tests + virtletPod, err := vm.VirtletPod() + Expect(err).NotTo(HaveOccurred()) + + err = virtletPod.Delete() + Expect(err).NotTo(HaveOccurred()) + + waitVirtletPod(vm) }) AfterAll(func() { deleteVM(vm) }) - It("Should allow to ssh to VM after virtlet pod and vm restart [Conformance]", func() { - pod, err := vm.VirtletPod() - Expect(err).NotTo(HaveOccurred()) + It("Should allow to ssh to VM after virtlet pod restart", func() { + waitSSH(vm) + }, 3*60) - virtletPodExecutor, err := pod.Container("virtlet") - Expect(err).NotTo(HaveOccurred()) + It("Should contain logs from attach session", func() { + var stdout bytes.Buffer + ctx, closeFunc := context.WithCancel(context.Background()) + defer closeFunc() + localExecutor := framework.LocalExecutor(ctx) - do(framework.ExecSimple(virtletPodExecutor, "pkill", "-9", "virtlet")) - Expect(pod.Wait()).NotTo(HaveOccurred()) + By(fmt.Sprintf("Running command: kubectl logs -n %s %s", controller.Namespace(), vm.Name)) + err := localExecutor.Run(nil, &stdout, &stdout, "kubectl", "-n", controller.Namespace(), "logs", vm.Name) + fmt.Sprintf(stdout.String()) + Expect(err).NotTo(HaveOccurred()) + Expect(stdout.String()).Should(ContainSubstring("login as 'cirros' user.")) - _, err = vm.VirshCommand("reboot", "") + By(fmt.Sprintf("Running command: kubectl attach -n %s -i %s", controller.Namespace(), vm.Name)) + stdin := bytes.NewBufferString("\nTESTTEXT\n\n") + stdout.Reset() + err = localExecutor.Run(stdin, &stdout, &stdout, "kubectl", "-n", controller.Namespace(), "attach", "-i", vm.Name) Expect(err).NotTo(HaveOccurred()) - waitSSH(vm) + By(fmt.Sprintf("Running again command: kubectl logs -n %s %s", controller.Namespace(), vm.Name)) + stdout.Reset() + err = localExecutor.Run(nil, &stdout, &stdout, "kubectl", "-n", controller.Namespace(), "logs", vm.Name) + Expect(err).NotTo(HaveOccurred()) + Expect(stdout.String()).Should(ContainSubstring("TESTTEXT")) }, 3*60) })