diff options
| author | Simon Rettberg | 2022-05-11 10:41:01 +0200 |
|---|---|---|
| committer | Simon Rettberg | 2022-05-11 10:41:01 +0200 |
| commit | a12e3c379cf2e5946c7316259ef46736cdd5f222 (patch) | |
| tree | 49638dad528a4490e293ea4a0f87e39ce862a75b /src/tests | |
| parent | Local UEFI disk boot support (diff) | |
| parent | [cloud] Allow aws-import script to run on Python 3.6 (diff) | |
| download | ipxe-a12e3c379cf2e5946c7316259ef46736cdd5f222.tar.gz ipxe-a12e3c379cf2e5946c7316259ef46736cdd5f222.tar.xz ipxe-a12e3c379cf2e5946c7316259ef46736cdd5f222.zip | |
Merge branch 'master' into openslx
Diffstat (limited to 'src/tests')
| -rw-r--r-- | src/tests/acpi_test.c | 257 | ||||
| -rw-r--r-- | src/tests/settings_test.c | 10 | ||||
| -rw-r--r-- | src/tests/tests.c | 2 | ||||
| -rw-r--r-- | src/tests/uri_test.c | 63 | ||||
| -rw-r--r-- | src/tests/utf8_test.c | 164 |
5 files changed, 483 insertions, 13 deletions
diff --git a/src/tests/acpi_test.c b/src/tests/acpi_test.c new file mode 100644 index 000000000..1ca5befaf --- /dev/null +++ b/src/tests/acpi_test.c @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2022 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * ACPI tests + * + */ + +/* Forcibly enable assertions */ +#undef NDEBUG + +#include <ipxe/acpi.h> +#include <ipxe/acpimac.h> +#include <ipxe/if_ether.h> +#include <ipxe/test.h> + +/** An ACPI test table signature */ +union acpi_test_signature { + /** String */ + char str[4]; + /** Raw value */ + uint32_t raw; +}; + +/** An ACPI test table */ +struct acpi_test_table { + /** Signature */ + union acpi_test_signature signature; + /** Table content */ + const void *data; +}; + +/** An ACPI test table set */ +struct acpi_test_tables { + /** Tables */ + struct acpi_test_table **table; + /** Number of tables */ + unsigned int count; +}; + +/** An ACPI MAC extraction test */ +struct acpi_mac_test { + /** ACPI test table set */ + struct acpi_test_tables *tables; + /** Expected MAC address */ + uint8_t expected[ETH_ALEN]; +}; + +/** Define inline data */ +#define DATA(...) { __VA_ARGS__ } + +/** Define an ACPI test table */ +#define ACPI_TABLE( name, SIGNATURE, DATA ) \ + static const uint8_t name ## _data[] = DATA; \ + static struct acpi_test_table name = { \ + .signature = { \ + .str = SIGNATURE, \ + }, \ + .data = name ## _data, \ + } + +/** Define an ACPI test table set */ +#define ACPI_TABLES( name, ... ) \ + static struct acpi_test_table * name ## _table[] = \ + { __VA_ARGS__ }; \ + static struct acpi_test_tables name = { \ + .table = name ## _table, \ + .count = ( sizeof ( name ## _table ) / \ + sizeof ( name ## _table[0] ) ), \ + } + +/** Define an ACPI MAC extraction test */ +#define ACPI_MAC( name, TABLES, EXPECTED ) \ + static struct acpi_mac_test name = { \ + .tables = TABLES, \ + .expected = EXPECTED, \ + } + +/** "AMAC" SSDT + * + * DefinitionBlock ("", "SSDT", 2, "", "", 0x0) { + * Scope (\_SB) { + * Method (HW00, 0, Serialized) { Return(0) } + * Method (AMAC, 0, Serialized) { ToString("_AUXMAC_#525400aabbcc#") } + * Method (HW42, 0, Serialized) { Return(42) } + * } + * } + */ +ACPI_TABLE ( amac_ssdt, "SSDT", + DATA ( 0x53, 0x53, 0x44, 0x54, 0x5d, 0x00, 0x00, 0x00, 0x02, + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x4e, 0x54, 0x4c, 0x04, 0x06, 0x21, 0x20, + 0x10, 0x38, 0x5c, 0x5f, 0x53, 0x42, 0x5f, 0x14, 0x08, + 0x48, 0x57, 0x30, 0x30, 0x08, 0xa4, 0x00, 0x14, 0x1e, + 0x41, 0x4d, 0x41, 0x43, 0x08, 0x0d, 0x5f, 0x41, 0x55, + 0x58, 0x4d, 0x41, 0x43, 0x5f, 0x23, 0x35, 0x32, 0x35, + 0x34, 0x30, 0x30, 0x61, 0x61, 0x62, 0x62, 0x63, 0x63, + 0x23, 0x00, 0x14, 0x09, 0x48, 0x57, 0x34, 0x32, 0x08, + 0xa4, 0x0a, 0x2a ) ); + +/** "AMAC" test tables */ +ACPI_TABLES ( amac_tables, &amac_ssdt ); + +/** "AMAC" test */ +ACPI_MAC ( amac, &amac_tables, + DATA ( 0x52, 0x54, 0x00, 0xaa, 0xbb, 0xcc ) ); + +/** "MACA" SSDT1 (does not contain AUXMAC) */ +ACPI_TABLE ( maca_ssdt1, "SSDT", + DATA ( 0x53, 0x53, 0x44, 0x54, 0x3e, 0x00, 0x00, 0x00, 0x02, + 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x4e, 0x54, 0x4c, 0x04, 0x06, 0x21, 0x20, + 0x10, 0x19, 0x5c, 0x5f, 0x53, 0x42, 0x5f, 0x14, 0x08, + 0x48, 0x57, 0x30, 0x30, 0x08, 0xa4, 0x00, 0x14, 0x09, + 0x48, 0x57, 0x34, 0x32, 0x08, 0xa4, 0x0a, 0x2a ) ); + +/** "MACA" SSDT2 (contains AUXMAC) */ +ACPI_TABLE ( maca_ssdt2, "SSDT", + DATA ( 0x53, 0x53, 0x44, 0x54, 0x54, 0x00, 0x00, 0x00, 0x02, + 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x4e, 0x54, 0x4c, 0x04, 0x06, 0x21, 0x20, + 0x10, 0x2f, 0x5c, 0x5f, 0x53, 0x42, 0x5f, 0x14, 0x1e, + 0x4d, 0x41, 0x43, 0x41, 0x08, 0x0d, 0x5f, 0x41, 0x55, + 0x58, 0x4d, 0x41, 0x43, 0x5f, 0x23, 0x35, 0x32, 0x35, + 0x34, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, + 0x23, 0x00, 0x14, 0x09, 0x48, 0x57, 0x39, 0x39, 0x08, + 0xa4, 0x0a, 0x63 ) ); + +/** "MACA" test tables */ +ACPI_TABLES ( maca_tables, &maca_ssdt1, &maca_ssdt2 ); + +/** "MACA" test */ +ACPI_MAC ( maca, &maca_tables, + DATA ( 0x52, 0x54, 0x00, 0x11, 0x22, 0x33 ) ); + +/** "RTMA" SSDT */ +ACPI_TABLE ( rtma_ssdt, "SSDT", + DATA ( 0x53, 0x53, 0x44, 0x54, 0x44, 0x00, 0x00, 0x00, 0x02, + 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x4e, 0x54, 0x4c, 0x04, 0x06, 0x21, 0x20, + 0x10, 0x1f, 0x5c, 0x5f, 0x53, 0x42, 0x5f, 0x14, 0x18, + 0x52, 0x54, 0x4d, 0x41, 0x08, 0x0d, 0x5f, 0x52, 0x54, + 0x58, 0x4d, 0x41, 0x43, 0x5f, 0x23, 0x52, 0x54, 0x30, + 0x30, 0x30, 0x31, 0x23, 0x00 ) ); + +/** "RTMA" test tables */ +ACPI_TABLES ( rtma_tables, &rtma_ssdt ); + +/** "RTMA" test */ +ACPI_MAC ( rtma, &rtma_tables, + DATA ( 0x52, 0x54, 0x30, 0x30, 0x30, 0x31 ) ); + +/** Current ACPI test table set */ +static struct acpi_test_tables *acpi_test_tables; + +/** + * Locate ACPI test table + * + * @v signature Requested table signature + * @v index Requested index of table with this signature + * @ret table Table, or UNULL if not found + */ +static userptr_t acpi_test_find ( uint32_t signature, unsigned int index ) { + struct acpi_test_table *table; + unsigned int i; + + /* Fail if no test tables are installed */ + if ( ! acpi_test_tables ) + return UNULL; + + /* Scan through test tables */ + for ( i = 0 ; i < acpi_test_tables->count ; i++ ) { + table = acpi_test_tables->table[i]; + if ( ( signature == le32_to_cpu ( table->signature.raw ) ) && + ( index-- == 0 ) ) { + return virt_to_user ( table->data ); + } + } + + return UNULL; +} + +/** Override ACPI table finder */ +typeof ( acpi_find ) *acpi_finder = acpi_test_find; + +/** + * Report ACPI MAC extraction test result + * + * @v test ACPI MAC extraction test + * @v file Test code file + * @v line Test code line + */ +static void acpi_mac_okx ( struct acpi_mac_test *test, + const char *file, unsigned int line ) { + uint8_t mac[ETH_ALEN]; + int rc; + + /* Set test table set */ + acpi_test_tables = test->tables; + + /* Extract MAC address */ + rc = acpi_mac ( mac ); + okx ( rc == 0, file, line ); + + /* Check extracted MAC address */ + okx ( memcmp ( mac, test->expected, ETH_ALEN ) == 0, file, line ); + + /* Clear test table set */ + acpi_test_tables = NULL; +} +#define acpi_mac_ok( test ) \ + acpi_mac_okx ( test, __FILE__, __LINE__ ) + +/** + * Perform ACPI self-test + * + */ +static void acpi_test_exec ( void ) { + + /* MAC extraction tests */ + acpi_mac_ok ( &amac ); + acpi_mac_ok ( &maca ); + acpi_mac_ok ( &rtma ); +} + +/** ACPI self-test */ +struct self_test acpi_test __self_test = { + .name = "acpi", + .exec = acpi_test_exec, +}; diff --git a/src/tests/settings_test.c b/src/tests/settings_test.c index 828901b06..5da7eb008 100644 --- a/src/tests/settings_test.c +++ b/src/tests/settings_test.c @@ -250,6 +250,12 @@ static struct setting test_uuid_setting = { .type = &setting_type_uuid, }; +/** Test GUID setting type */ +static struct setting test_guid_setting = { + .name = "test_guid", + .type = &setting_type_guid, +}; + /** Test PCI bus:dev.fn setting type */ static struct setting test_busdevfn_setting = { .name = "test_busdevfn", @@ -419,6 +425,10 @@ static void settings_test_exec ( void ) { RAW ( 0x1a, 0x6a, 0x74, 0x9d, 0x0e, 0xda, 0x46, 0x1a,0xa8, 0x7a, 0x7c, 0xfe, 0x4f, 0xca, 0x4a, 0x57 ), "1a6a749d-0eda-461a-a87a-7cfe4fca4a57" ); + fetchf_ok ( &test_settings, &test_guid_setting, + RAW ( 0x1a, 0x6a, 0x74, 0x9d, 0x0e, 0xda, 0x46, 0x1a,0xa8, + 0x7a, 0x7c, 0xfe, 0x4f, 0xca, 0x4a, 0x57 ), + "9d746a1a-da0e-1a46-a87a-7cfe4fca4a57" ); /* "busdevfn" setting type (no store capability) */ fetchf_ok ( &test_settings, &test_busdevfn_setting, diff --git a/src/tests/tests.c b/src/tests/tests.c index 1cc4c81e8..5dbbac1b1 100644 --- a/src/tests/tests.c +++ b/src/tests/tests.c @@ -75,3 +75,5 @@ REQUIRE_OBJECT ( pem_test ); REQUIRE_OBJECT ( ntlm_test ); REQUIRE_OBJECT ( zlib_test ); REQUIRE_OBJECT ( gzip_test ); +REQUIRE_OBJECT ( utf8_test ); +REQUIRE_OBJECT ( acpi_test ); diff --git a/src/tests/uri_test.c b/src/tests/uri_test.c index 92c2f9037..338f479cd 100644 --- a/src/tests/uri_test.c +++ b/src/tests/uri_test.c @@ -149,8 +149,10 @@ static void uri_okx ( struct uri *uri, struct uri *expected, const char *file, okx ( uristrcmp ( uri->host, expected->host ) == 0, file, line ); okx ( uristrcmp ( uri->port, expected->port ) == 0, file, line ); okx ( uristrcmp ( uri->path, expected->path ) == 0, file, line ); - okx ( uristrcmp ( uri->query, expected->query ) == 0, file, line ); - okx ( uristrcmp ( uri->fragment, expected->fragment ) == 0, file, line); + okx ( uristrcmp ( uri->epath, expected->epath ) == 0, file, line ); + okx ( uristrcmp ( uri->equery, expected->equery ) == 0, file, line ); + okx ( uristrcmp ( uri->efragment, expected->efragment ) == 0, + file, line); okx ( uri->params == expected->params, file, line ); } #define uri_ok( uri, expected ) uri_okx ( uri, expected, __FILE__, __LINE__ ) @@ -490,25 +492,33 @@ static struct uri_test uri_empty = { /** Basic HTTP URI */ static struct uri_test uri_boot_ipxe_org = { "http://boot.ipxe.org/demo/boot.php", - { .scheme = "http", .host = "boot.ipxe.org", .path = "/demo/boot.php" } + { .scheme = "http", .host = "boot.ipxe.org", + .path = "/demo/boot.php", .epath = "/demo/boot.php" }, }; /** Basic opaque URI */ static struct uri_test uri_mailto = { "mailto:ipxe-devel@lists.ipxe.org", - { .scheme = "mailto", .opaque = "ipxe-devel@lists.ipxe.org" } + { .scheme = "mailto", .opaque = "ipxe-devel@lists.ipxe.org" }, +}; + +/** Basic host-only URI */ +static struct uri_test uri_host = { + "http://boot.ipxe.org", + { .scheme = "http", .host = "boot.ipxe.org" }, }; /** Basic path-only URI */ static struct uri_test uri_path = { "/var/lib/tftpboot/pxelinux.0", - { .path = "/var/lib/tftpboot/pxelinux.0" }, + { .path = "/var/lib/tftpboot/pxelinux.0", + .epath ="/var/lib/tftpboot/pxelinux.0" }, }; /** Path-only URI with escaped characters */ static struct uri_test uri_path_escaped = { "/hello%20world%3F", - { .path = "/hello world?" }, + { .path = "/hello world?", .epath = "/hello%20world%3F" }, }; /** HTTP URI with all the trimmings */ @@ -521,8 +531,9 @@ static struct uri_test uri_http_all = { .host = "example.com", .port = "3001", .path = "/~foo/cgi-bin/foo.pl", - .query = "a=b&c=d", - .fragment = "bit", + .epath = "/~foo/cgi-bin/foo.pl", + .equery = "a=b&c=d", + .efragment = "bit", }, }; @@ -533,8 +544,9 @@ static struct uri_test uri_http_escaped = { .scheme = "https", .host = "test.ipxe.org", .path = "/wtf?\n", - .query = "kind#of/uri is", - .fragment = "this?", + .epath = "/wtf%3F%0A", + .equery = "kind%23of/uri%20is", + .efragment = "this%3F", }, }; @@ -550,8 +562,9 @@ static struct uri_test uri_http_escaped_improper = { .scheme = "https", .host = "test.ipxe.org", .path = "/wtf?\n", - .query = "kind#of/uri is", - .fragment = "this?", + .epath = "/wt%66%3f\n", + .equery = "kind%23of/uri is", + .efragment = "this?", }, }; @@ -562,6 +575,7 @@ static struct uri_test uri_ipv6 = { .scheme = "http", .host = "[2001:ba8:0:1d4::6950:5845]", .path = "/", + .epath = "/", }, }; @@ -573,6 +587,7 @@ static struct uri_test uri_ipv6_port = { .host = "[2001:ba8:0:1d4::6950:5845]", .port = "8001", .path = "/boot", + .epath = "/boot", }, }; @@ -583,6 +598,7 @@ static struct uri_test uri_ipv6_local = { .scheme = "http", .host = "[fe80::69ff:fe50:5845%net0]", .path = "/ipxe", + .epath = "/ipxe", }, }; @@ -598,6 +614,7 @@ static struct uri_test uri_ipv6_local_non_conforming = { .scheme = "http", .host = "[fe80::69ff:fe50:5845%net0]", .path = "/ipxe", + .epath = "/ipxe", }, }; @@ -625,6 +642,7 @@ static struct uri_test uri_file_absolute = { { .scheme = "file", .path = "/boot/script.ipxe", + .epath = "/boot/script.ipxe", }, }; @@ -635,6 +653,16 @@ static struct uri_test uri_file_volume = { .scheme = "file", .host = "hpilo", .path = "/boot/script.ipxe", + .epath = "/boot/script.ipxe", + }, +}; + +/** Relative URI with colons in path */ +static struct uri_test uri_colons = { + "/boot/52:54:00:12:34:56/boot.ipxe", + { + .path = "/boot/52:54:00:12:34:56/boot.ipxe", + .epath = "/boot/52:54:00:12:34:56/boot.ipxe", }, }; @@ -736,6 +764,7 @@ static struct uri_pxe_test uri_pxe_absolute = { .scheme = "http", .host = "not.a.tftp", .path = "/uri", + .epath = "/uri", }, "http://not.a.tftp/uri", }; @@ -754,6 +783,7 @@ static struct uri_pxe_test uri_pxe_absolute_path = { .scheme = "tftp", .host = "192.168.0.2", .path = "//absolute/path", + .epath = "//absolute/path", }, "tftp://192.168.0.2//absolute/path", }; @@ -772,6 +802,7 @@ static struct uri_pxe_test uri_pxe_relative_path = { .scheme = "tftp", .host = "192.168.0.3", .path = "/relative/path", + .epath = "/relative/path", }, "tftp://192.168.0.3/relative/path", }; @@ -790,8 +821,9 @@ static struct uri_pxe_test uri_pxe_icky = { .scheme = "tftp", .host = "10.0.0.6", .path = "/C:\\tftpboot\\icky#path", + .epath = "/C:\\tftpboot\\icky#path", }, - "tftp://10.0.0.6/C%3A\\tftpboot\\icky%23path", + "tftp://10.0.0.6/C:\\tftpboot\\icky#path", }; /** PXE URI with custom port */ @@ -810,6 +842,7 @@ static struct uri_pxe_test uri_pxe_port = { .host = "192.168.0.1", .port = "4069", .path = "//another/path", + .epath = "//another/path", }, "tftp://192.168.0.1:4069//another/path", }; @@ -873,6 +906,7 @@ static struct uri_params_test uri_params = { .scheme = "http", .host = "boot.ipxe.org", .path = "/demo/boot.php", + .epath = "/demo/boot.php", }, NULL, uri_params_list, @@ -902,6 +936,7 @@ static struct uri_params_test uri_named_params = { .host = "192.168.100.4", .port = "3001", .path = "/register", + .epath = "/register", }, "foo", uri_named_params_list, @@ -917,6 +952,7 @@ static void uri_test_exec ( void ) { uri_parse_format_dup_ok ( &uri_empty ); uri_parse_format_dup_ok ( &uri_boot_ipxe_org ); uri_parse_format_dup_ok ( &uri_mailto ); + uri_parse_format_dup_ok ( &uri_host ); uri_parse_format_dup_ok ( &uri_path ); uri_parse_format_dup_ok ( &uri_path_escaped ); uri_parse_format_dup_ok ( &uri_http_all ); @@ -930,6 +966,7 @@ static void uri_test_exec ( void ) { uri_parse_format_dup_ok ( &uri_file_relative ); uri_parse_format_dup_ok ( &uri_file_absolute ); uri_parse_format_dup_ok ( &uri_file_volume ); + uri_parse_format_dup_ok ( &uri_colons ); /** URI port number tests */ uri_port_ok ( &uri_explicit_port ); diff --git a/src/tests/utf8_test.c b/src/tests/utf8_test.c new file mode 100644 index 000000000..1996915cb --- /dev/null +++ b/src/tests/utf8_test.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2022 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * UTF-8 Unicode encoding tests + * + */ + +/* Forcibly enable assertions */ +#undef NDEBUG + +#include <string.h> +#include <ipxe/utf8.h> +#include <ipxe/test.h> + +/** A UTF-8 accumulation test */ +struct utf8_accumulate_test { + /** UTF-8 byte string */ + const char *bytes; + /** Expected character sequence */ + const unsigned int *expected; + /** Length */ + size_t len; +}; + +/** Define inline data */ +#define DATA(...) { __VA_ARGS__ } + +/** Define a UTF-8 accumulation test */ +#define UTF8_ACCUMULATE( name, BYTES, EXPECTED ) \ + static const char name ## _bytes[] = BYTES; \ + static const unsigned int name ## _expected[] = EXPECTED; \ + static struct utf8_accumulate_test name = { \ + .bytes = name ## _bytes, \ + .expected = name ## _expected, \ + .len = ( sizeof ( name ## _expected ) / \ + sizeof ( name ## _expected[0] ) ), \ + }; + +/** Basic ASCII test */ +UTF8_ACCUMULATE ( ascii, "Hello world!", + DATA ( 'H', 'e', 'l', 'l', 'o', ' ', + 'w', 'o', 'r', 'l', 'd', '!' ) ); + +/** Multi-byte character test */ +UTF8_ACCUMULATE ( multibyte, "Héllô wörld 🥳", + DATA ( 'H', 0, L'é', 'l', 'l', 0, L'ô', ' ', + 'w', 0, L'ö', 'r', 'l', 'd', ' ', + 0, 0, 0, 0x1f973 ) ); + +/** Stray continuation byte test */ +UTF8_ACCUMULATE ( stray_continuation, + DATA ( 'a', 0x81, 'b', 0xc3, 0x82, 0x83, 'c' ), + DATA ( 'a', 0xfffd, 'b', 0, 0xc2, 0xfffd, 'c' ) ); + +/** Missing continuation byte test */ +UTF8_ACCUMULATE ( missing_continuation, + DATA ( 'a', 0xc3, 'b', 0xe1, 0x86, 0xc3, 0x89, 'c' ), + DATA ( 'a', 0, 'b', 0, 0, 0, 0xc9, 'c' ) ); + +/** Illegal two-byte sequence test */ +UTF8_ACCUMULATE ( illegal_two, + DATA ( 'a', 0xc2, 0x80, 'b', 0xc1, 0xbf, 'c', 0xc0, 0x80, + 'd' ), + DATA ( 'a', 0, 0x80, 'b', 0, 0xfffd, 'c', 0, 0xfffd, 'd' ) ); + +/** Illegal three-byte sequence test */ +UTF8_ACCUMULATE ( illegal_three, + DATA ( 'a', 0xe0, 0xa0, 0x80, 'b', 0xe0, 0x9f, 0xbf, 'c', + 0xe0, 0x80, 0x80, 'd' ), + DATA ( 'a', 0, 0, 0x800, 'b', 0, 0, 0xfffd, 'c', + 0, 0, 0xfffd, 'd' ) ); + +/** Illegal four-byte sequence test */ +UTF8_ACCUMULATE ( illegal_four, + DATA ( 'a', 0xf0, 0x90, 0x80, 0x80, 'b', 0xf0, 0x8f, 0xbf, + 0xbf, 'c', 0xf0, 0x80, 0x80, 0x80, 'd' ), + DATA ( 'a', 0, 0, 0, 0x10000, 'b', 0, 0, 0, 0xfffd, 'c', + 0, 0, 0, 0xfffd, 'd' ) ); + +/** Illegal overlength sequence test */ +UTF8_ACCUMULATE ( illegal_length, + DATA ( 'a', 0xf8, 0xbf, 0xbf, 0xbf, 0xbf, 'b', 0xfc, 0xbf, + 0xbf, 0xbf, 0xbf, 0xbf, 'c', 0xfe, 0xbf, 0xbf, 0xbf, + 0xbf, 0xbf, 0xbf, 'd', 0xff, 0xbf, 0xbf, 0xbf, 0xbf, + 0xbf, 0xbf, 0xbf, 'e' ), + DATA ( 'a', 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 'b', + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 'c', + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 'd', 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 'e' ) ); + +/** + * Report UTF-8 accumulation test result + * + * @v test UTF-8 accumulation test + * @v file Test code file + * @v line Test code line + */ +static void utf8_accumulate_okx ( struct utf8_accumulate_test *test, + const char *file, unsigned int line ) { + struct utf8_accumulator utf8; + unsigned int character; + unsigned int i; + + /* Initialise accumulator */ + memset ( &utf8, 0, sizeof ( utf8 ) ); + + /* Test each byte in turn */ + for ( i = 0 ; i < test->len ; i++ ) { + character = utf8_accumulate ( &utf8, test->bytes[i] ); + DBGC ( test, "UTF8 byte %02x character %02x\n", + test->bytes[i], character ); + okx ( character == test->expected[i], file, line ); + } +} +#define utf8_accumulate_ok( test ) \ + utf8_accumulate_okx ( test, __FILE__, __LINE__ ) + +/** + * Perform UTF-8 self-test + * + */ +static void utf8_test_exec ( void ) { + + /* Accumulation tests */ + utf8_accumulate_ok ( &ascii ); + utf8_accumulate_ok ( &multibyte ); + utf8_accumulate_ok ( &stray_continuation ); + utf8_accumulate_ok ( &missing_continuation ); + utf8_accumulate_ok ( &illegal_two ); + utf8_accumulate_ok ( &illegal_three ); + utf8_accumulate_ok ( &illegal_four ); + utf8_accumulate_ok ( &illegal_length ); +} + +/** UTF-8 self-test */ +struct self_test utf8_test __self_test = { + .name = "utf8", + .exec = utf8_test_exec, +}; |
