Improve VNC screenshot test
It turns out that eventually the VNC screen ends up with a resolution of
720x400, but the initial seabios screen has a different resolution for a
very short amount of time.
Cope with that by retrying until we see the exepcted resolution.
@@ -23,6 +23,7 @@ import (
"context"
"encoding/json"
"fmt"
+ "image"
"image/png"
"io"
"net"
@@ -246,6 +247,9 @@ var _ = Describe("[rfe_id:127][crit:medium][arm64][vendor:cnv-qe@redhat.com][lev
It("should allow creating a VNC screenshot in PNG format", func() {
filePath := filepath.Join(GinkgoT().TempDir(), "screenshot.png")
+ // Sometimes we can see initially a 640x480 resolution if we connect very early
+ By("gathering screenshots until we are past the first boot screen and see the expected 720x400 resolution")
+ Eventually(func() image.Image {
cmd := clientcmd.NewVirtctlCommand("vnc", "screenshot", "--namespace", vmi.Namespace, "--file", filePath, vmi.Name)
Expect(cmd.Execute()).To(Succeed())
@@ -255,8 +259,8 @@ var _ = Describe("[rfe_id:127][crit:medium][arm64][vendor:cnv-qe@redhat.com][lev
img, err := png.Decode(f)
Expect(err).ToNot(HaveOccurred())
- Expect(img.Bounds().Size().X).To(BeNumerically("==", 720))
- Expect(img.Bounds().Size().Y).To(BeNumerically("==", 400))
+ return img
+ }, 10*time.Second).Should(HaveResolution(720, 400))
})
})
})
@@ -299,3 +303,47 @@ func upgradeCheckRoundTripperFromConfig(config *rest.Config, subprotocols []stri
Dialer: dialer,
}, nil
}
+
+type ResolutionMatcher struct {
+ X, Y int
+}
+
+func (h ResolutionMatcher) Match(actual interface{}) (success bool, err error) {
+ x, y, err := imgSize(actual)
+ if err != nil {
+ return false, nil
+ }
+ return x == h.X && y == h.Y, nil
+}
+
+func (h ResolutionMatcher) FailureMessage(actual interface{}) (message string) {
+ x, y, err := imgSize(actual)
+ if err != nil {
+ return err.Error()
+ }
+ return fmt.Sprintf("Expected (X: %d, Y: %d) to match (X: %d, Y: %d)", x, y, h.X, h.Y)
+}
+
+func (h ResolutionMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+ x, y, err := imgSize(actual)
+ if err != nil {
+ return err.Error()
+ }
+ return fmt.Sprintf("Expected (X: %d, Y: %d) to not match (X: %d, Y: %d)", x, y, h.X, h.Y)
+}
+
+func HaveResolution(X, Y int) ResolutionMatcher {
+ return ResolutionMatcher{X: X, Y: Y}
+}
+
+func imgSize(actual interface{}) (X, Y int, err error) {
+ if actual == nil {
+ return -1, -1, fmt.Errorf("expected an object of type image.Image but got nil")
+ }
+ img, ok := actual.(image.Image)
+ if !ok {
+ return -1, -1, fmt.Errorf("expected an object of type image.Image")
+ }
+ size := img.Bounds().Size()
+ return size.X, size.Y, nil
+}
