summaryrefslogtreecommitdiffstats
path: root/tests/lib/cbmem_console-test.c
blob: fca84a7bd4e4e595c102c374504bd0a1275c9645 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* SPDX-License-Identifier: GPL-2.0-only */

#include "../lib/cbmem_console.c"

#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <tests/test.h>


#if ENV_ROMSTAGE_OR_BEFORE
/* Weak references have to be here, so TEST_REGION macro will work properly */
__weak extern u8 _preram_cbmem_console[];
__weak extern u8 _epreram_cbmem_console[];

#define PRERAM_CBMEM_CONSOLE_SIZE (1 * KiB)
TEST_REGION(preram_cbmem_console, PRERAM_CBMEM_CONSOLE_SIZE);
#endif

/* Disable init hooks. This test does not need them. */
void cbmem_run_init_hooks(int is_recovery)
{
	(void)is_recovery;
}

int setup_cbmemc(void **state)
{
	cbmemc_init();
	return 0;
}

int teardown_cbmemc(void **state)
{
	current_console->size = 0;
	return 0;
}

void test_cbmemc_init(void **state)
{
	cbmemc_init();

	/* Check if console structure was created. */
	assert_non_null(current_console);
}

void test_cbmemc_tx_byte(void **state)
{
	int i;
	u32 cursor;
	const unsigned char data[] = "Random testing string\n"
				"`1234567890-=~!@#$%^&*()_+\n"
				"abcdefghijklmnopqrstuvwxyz\n"
				"ABCDEFGHIJKLMNOPQRSTUVWXYZ\n";

	for (i = 0; i < ARRAY_SIZE(data); ++i)
		cbmemc_tx_byte(data[i]);

	cursor = current_console->cursor & CURSOR_MASK;

	assert_int_equal(ARRAY_SIZE(data), cursor);

	/* Check if all characters were added correctly. */
	assert_memory_equal(data, current_console->body, ARRAY_SIZE(data));
}

void test_cbmemc_tx_byte_overflow(void **state)
{
	int i;
	u32 cursor;
	u32 flags;
	const uint32_t console_size = current_console->size;
	const unsigned char data[] = "Another random string\n"
				"abcdefghijklmnopqrstuvwxyz\n"
				"ABCDEFGHIJKLMNOPQRSTUVWXYZ\n"
				"`1234567890-=~!@#$%^&*()_+\n";
	const int data_size = ARRAY_SIZE(data) - 1;
	const int data_stream_length = console_size + data_size;
	const int overflow_bytes = data_stream_length % console_size;
	unsigned char *check_buffer =
			(unsigned char *)malloc(sizeof(unsigned char) * console_size);

	/* Fill console buffer */
	for (i = 0; i < console_size; ++i)
		cbmemc_tx_byte(data[i % data_size]);

	/* Store buffer for checking */
	memcpy(check_buffer, current_console->body, console_size);

	assert_memory_equal(current_console->body, data, overflow_bytes);

	/* Add more data to console buffer to override older bytes */
	for (; i < data_stream_length; ++i)
		cbmemc_tx_byte(data[i % data_size]);

	cursor = current_console->cursor & CURSOR_MASK;
	flags = current_console->cursor & ~CURSOR_MASK;

	/* Check if there was a overflow in buffer */
	assert_int_equal(OVERFLOW, flags & OVERFLOW);

	/* Check if cursor got back to the beginning of a buffer */
	assert_int_equal(data_size, cursor);

	/* Check if overflow buffer was overwritten */
	assert_memory_not_equal(current_console->body,
			data,
			overflow_bytes);

	/* Check if rest of the buffer contents, that should not be overridden,
	 * is the same.
	 */
	assert_memory_equal(&current_console->body[overflow_bytes],
			check_buffer + overflow_bytes,
			console_size - overflow_bytes);

	free(check_buffer);
}

int main(void)
{
	const struct CMUnitTest tests[] = {
		cmocka_unit_test_teardown(test_cbmemc_init, teardown_cbmemc),
		cmocka_unit_test_setup_teardown(test_cbmemc_tx_byte,
						setup_cbmemc, teardown_cbmemc),
		cmocka_unit_test_setup_teardown(test_cbmemc_tx_byte_overflow,
						setup_cbmemc, teardown_cbmemc),
	};

	return cb_run_group_tests(tests, NULL, NULL);
}