VNC

Check a BMC’s KVM over VNC (RFB): connect from the runner, optionally send keys, capture one frame, check it and attach it as a PNG screenshot. Where PiKVM drives an external KVM device, vnc checks the KVM that the BMC serves itself.

On OpenBMC, obmc-ikvm serves the host’s video and keyboard as a VNC server on TCP 5900, but it listens on localhost only. bmcweb forwards it as a websocket at /kvm/0, which is what the web UI uses, so the step goes through bmcweb by default. via: direct is for VNC servers that listen on the network, such as QEMU’s -vnc display.

AttributeTypeRequiredDefaultDescription
cmdconstYesvncCommand Name
namestringYesName to uniquely identify the teststep. This name will show up in reports, logs and the WebUI
optionsOptionsObjectNoAdditional command options
parametersVNCOptionsYesOptions passed into the vnc cmd

The step uses no transport: the runner itself opens the connection.

VNC Quick start

- cmd: vnc
  name: KVM shows the host console
  parameters:
    host: "[[attributes.BMC]]"
    auth: { user: root, password: "[[attributes.BMCPassword]]" }
    insecure: true              # BMCs serve self-signed certificates
    expect:
      width: { ge: 640 }
      height: { ge: 480 }
      blank: false
      name: { contains: IKVM }  # obmc-ikvm reports "OpenBMC IKVM"

VNC Options

AttributeTypeRequiredDefaultDescription
hoststringYesBMC host name or address; with via: bmcweb also an https:// URL.
portinteger or stringNo443 for bmcweb, 5900 for directHTTPS port for via: bmcweb, VNC port for via: direct. A string such as "[[attributes.KVMPort]]" works too.
viastringNobmcwebbmcweb: the KVM websocket wss://host/kvm/0. direct: TCP to a VNC server that listens on the network.
auth{user, password}Yes, for via: bmcwebSent as HTTP Basic with the websocket upgrade. The account needs the ConfigureComponents privilege.
insecurebooleanNofalsevia: bmcweb only: accept a self-signed certificate.
pathstringNo/kvm/0via: bmcweb only: the websocket path.
passwordstringNoVNC password, at most 8 characters. Without it the step asks for security type None.
keys[]string or {text}NoKeys sent before the capture, in order. See VNC Keys.
waitstringNoPause after the keys, before the capture, such as 5s.
expectVNCExpectNoWhat the frame must show.
screenshotbooleanNotrueAttach the frame as PNG, also when a check fails.

Passwords are masked in the log. Without an options timeout, the step timeout is 2 minutes plus wait; every read and write on the connection has its own 30 second deadline.

VNC Keys

A string is a key or a combination joined by -: Return, F2, Escape, ctrl-alt-del, alt-F4. Modifiers are ctrl, alt, shift and super. Other names: tab, backspace, delete, insert, home, end, pageup, pagedown, up, down, left, right, space, minus, plus, f1 to f12, and any single printable character. Names ignore case.

Before the first key the step waits 3 seconds: obmc-ikvm plugs its USB keyboard into the host only when the first viewer connects, and the host drops keys that arrive before it has found the keyboard.

A map { text: ... } types printable ASCII text; \n is Return and \t is Tab. Capitals and shifted symbols are typed with Shift held, as on a US layout:

    keys: [Return, { text: "root\n" }]
    wait: 5s

VNC Expectations

KeyChecks
width, heightFrame size in pixels.
contentPercent of pixels that differ clearly from the dominant colour.
deltacontent after the keys minus content before them, in percentage points. The step then also captures a frame before the keys.
blanktrue: the frame is blank; false: it shows something.
nameThe desktop name the server reports.

width, height, content and delta take a number (equals) or one operator of eq, ne, ge, le, range (min..max). name takes a string (equals) or one of eq, ne, matches, contains. Without expectations the step passes when the KVM answers with a frame.

The step buckets the pixels by colour and takes the fullest bucket as the dominant colour. A pixel counts as content when one channel differs from it by more than 48, which ignores video compression noise. A frame is blank below 0.01 percent content; a single login prompt on a 1024x768 console is about 0.03 percent. blank and content both judge the picture, so a step uses one of them.

content depends on the screen resolution and on what the screen already shows. delta does not depend on what is already there, so it is the check for keys: typed text raises it, erased text lowers it. 40 # characters on a Linux console change about 1,700 pixels: 0.07 points at 1920x1200 and 0.21 at 1024x768. Ctrl-U at a login prompt erases them again:

- cmd: vnc
  name: Text typed over the KVM appears on the host screen
  parameters:
    host: "[[attributes.BMC]]"
    auth: { user: root, password: "[[attributes.BMCPassword]]" }
    insecure: true
    keys: [{ text: "########################################" }]
    wait: 3s
    expect:
      delta: { ge: 0.03 }

- cmd: vnc
  name: Ctrl-U over the KVM erases the typed text
  parameters:
    host: "[[attributes.BMC]]"
    auth: { user: root, password: "[[attributes.BMCPassword]]" }
    insecure: true
    keys: [ctrl-u]
    wait: 3s
    expect:
      delta: { le: -0.03 }

The log names the protocol version, the security type, the desktop name and size, the keys, and the dominant colour and content of the frame, with delta also of the frame before the keys:

RFB 3.8, security None
desktop "OpenBMC IKVM" 1920x1200
frame before the keys: dominant colour #010101 on 99.73% of pixels, content 0.131%
keys: text "########################################"
waited 3s
frame 1920x1200: dominant colour #010101 on 99.62% of pixels, content 0.204%

✓ delta ge 0.03: +0.073 (content 0.131% before, 0.204% after)

The step speaks RFB 3.3, 3.7 and 3.8 with security None and VNC authentication, joins a shared session (other viewers stay connected), reads 32-bit true colour in Raw encoding, and follows DesktopSize changes while the frame is read.

obmc-ikvm answers every frame request twice: with a JPEG of the screen from the BMC’s video engine, sent as Tight (encoding 7) although the step asks for Raw only, and from libvncserver’s own framebuffer, which stays black with the mouse pointer drawn in. Both are written at the same time, so the libvncserver answer can corrupt the JPEG. From a server named OpenBMC IKVM the step therefore requests an empty area: libvncserver then sends nothing, and the step takes a size change from the JPEG. The step reads Tight JPEG and solid fill rectangles; a Tight rectangle with basic (zlib) compression fails the step with a message that names it.

To check that the raw VNC port is not open to the network, use Ping with port: 5900 and expect: { should_fail: true }.