Add tests that check that the video console is working correcty. Also check that text output produces the expected result. Test coverage includes character output, wrapping and scrolling. Signed-off-by: Simon Glass <sjg@chromium.org> Acked-by: Anatolij Gustschin <agust@denx.de>master
parent
3ade5bc4dc
commit
3c97c4fb52
@ -0,0 +1,190 @@ |
||||
/*
|
||||
* Copyright (c) 2014 Google, Inc |
||||
* Written by Simon Glass <sjg@chromium.org> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <bzlib.h> |
||||
#include <dm.h> |
||||
#include <mapmem.h> |
||||
#include <os.h> |
||||
#include <video.h> |
||||
#include <video_console.h> |
||||
#include <dm/test.h> |
||||
#include <dm/uclass-internal.h> |
||||
#include <test/ut.h> |
||||
|
||||
/*
|
||||
* These tests use the standard sandbox frame buffer, the resolution of which |
||||
* is defined in the device tree. This only supports 16bpp so the tests only |
||||
* test that code path. It would be possible to adjust this fairly easily, |
||||
* by adjusting the bpix value in struct sandbox_sdl_plat. However the code |
||||
* in sandbox_sdl_sync() would also need to change to handle the different |
||||
* surface depth. |
||||
*/ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
/* Basic test of the video uclass */ |
||||
static int dm_test_video_base(struct unit_test_state *uts) |
||||
{ |
||||
struct video_priv *priv; |
||||
struct udevice *dev; |
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev)); |
||||
ut_asserteq(1366, video_get_xsize(dev)); |
||||
ut_asserteq(768, video_get_ysize(dev)); |
||||
priv = dev_get_uclass_priv(dev); |
||||
ut_asserteq(priv->fb_size, 1366 * 768 * 2); |
||||
|
||||
return 0; |
||||
} |
||||
DM_TEST(dm_test_video_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); |
||||
|
||||
/**
|
||||
* compress_frame_buffer() - Compress the frame buffer and return its size |
||||
* |
||||
* We want to write tests which perform operations on the video console and |
||||
* check that the frame buffer ends up with the correct contents. But it is |
||||
* painful to store 'known good' images for comparison with the frame |
||||
* buffer. As an alternative, we can compress the frame buffer and check the |
||||
* size of the compressed data. This provides a pretty good level of |
||||
* certainty and the resulting tests need only check a single value. |
||||
* |
||||
* @dev: Video device |
||||
* @return compressed size of the frame buffer, or -ve on error |
||||
*/ |
||||
static int compress_frame_buffer(struct udevice *dev) |
||||
{ |
||||
struct video_priv *priv = dev_get_uclass_priv(dev); |
||||
uint destlen; |
||||
void *dest; |
||||
int ret; |
||||
|
||||
destlen = priv->fb_size; |
||||
dest = malloc(priv->fb_size); |
||||
if (!dest) |
||||
return -ENOMEM; |
||||
ret = BZ2_bzBuffToBuffCompress(dest, &destlen, |
||||
priv->fb, priv->fb_size, |
||||
3, 0, 0); |
||||
free(dest); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
return destlen; |
||||
} |
||||
|
||||
/*
|
||||
* Call this function at any point to halt and show the current display. Be |
||||
* sure to run the test with the -l flag. |
||||
*/ |
||||
static void __maybe_unused see_output(void) |
||||
{ |
||||
video_sync_all(); |
||||
while (1); |
||||
} |
||||
|
||||
/* Test text output works on the video console */ |
||||
static int dm_test_video_text(struct unit_test_state *uts) |
||||
{ |
||||
struct udevice *dev, *con; |
||||
int i; |
||||
|
||||
#define WHITE 0xffff |
||||
#define SCROLL_LINES 100 |
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev)); |
||||
ut_asserteq(46, compress_frame_buffer(dev)); |
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); |
||||
vidconsole_putc_xy(con, 0, 0, 'a'); |
||||
ut_asserteq(79, compress_frame_buffer(dev)); |
||||
|
||||
vidconsole_putc_xy(con, 0, 0, ' '); |
||||
ut_asserteq(46, compress_frame_buffer(dev)); |
||||
|
||||
for (i = 0; i < 20; i++) |
||||
vidconsole_putc_xy(con, i * 8, 0, ' ' + i); |
||||
ut_asserteq(273, compress_frame_buffer(dev)); |
||||
|
||||
vidconsole_set_row(con, 0, WHITE); |
||||
ut_asserteq(46, compress_frame_buffer(dev)); |
||||
|
||||
for (i = 0; i < 20; i++) |
||||
vidconsole_putc_xy(con, i * 8, 0, ' ' + i); |
||||
ut_asserteq(273, compress_frame_buffer(dev)); |
||||
|
||||
return 0; |
||||
} |
||||
DM_TEST(dm_test_video_text, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); |
||||
|
||||
/* Test handling of special characters in the console */ |
||||
static int dm_test_video_chars(struct unit_test_state *uts) |
||||
{ |
||||
struct udevice *dev, *con; |
||||
const char *test_string = "Well\b\b\b\bxhe is\r \n\ta very modest \bman\n\t\tand Has much to\b\bto be modest about."; |
||||
const char *s; |
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev)); |
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); |
||||
for (s = test_string; *s; s++) |
||||
vidconsole_put_char(con, *s); |
||||
ut_asserteq(466, compress_frame_buffer(dev)); |
||||
|
||||
return 0; |
||||
} |
||||
DM_TEST(dm_test_video_chars, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); |
||||
|
||||
/**
|
||||
* check_vidconsole_output() - Run a text console test |
||||
* |
||||
* @uts: Test state |
||||
* @rot: Console rotation (0, 90, 180, 270) |
||||
* @wrap_size: Expected size of compressed frame buffer for the wrap test |
||||
* @scroll_size: Same for the scroll test |
||||
* @return 0 on success |
||||
*/ |
||||
static int check_vidconsole_output(struct unit_test_state *uts, int rot, |
||||
int wrap_size, int scroll_size) |
||||
{ |
||||
struct udevice *dev, *con; |
||||
struct sandbox_sdl_plat *plat; |
||||
int i; |
||||
|
||||
ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev)); |
||||
ut_assert(!device_active(dev)); |
||||
plat = dev_get_platdata(dev); |
||||
plat->rot = rot; |
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev)); |
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); |
||||
ut_asserteq(46, compress_frame_buffer(dev)); |
||||
|
||||
/* Check display wrap */ |
||||
for (i = 0; i < 120; i++) |
||||
vidconsole_put_char(con, 'A' + i % 50); |
||||
ut_asserteq(wrap_size, compress_frame_buffer(dev)); |
||||
|
||||
/* Check display scrolling */ |
||||
for (i = 0; i < SCROLL_LINES; i++) { |
||||
vidconsole_put_char(con, 'A' + i % 50); |
||||
vidconsole_put_char(con, '\n'); |
||||
} |
||||
ut_asserteq(scroll_size, compress_frame_buffer(dev)); |
||||
|
||||
/* If we scroll enough, the screen becomes blank again */ |
||||
for (i = 0; i < SCROLL_LINES; i++) |
||||
vidconsole_put_char(con, '\n'); |
||||
ut_asserteq(46, compress_frame_buffer(dev)); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/* Test text output through the console uclass */ |
||||
static int dm_test_video_context(struct unit_test_state *uts) |
||||
{ |
||||
return check_vidconsole_output(uts, 0, 788, 453); |
||||
} |
||||
DM_TEST(dm_test_video_context, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); |
Loading…
Reference in new issue