test_weston.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import os
  2. import time
  3. import infra.basetest
  4. from ..graphics_base import GraphicsBase
  5. class TestWeston(infra.basetest.BRTest, GraphicsBase):
  6. config = \
  7. """
  8. BR2_aarch64=y
  9. BR2_TOOLCHAIN_EXTERNAL=y
  10. BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
  11. BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0"
  12. BR2_ROOTFS_OVERLAY="{}"
  13. BR2_PER_PACKAGE_DIRECTORIES=y
  14. BR2_LINUX_KERNEL=y
  15. BR2_LINUX_KERNEL_CUSTOM_VERSION=y
  16. BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.1.44"
  17. BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
  18. BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-virt/linux.config"
  19. BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{}"
  20. BR2_PACKAGE_LIBDRM=y
  21. BR2_PACKAGE_MESA3D=y
  22. BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_SWRAST=y
  23. BR2_PACKAGE_MESA3D_LLVM=y
  24. BR2_PACKAGE_MESA3D_OPENGL_EGL=y
  25. BR2_PACKAGE_MESA3D_OPENGL_ES=y
  26. BR2_PACKAGE_WAYLAND_UTILS=y
  27. BR2_PACKAGE_WESTON=y
  28. BR2_PACKAGE_WESTON_SIMPLE_CLIENTS=y
  29. BR2_TARGET_ROOTFS_CPIO=y
  30. BR2_TARGET_ROOTFS_CPIO_GZIP=y
  31. # BR2_TARGET_ROOTFS_TAR is not set
  32. """.format(
  33. infra.filepath("tests/package/test_weston/overlay"),
  34. infra.filepath("tests/package/test_weston/linux-vkms.fragment")
  35. )
  36. def start_weston(self):
  37. self.assertRunOk("export XDG_RUNTIME_DIR=/tmp")
  38. cmd = "( weston"
  39. cmd += " --config=/etc/weston.ini"
  40. cmd += " --continue-without-input"
  41. cmd += " --log=/tmp/weston.log"
  42. cmd += " &> /dev/null & )"
  43. self.assertRunOk(cmd)
  44. self.assertRunOk("export WAYLAND_DISPLAY=wayland-1")
  45. def wait_for_weston(self):
  46. # We wait for the wayland socket to appear...
  47. wayland_socket = "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}"
  48. cmd = f"while [ ! -e \"{wayland_socket}\" ] ; do sleep 1 ; done"
  49. self.assertRunOk(cmd, timeout=10)
  50. time.sleep(4)
  51. def stop_weston(self):
  52. cmd = "killall weston"
  53. time.sleep(3)
  54. self.assertRunOk(cmd)
  55. def test_run(self):
  56. img = os.path.join(self.builddir, "images", "rootfs.cpio.gz")
  57. kern = os.path.join(self.builddir, "images", "Image")
  58. self.emulator.boot(arch="aarch64",
  59. kernel=kern,
  60. kernel_cmdline=["console=ttyAMA0", "vt.global_cursor_default=0"],
  61. options=["-M", "virt",
  62. "-cpu", "cortex-a57",
  63. "-smp", "4",
  64. "-m", "512M",
  65. "-initrd", img])
  66. self.emulator.login()
  67. # This test uses the vkms DRM Kernel driver. This driver can
  68. # generate kernel warning messages in some cases (e.g. "vblank
  69. # timer overrun"). Those messages can happen on slow test
  70. # runners. This warning is not an issue in this test: it is
  71. # not checking performance here; it just checks the rendering
  72. # pipeline is functional. For that reason, this test adds the
  73. # file "/etc/default/klogd" to only show emergency messages
  74. # (level value 0) on the console.
  75. # Check the weston binary can execute
  76. self.assertRunOk("weston --version")
  77. self.start_weston()
  78. self.wait_for_weston()
  79. # Check a simple info client can communicate with the compositor
  80. self.assertRunOk("wayland-info", timeout=10)
  81. # We get 10 consecutive DRM frame CRCs and count how many
  82. # unique CRCs we have. Since weston is supposed to run idle,
  83. # we should have 10 times the same display CRC.
  84. self.assertTrue(len(self.get_n_fb_crc(uniq=True)) == 1)
  85. # We save the CRC value of an empty weston desktop for
  86. # later...
  87. weston_desktop_crc = self.get_n_fb_crc(count=1)[0]
  88. # We start the weston-simple-egl in background... Every
  89. # rendered frame is supposed to be different (as the triangle
  90. # animation is derived from the system time). Since all the
  91. # rendering (client application and compositor) is in
  92. # software, we sleep a bit to let those program to settle.
  93. self.assertRunOk("( weston-simple-egl >/dev/null 2>&1 & )")
  94. # Since the weston-simple-egl client is supposed to run and
  95. # display something, we are now supposed to measure a
  96. # different display CRC than the one we measured when the
  97. # desktop was empty.
  98. for i in range(600):
  99. crc = self.get_n_fb_crc(count=1)[0]
  100. if crc != weston_desktop_crc:
  101. break
  102. time.sleep(1)
  103. self.assertNotEqual(crc, weston_desktop_crc)
  104. # While weston-simple-egl is running, we check the VKMS DRM
  105. # CRCs are now changing. We get many CRCs, one per display
  106. # driver refresh (at ~60Hz). Since all the rendering is in
  107. # software, we can expect a slow frame rate. In 300 captured
  108. # CRCs (5s), we expect at least 5 different values (i.e. 1 fps).
  109. # This guarantees the rendering pipeline is working, while we
  110. # remain very permissive to slow emulation situations.
  111. # Increase timeout, as the command is expected to run about 5s,
  112. # which is the default timeout.
  113. crcs = self.get_n_fb_crc(count=300, timeout=10)
  114. self.assertGreaterEqual(len(crcs), 5)
  115. # We stop weston-simple-egl, and sleep a bit to let Weston do
  116. # its cleanup and desktop repaint refresh...
  117. self.assertRunOk("killall weston-simple-egl")
  118. # After we stopped the application, we should have the initial
  119. # weston desktop background. The CRC we measure now should be
  120. # the same as the one we saved earlier.
  121. for i in range(600):
  122. crc = self.get_n_fb_crc(count=1)[0]
  123. if crc == weston_desktop_crc:
  124. break
  125. time.sleep(1)
  126. self.assertEqual(crc, weston_desktop_crc)
  127. self.stop_weston()
  128. # Now weston is supposed to be stopped,
  129. # a simple client is expected to fail.
  130. _, exit_code = self.emulator.run("wayland-info")
  131. self.assertNotEqual(exit_code, 0)