A lot of goodness in this release. We're *very* close to running the UEFI Shell and SCT natively. The only missing piece are HII protocols. - FAT write support (needed for SCT) - improved FAT directory support (needed for SCT) - RTC support with QEMU -M virt - Sandbox support (run UEFI binaries in Linux - yay) - Proper UTF-16 support - EFI_UNICODE_COLLATION_PROTOCOL support (for UEFI Shell) - EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL support (for UEFI Shell) - Fix window size determination - Fix Tegra by explicitly unmapping RAM - Clean up handle entanglement - Lots of generic code cleanup -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJbq6+cAAoJECszeR4D/txgV1cP+wZPVsY/kRDwCZ8PODOIyLW/ YWWX0CHOUNIXcvWyrQQVflRKE7IbsoPNU+PxOze/toBZvNGZofCqd/P0sT0kk8UU /aQ55+Hn8/N4etysKxhk2uszBuEXZsOdprNV3H7tO9vKsMHpImAdLvIyviYK0eCF WnNsmDVFv/W4M5IWDJrS7KqwTuLPYE5Xli9BW/O2qi8NOvpfyb4EEqdL7OHyHAxe 8zpzyaRXJkPcgPkJ6z3WZ+BmAuXSl5DsLWqfsnZJQzkXatRhT8PneRk787e+xK3A OEFarj5t/94T1KivxquM9iYi0NzwGWrrCfRzbQh5klV4Z/bRYHbGQ92j6iZyfnpj 0zvWrJCalDaUz310BKZDyzKYQnoDj5/iYaMJHtaG6zmkXCzM41kniGKxuy/3IpTB ozeFtH2AOwlAFZRIzQiazkyU0bizis2Y/K4xzOQczvVajdLW0DsLXL/hyqaFaGO2 3oVK350FXMHKa1UhpsG05aoQvyYq8N4YVEfOSdBKah8qhhMG8zZ2IaX5oheZJjr4 yPV8iaSj8trX3mI9clsnX9YT7qJdcS188JYSii+8SVpVH4VpgwvUSHfDqznn7JNz COue6rFo9sg55Le9OsoxUgaQ5GO4oz+5iGmfyBmOtQ3n83JxmP4CJK84Ykw2i9fi sxJR6aNtktsLhfYhlDO/ =ZuJG -----END PGP SIGNATURE----- Merge tag 'signed-efi-next' of git://github.com/agraf/u-boot Patch queue for efi - 2018-09-26 A lot of goodness in this release. We're *very* close to running the UEFI Shell and SCT natively. The only missing piece are HII protocols. - FAT write support (needed for SCT) - improved FAT directory support (needed for SCT) - RTC support with QEMU -M virt - Sandbox support (run UEFI binaries in Linux - yay) - Proper UTF-16 support - EFI_UNICODE_COLLATION_PROTOCOL support (for UEFI Shell) - EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL support (for UEFI Shell) - Fix window size determination - Fix Tegra by explicitly unmapping RAM - Clean up handle entanglement - Lots of generic code cleanup [trini: Fixup merge conflict in include/configs/qemu-arm.h] Signed-off-by: Tom Rini <trini@konsulko.com>lime2-spi
commit
0ae8dcfef7
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,40 @@ |
||||
/* SPDX-License-Identifier: GPL-2.0+ */ |
||||
|
||||
/*
|
||||
* Constant CP1250 contains the Unicode code points for characters 0x80 - 0xff |
||||
* of the code page 1250. |
||||
*/ |
||||
#define CP1250 { \ |
||||
0x20ac, 0x0000, 0x201a, 0x0000, \
|
||||
0x201e, 0x2026, 0x2020, 0x2021, \
|
||||
0x0000, 0x2030, 0x0160, 0x2039, \
|
||||
0x015a, 0x0164, 0x017d, 0x0179, \
|
||||
0x0000, 0x2018, 0x2019, 0x201c, \
|
||||
0x201d, 0x2022, 0x2013, 0x2014, \
|
||||
0x0000, 0x2122, 0x0161, 0x203a, \
|
||||
0x015b, 0x0165, 0x017e, 0x017a, \
|
||||
0x00a0, 0x02c7, 0x02d8, 0x0141, \
|
||||
0x00a4, 0x0104, 0x00a6, 0x00a7, \
|
||||
0x00a8, 0x00a9, 0x015e, 0x00ab, \
|
||||
0x00ac, 0x00ad, 0x00ae, 0x017b, \
|
||||
0x00b0, 0x00b1, 0x02db, 0x0142, \
|
||||
0x00b4, 0x00b5, 0x00b6, 0x00b7, \
|
||||
0x00b8, 0x0105, 0x015f, 0x00bb, \
|
||||
0x013d, 0x02dd, 0x013e, 0x017c, \
|
||||
0x0154, 0x00c1, 0x00c2, 0x0102, \
|
||||
0x00c4, 0x0139, 0x0106, 0x00c7, \
|
||||
0x010c, 0x00c9, 0x0118, 0x00cb, \
|
||||
0x011a, 0x00cd, 0x00ce, 0x010e, \
|
||||
0x0110, 0x0143, 0x0147, 0x00d3, \
|
||||
0x00d4, 0x0150, 0x00d6, 0x00d7, \
|
||||
0x0158, 0x016e, 0x00da, 0x0170, \
|
||||
0x00dc, 0x00dd, 0x0162, 0x00df, \
|
||||
0x0155, 0x00e1, 0x00e2, 0x0103, \
|
||||
0x00e4, 0x013a, 0x0107, 0x00e7, \
|
||||
0x010d, 0x00e9, 0x0119, 0x00eb, \
|
||||
0x011b, 0x00ed, 0x00ee, 0x010f, \
|
||||
0x0111, 0x0144, 0x0148, 0x00f3, \
|
||||
0x00f4, 0x0151, 0x00f6, 0x00f7, \
|
||||
0x0159, 0x016f, 0x00fa, 0x0171, \
|
||||
0x00fc, 0x00fd, 0x0163, 0x02d9, \
|
||||
} |
@ -0,0 +1,40 @@ |
||||
/* SPDX-License-Identifier: GPL-2.0+ */ |
||||
|
||||
/*
|
||||
* Constant CP437 contains the Unicode code points for characters 0x80 - 0xff |
||||
* of the code page 437. |
||||
*/ |
||||
#define CP437 { \ |
||||
0x00c7, 0x00fc, 0x00e9, 0x00e2, \
|
||||
0x00e4, 0x00e0, 0x00e5, 0x00e7, \
|
||||
0x00ea, 0x00eb, 0x00e8, 0x00ef, \
|
||||
0x00ee, 0x00ec, 0x00c4, 0x00c5, \
|
||||
0x00c9, 0x00e6, 0x00c6, 0x00f4, \
|
||||
0x00f6, 0x00f2, 0x00fb, 0x00f9, \
|
||||
0x00ff, 0x00d6, 0x00dc, 0x00a2, \
|
||||
0x00a3, 0x00a5, 0x20a7, 0x0192, \
|
||||
0x00e1, 0x00ed, 0x00f3, 0x00fa, \
|
||||
0x00f1, 0x00d1, 0x00aa, 0x00ba, \
|
||||
0x00bf, 0x2310, 0x00ac, 0x00bd, \
|
||||
0x00bc, 0x00a1, 0x00ab, 0x00bb, \
|
||||
0x2591, 0x2592, 0x2593, 0x2502, \
|
||||
0x2524, 0x2561, 0x2562, 0x2556, \
|
||||
0x2555, 0x2563, 0x2551, 0x2557, \
|
||||
0x255d, 0x255c, 0x255b, 0x2510, \
|
||||
0x2514, 0x2534, 0x252c, 0x251c, \
|
||||
0x2500, 0x253c, 0x255e, 0x255f, \
|
||||
0x255a, 0x2554, 0x2569, 0x2566, \
|
||||
0x2560, 0x2550, 0x256c, 0x2567, \
|
||||
0x2568, 0x2564, 0x2565, 0x2559, \
|
||||
0x2558, 0x2552, 0x2553, 0x256b, \
|
||||
0x256a, 0x2518, 0x250c, 0x2588, \
|
||||
0x2584, 0x258c, 0x2590, 0x2580, \
|
||||
0x03b1, 0x00df, 0x0393, 0x03c0, \
|
||||
0x03a3, 0x03c3, 0x00b5, 0x03c4, \
|
||||
0x03a6, 0x0398, 0x03a9, 0x03b4, \
|
||||
0x221e, 0x03c6, 0x03b5, 0x2229, \
|
||||
0x2261, 0x00b1, 0x2265, 0x2264, \
|
||||
0x2320, 0x2321, 0x00f7, 0x2248, \
|
||||
0x00b0, 0x2219, 0x00b7, 0x221a, \
|
||||
0x207f, 0x00b2, 0x25a0, 0x00a0, \
|
||||
} |
@ -0,0 +1,79 @@ |
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Root node for system services |
||||
* |
||||
* Copyright (c) 2018 Heinrich Schuchardt |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <malloc.h> |
||||
#include <efi_loader.h> |
||||
|
||||
const efi_guid_t efi_u_boot_guid = U_BOOT_GUID; |
||||
|
||||
struct efi_root_dp { |
||||
struct efi_device_path_vendor vendor; |
||||
struct efi_device_path end; |
||||
} __packed; |
||||
|
||||
/**
|
||||
* efi_root_node_register() - create root node |
||||
* |
||||
* Create the root node on which we install all protocols that are |
||||
* not related to a loaded image or a driver. |
||||
* |
||||
* Return: status code |
||||
*/ |
||||
efi_status_t efi_root_node_register(void) |
||||
{ |
||||
efi_handle_t root; |
||||
efi_status_t ret; |
||||
struct efi_root_dp *dp; |
||||
|
||||
/* Create handle */ |
||||
ret = efi_create_handle(&root); |
||||
if (ret != EFI_SUCCESS) |
||||
return ret; |
||||
|
||||
/* Install device path protocol */ |
||||
dp = calloc(1, sizeof(*dp)); |
||||
if (!dp) |
||||
return EFI_OUT_OF_RESOURCES; |
||||
|
||||
/* Fill vendor node */ |
||||
dp->vendor.dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE; |
||||
dp->vendor.dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR; |
||||
dp->vendor.dp.length = sizeof(struct efi_device_path_vendor); |
||||
dp->vendor.guid = efi_u_boot_guid; |
||||
|
||||
/* Fill end node */ |
||||
dp->end.type = DEVICE_PATH_TYPE_END; |
||||
dp->end.sub_type = DEVICE_PATH_SUB_TYPE_END; |
||||
dp->end.length = sizeof(struct efi_device_path); |
||||
|
||||
/* Install device path protocol */ |
||||
ret = efi_add_protocol(root, &efi_guid_device_path, dp); |
||||
if (ret != EFI_SUCCESS) |
||||
goto failure; |
||||
|
||||
/* Install device path to text protocol */ |
||||
ret = efi_add_protocol(root, &efi_guid_device_path_to_text_protocol, |
||||
(void *)&efi_device_path_to_text); |
||||
if (ret != EFI_SUCCESS) |
||||
goto failure; |
||||
|
||||
/* Install device path utilities protocol */ |
||||
ret = efi_add_protocol(root, &efi_guid_device_path_utilities_protocol, |
||||
(void *)&efi_device_path_utilities); |
||||
if (ret != EFI_SUCCESS) |
||||
goto failure; |
||||
|
||||
/* Install Unicode collation protocol */ |
||||
ret = efi_add_protocol(root, &efi_guid_unicode_collation_protocol, |
||||
(void *)&efi_unicode_collation_protocol); |
||||
if (ret != EFI_SUCCESS) |
||||
goto failure; |
||||
|
||||
failure: |
||||
return ret; |
||||
} |
@ -0,0 +1,329 @@ |
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* EFI Unicode collation protocol |
||||
* |
||||
* Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de> |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <charset.h> |
||||
#include <cp1250.h> |
||||
#include <cp437.h> |
||||
#include <efi_loader.h> |
||||
|
||||
/* Characters that may not be used in file names */ |
||||
static const char illegal[] = "<>:\"/\\|?*"; |
||||
|
||||
/*
|
||||
* EDK2 assumes codepage 1250 when creating FAT 8.3 file names. |
||||
* Linux defaults to codepage 437 for FAT 8.3 file names. |
||||
*/ |
||||
#if CONFIG_FAT_DEFAULT_CODEPAGE == 1250 |
||||
/* Unicode code points for code page 1250 characters 0x80 - 0xff */ |
||||
static const u16 codepage[] = CP1250; |
||||
#else |
||||
/* Unicode code points for code page 437 characters 0x80 - 0xff */ |
||||
static const u16 codepage[] = CP437; |
||||
#endif |
||||
|
||||
/* GUID of the EFI_UNICODE_COLLATION_PROTOCOL */ |
||||
const efi_guid_t efi_guid_unicode_collation_protocol = |
||||
EFI_UNICODE_COLLATION_PROTOCOL2_GUID; |
||||
|
||||
/**
|
||||
* efi_stri_coll() - compare utf-16 strings case-insenitively |
||||
* |
||||
* @this: unicode collation protocol instance |
||||
* @s1: first string |
||||
* @s2: second string |
||||
* |
||||
* This function implements the StriColl() service of the |
||||
* EFI_UNICODE_COLLATION_PROTOCOL. |
||||
* |
||||
* See the Unified Extensible Firmware Interface (UEFI) specification for |
||||
* details. |
||||
* |
||||
* TODO: |
||||
* The implementation does not follow the Unicode collation algorithm. |
||||
* For ASCII characters it results in the same sort order as EDK2. |
||||
* We could use table UNICODE_CAPITALIZATION_TABLE for better results. |
||||
* |
||||
* Return: 0: s1 == s2, > 0: s1 > s2, < 0: s1 < s2 |
||||
*/ |
||||
static efi_intn_t EFIAPI efi_stri_coll( |
||||
struct efi_unicode_collation_protocol *this, u16 *s1, u16 *s2) |
||||
{ |
||||
s32 c1, c2; |
||||
efi_intn_t ret = 0; |
||||
|
||||
EFI_ENTRY("%p, %ls, %ls", this, s1, s2); |
||||
for (; *s1 | *s2; ++s1, ++s2) { |
||||
c1 = utf_to_upper(*s1); |
||||
c2 = utf_to_upper(*s2); |
||||
if (c1 < c2) { |
||||
ret = -1; |
||||
goto out; |
||||
} else if (c1 > c2) { |
||||
ret = 1; |
||||
goto out; |
||||
} |
||||
} |
||||
out: |
||||
EFI_EXIT(EFI_SUCCESS); |
||||
return ret; |
||||
} |
||||
|
||||
/**
|
||||
* metai_match() - compare utf-16 string with a pattern string case-insenitively |
||||
* |
||||
* @s: string to compare |
||||
* @p: pattern string |
||||
* |
||||
* The pattern string may use these: |
||||
* - * matches >= 0 characters |
||||
* - ? matches 1 character |
||||
* - [<char1><char2>...<charN>] match any character in the set |
||||
* - [<char1>-<char2>] matches any character in the range |
||||
* |
||||
* This function is called my efi_metai_match(). |
||||
* |
||||
* For '*' pattern searches this function calls itself recursively. |
||||
* Performance-wise this is suboptimal, especially for multiple '*' wildcards. |
||||
* But it results in simple code. |
||||
* |
||||
* Return: true if the string is matched. |
||||
*/ |
||||
static bool metai_match(const u16 *s, const u16 *p) |
||||
{ |
||||
u16 first; |
||||
|
||||
for (; *s && *p; ++s, ++p) { |
||||
switch (*p) { |
||||
case '*': |
||||
/* Match 0 or more characters */ |
||||
++p; |
||||
for (;; ++s) { |
||||
if (metai_match(s, p)) |
||||
return true; |
||||
if (!*s) |
||||
return false; |
||||
} |
||||
case '?': |
||||
/* Match any one character */ |
||||
break; |
||||
case '[': |
||||
/* Match any character in the set */ |
||||
++p; |
||||
first = *p; |
||||
if (first == ']') |
||||
/* Empty set */ |
||||
return false; |
||||
++p; |
||||
if (*p == '-') { |
||||
/* Range */ |
||||
++p; |
||||
if (*s < first || *s > *p) |
||||
return false; |
||||
++p; |
||||
if (*p != ']') |
||||
return false; |
||||
} else { |
||||
/* Set */ |
||||
bool hit = false; |
||||
|
||||
if (*s == first) |
||||
hit = true; |
||||
for (; *p && *p != ']'; ++p) { |
||||
if (*p == *s) |
||||
hit = true; |
||||
} |
||||
if (!hit || *p != ']') |
||||
return false; |
||||
} |
||||
break; |
||||
default: |
||||
/* Match one character */ |
||||
if (*p != *s) |
||||
return false; |
||||
} |
||||
} |
||||
if (!*p && !*s) |
||||
return true; |
||||
return false; |
||||
} |
||||
|
||||
/**
|
||||
* efi_metai_match() - compare utf-16 string with a pattern string |
||||
* case-insenitively |
||||
* |
||||
* @this: unicode collation protocol instance |
||||
* @s: string to compare |
||||
* @p: pattern string |
||||
* |
||||
* The pattern string may use these: |
||||
* - * matches >= 0 characters |
||||
* - ? matches 1 character |
||||
* - [<char1><char2>...<charN>] match any character in the set |
||||
* - [<char1>-<char2>] matches any character in the range |
||||
* |
||||
* This function implements the MetaMatch() service of the |
||||
* EFI_UNICODE_COLLATION_PROTOCOL. |
||||
* |
||||
* Return: true if the string is matched. |
||||
*/ |
||||
static bool EFIAPI efi_metai_match(struct efi_unicode_collation_protocol *this, |
||||
const u16 *string, const u16 *pattern) |
||||
{ |
||||
bool ret; |
||||
|
||||
EFI_ENTRY("%p, %ls, %ls", this, string, pattern); |
||||
ret = metai_match(string, pattern); |
||||
EFI_EXIT(EFI_SUCCESS); |
||||
return ret; |
||||
} |
||||
|
||||
/**
|
||||
* efi_str_lwr() - convert to lower case |
||||
* |
||||
* @this: unicode collation protocol instance |
||||
* @string: string to convert |
||||
* @p: pattern string |
||||
* |
||||
* The conversion is done in place. As long as upper and lower letters use the |
||||
* same number of words this does not pose a problem. |
||||
* |
||||
* This function implements the StrLwr() service of the |
||||
* EFI_UNICODE_COLLATION_PROTOCOL. |
||||
*/ |
||||
static void EFIAPI efi_str_lwr(struct efi_unicode_collation_protocol *this, |
||||
u16 *string) |
||||
{ |
||||
EFI_ENTRY("%p, %ls", this, string); |
||||
for (; *string; ++string) |
||||
*string = utf_to_lower(*string); |
||||
EFI_EXIT(EFI_SUCCESS); |
||||
} |
||||
|
||||
/**
|
||||
* efi_str_upr() - convert to upper case |
||||
* |
||||
* @this: unicode collation protocol instance |
||||
* @string: string to convert |
||||
* @p: pattern string |
||||
* |
||||
* The conversion is done in place. As long as upper and lower letters use the |
||||
* same number of words this does not pose a problem. |
||||
* |
||||
* This function implements the StrUpr() service of the |
||||
* EFI_UNICODE_COLLATION_PROTOCOL. |
||||
*/ |
||||
static void EFIAPI efi_str_upr(struct efi_unicode_collation_protocol *this, |
||||
u16 *string) |
||||
{ |
||||
EFI_ENTRY("%p, %ls", this, string); |
||||
for (; *string; ++string) |
||||
*string = utf_to_upper(*string); |
||||
EFI_EXIT(EFI_SUCCESS); |
||||
} |
||||
|
||||
/**
|
||||
* efi_fat_to_str() - convert an 8.3 file name from an OEM codepage to Unicode |
||||
* |
||||
* @this: unicode collation protocol instance |
||||
* @fat_size: size of the string to convert |
||||
* @fat: string to convert |
||||
* @string: converted string |
||||
* |
||||
* This function implements the FatToStr() service of the |
||||
* EFI_UNICODE_COLLATION_PROTOCOL. |
||||
*/ |
||||
static void EFIAPI efi_fat_to_str(struct efi_unicode_collation_protocol *this, |
||||
efi_uintn_t fat_size, char *fat, u16 *string) |
||||
{ |
||||
efi_uintn_t i; |
||||
u16 c; |
||||
|
||||
EFI_ENTRY("%p, %zu, %s, %p", this, fat_size, fat, string); |
||||
for (i = 0; i < fat_size; ++i) { |
||||
c = (unsigned char)fat[i]; |
||||
if (c > 0x80) |
||||
c = codepage[i - 0x80]; |
||||
string[i] = c; |
||||
if (!c) |
||||
break; |
||||
} |
||||
string[i] = 0; |
||||
EFI_EXIT(EFI_SUCCESS); |
||||
} |
||||
|
||||
/**
|
||||
* efi_fat_to_str() - convert a utf-16 string to legal characters for a FAT |
||||
* file name in an OEM code page |
||||
* |
||||
* @this: unicode collation protocol instance |
||||
* @string: Unicode string to convert |
||||
* @fat_size: size of the target buffer |
||||
* @fat: converted string |
||||
* |
||||
* This function implements the StrToFat() service of the |
||||
* EFI_UNICODE_COLLATION_PROTOCOL. |
||||
* |
||||
* Return: true if an illegal character was substituted by '_'. |
||||
*/ |
||||
static bool EFIAPI efi_str_to_fat(struct efi_unicode_collation_protocol *this, |
||||
const u16 *string, efi_uintn_t fat_size, |
||||
char *fat) |
||||
{ |
||||
efi_uintn_t i; |
||||
s32 c; |
||||
bool ret = false; |
||||
|
||||
EFI_ENTRY("%p, %ls, %zu, %p", this, string, fat_size, fat); |
||||
for (i = 0; i < fat_size;) { |
||||
c = utf16_get(&string); |
||||
switch (c) { |
||||
/* Ignore period and space */ |
||||
case '.': |
||||
case ' ': |
||||
continue; |
||||
case 0: |
||||
break; |
||||
} |
||||
c = utf_to_upper(c); |
||||
if (c >= 0x80) { |
||||
int j; |
||||
|
||||
/* Look for codepage translation */ |
||||
for (j = 0; j < 0x80; ++j) { |
||||
if (c == codepage[j]) { |
||||
c = j + 0x80; |
||||
break; |
||||
} |
||||
} |
||||
if (j >= 0x80) { |
||||
c = '_'; |
||||
ret = true; |
||||
} |
||||
} else if (c && (c < 0x20 || strchr(illegal, c))) { |
||||
c = '_'; |
||||
ret = true; |
||||
} |
||||
|
||||
fat[i] = c; |
||||
if (!c) |
||||
break; |
||||
++i; |
||||
} |
||||
EFI_EXIT(EFI_SUCCESS); |
||||
return ret; |
||||
} |
||||
|
||||
const struct efi_unicode_collation_protocol efi_unicode_collation_protocol = { |
||||
.stri_coll = efi_stri_coll, |
||||
.metai_match = efi_metai_match, |
||||
.str_lwr = efi_str_lwr, |
||||
.str_upr = efi_str_upr, |
||||
.fat_to_str = efi_fat_to_str, |
||||
.str_to_fat = efi_str_to_fat, |
||||
.supported_languages = "en", |
||||
}; |
@ -0,0 +1,108 @@ |
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* efi_selftest_loaded_image |
||||
* |
||||
* Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de> |
||||
* |
||||
* This unit test checks the Loaded Image Protocol. |
||||
*/ |
||||
|
||||
#include <efi_selftest.h> |
||||
|
||||
static efi_guid_t loaded_image_protocol_guid = |
||||
EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, |
||||
0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b); |
||||
static struct efi_boot_services *boottime; |
||||
efi_handle_t image_handle; |
||||
|
||||
/*
|
||||
* Setup unit test. |
||||
* |
||||
* @handle: handle of the loaded image |
||||
* @systable: system table |
||||
*/ |
||||
static int setup(const efi_handle_t img_handle, |
||||
const struct efi_system_table *systable) |
||||
{ |
||||
boottime = systable->boottime; |
||||
image_handle = img_handle; |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
/*
|
||||
* Execute unit test. |
||||
* |
||||
* Verify that the loaded image protocol is installed on the image handle. |
||||
* Verify that the loaded image protocol points to the system table. |
||||
*/ |
||||
static int execute(void) |
||||
{ |
||||
efi_status_t ret; |
||||
efi_uintn_t i, protocol_buffer_count = 0; |
||||
efi_guid_t **protocol_buffer = NULL; |
||||
bool found = false; |
||||
struct efi_loaded_image *loaded_image_protocol; |
||||
|
||||
/*
|
||||
* Get the GUIDs of all protocols installed on the handle. |
||||
*/ |
||||
ret = boottime->protocols_per_handle(image_handle, &protocol_buffer, |
||||
&protocol_buffer_count); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("ProtocolsPerHandle failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (!protocol_buffer_count | !protocol_buffer) { |
||||
efi_st_error("ProtocolsPerHandle returned no protocol\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
efi_st_printf("%u protocols installed on image handle\n", |
||||
(unsigned int)protocol_buffer_count); |
||||
for (i = 0; i < protocol_buffer_count; ++i) { |
||||
if (efi_st_memcmp(protocol_buffer[i], |
||||
&loaded_image_protocol_guid, |
||||
sizeof(efi_guid_t))) |
||||
found = true; |
||||
} |
||||
if (!found) { |
||||
efi_st_printf("LoadedImageProtocol not found\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = boottime->free_pool(protocol_buffer); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("FreePool failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
/*
|
||||
* Open the loaded image protocol. |
||||
*/ |
||||
ret = boottime->open_protocol(image_handle, &loaded_image_protocol_guid, |
||||
(void **)&loaded_image_protocol, NULL, |
||||
NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("OpenProtocol failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (loaded_image_protocol->revision != |
||||
EFI_LOADED_IMAGE_PROTOCOL_REVISION) { |
||||
efi_st_printf("Incorrect revision\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (!loaded_image_protocol->system_table || |
||||
loaded_image_protocol->system_table->hdr.signature != |
||||
EFI_SYSTEM_TABLE_SIGNATURE) { |
||||
efi_st_printf("System table reference missing\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
EFI_UNIT_TEST(loadedimage) = { |
||||
.name = "loaded image", |
||||
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, |
||||
.setup = setup, |
||||
.execute = execute, |
||||
}; |
@ -0,0 +1,198 @@ |
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* efi_selftest_textinput |
||||
* |
||||
* Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de> |
||||
* |
||||
* Provides a unit test for the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL. |
||||
* The unicode character and the scan code are printed for text |
||||
* input. To run the test: |
||||
* |
||||
* setenv efi_selftest extended text input |
||||
* bootefi selftest |
||||
*/ |
||||
|
||||
#include <efi_selftest.h> |
||||
|
||||
static const efi_guid_t text_input_ex_protocol_guid = |
||||
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID; |
||||
|
||||
static struct efi_simple_text_input_ex_protocol *con_in_ex; |
||||
|
||||
static struct efi_boot_services *boottime; |
||||
|
||||
static void *efi_key_notify_handle; |
||||
static bool efi_running; |
||||
|
||||
/**
|
||||
* efi_key_notify_function() - key notification function |
||||
* |
||||
* This function is called when the registered key is hit. |
||||
* |
||||
* @key_data: next key |
||||
* Return: status code |
||||
*/ |
||||
static efi_status_t EFIAPI efi_key_notify_function |
||||
(struct efi_key_data *key_data) |
||||
{ |
||||
efi_running = false; |
||||
|
||||
return EFI_SUCCESS; |
||||
} |
||||
|
||||
/*
|
||||
* Setup unit test. |
||||
* |
||||
* @handle: handle of the loaded image |
||||
* @systable: system table |
||||
* @return: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int setup(const efi_handle_t handle, |
||||
const struct efi_system_table *systable) |
||||
{ |
||||
efi_status_t ret; |
||||
struct efi_key_data key_data = { |
||||
.key = { |
||||
.scan_code = 0, |
||||
.unicode_char = 0x18 |
||||
}, |
||||
.key_state = { |
||||
.key_shift_state = EFI_SHIFT_STATE_VALID | |
||||
EFI_LEFT_CONTROL_PRESSED, |
||||
.key_toggle_state = EFI_TOGGLE_STATE_INVALID, |
||||
}, |
||||
}; |
||||
|
||||
boottime = systable->boottime; |
||||
|
||||
ret = boottime->locate_protocol(&text_input_ex_protocol_guid, NULL, |
||||
(void **)&con_in_ex); |
||||
if (ret != EFI_SUCCESS) { |
||||
con_in_ex = NULL; |
||||
efi_st_error |
||||
("Extended text input protocol is not available.\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = con_in_ex->register_key_notify(con_in_ex, &key_data, |
||||
efi_key_notify_function, |
||||
&efi_key_notify_handle); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_key_notify_handle = NULL; |
||||
efi_st_error |
||||
("Notify function could not be registered.\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
efi_running = true; |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
/*
|
||||
* Tear down unit test. |
||||
* |
||||
* Unregister notify function. |
||||
* |
||||
* @return: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int teardown(void) |
||||
{ |
||||
efi_status_t ret; |
||||
|
||||
ret = con_in_ex->unregister_key_notify |
||||
(con_in_ex, efi_key_notify_handle); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error |
||||
("Notify function could not be registered.\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
/*
|
||||
* Execute unit test. |
||||
* |
||||
* @return: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int execute(void) |
||||
{ |
||||
struct efi_key_data input_key = { {0, 0}, {0, 0} }; |
||||
efi_status_t ret; |
||||
efi_uintn_t index; |
||||
|
||||
if (!con_in_ex) { |
||||
efi_st_printf("Setup failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
/* Drain the console input */ |
||||
ret = con_in_ex->reset(con_in_ex, true); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("Reset failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = con_in_ex->read_key_stroke_ex(con_in_ex, &input_key); |
||||
if (ret != EFI_NOT_READY) { |
||||
efi_st_error("Empty buffer not reported\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
efi_st_printf("Waiting for your input\n"); |
||||
efi_st_printf("To terminate type 'CTRL+x'\n"); |
||||
|
||||
while (efi_running) { |
||||
/* Wait for next key */ |
||||
ret = boottime->wait_for_event(1, &con_in_ex->wait_for_key_ex, |
||||
&index); |
||||
if (ret != EFI_ST_SUCCESS) { |
||||
efi_st_error("WaitForEvent failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = con_in_ex->read_key_stroke_ex(con_in_ex, &input_key); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("ReadKeyStroke failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
/* Allow 5 minutes until time out */ |
||||
boottime->set_watchdog_timer(300, 0, 0, NULL); |
||||
|
||||
efi_st_printf("Unicode char %u (%ps), scan code %u (", |
||||
(unsigned int)input_key.key.unicode_char, |
||||
efi_st_translate_char(input_key.key.unicode_char), |
||||
(unsigned int)input_key.key.scan_code); |
||||
if (input_key.key_state.key_shift_state & |
||||
EFI_SHIFT_STATE_VALID) { |
||||
if (input_key.key_state.key_shift_state & |
||||
(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED)) |
||||
efi_st_printf("SHIFT+"); |
||||
if (input_key.key_state.key_shift_state & |
||||
(EFI_LEFT_ALT_PRESSED | EFI_RIGHT_ALT_PRESSED)) |
||||
efi_st_printf("ALT+"); |
||||
if (input_key.key_state.key_shift_state & |
||||
(EFI_LEFT_CONTROL_PRESSED | |
||||
EFI_RIGHT_CONTROL_PRESSED)) |
||||
efi_st_printf("CTRL+"); |
||||
if (input_key.key_state.key_shift_state & |
||||
(EFI_LEFT_LOGO_PRESSED | EFI_RIGHT_LOGO_PRESSED)) |
||||
efi_st_printf("META+"); |
||||
if (input_key.key_state.key_shift_state == |
||||
EFI_SHIFT_STATE_VALID) |
||||
efi_st_printf("+"); |
||||
} |
||||
|
||||
efi_st_printf("%ps)\n", |
||||
efi_st_translate_code(input_key.key.scan_code)); |
||||
|
||||
} |
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
EFI_UNIT_TEST(textinputex) = { |
||||
.name = "extended text input", |
||||
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, |
||||
.setup = setup, |
||||
.execute = execute, |
||||
.teardown = teardown, |
||||
.on_request = true, |
||||
}; |
@ -0,0 +1,260 @@ |
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* efi_selftest_unicode_collation |
||||
* |
||||
* Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de> |
||||
* |
||||
* Test unicode collation protocol. |
||||
*/ |
||||
|
||||
#include <efi_selftest.h> |
||||
|
||||
static const efi_guid_t unicode_collation_protocol_guid = |
||||
EFI_UNICODE_COLLATION_PROTOCOL2_GUID; |
||||
|
||||
static struct efi_boot_services *boottime; |
||||
|
||||
static struct efi_unicode_collation_protocol *unicode_collation_protocol; |
||||
|
||||
/**
|
||||
* setup() - setup unit test. |
||||
* |
||||
* @handle: handle of the loaded image |
||||
* @systable: system table |
||||
* ReturnValue: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int setup(const efi_handle_t handle, |
||||
const struct efi_system_table *systable) |
||||
{ |
||||
efi_status_t ret; |
||||
|
||||
boottime = systable->boottime; |
||||
|
||||
ret = boottime->locate_protocol(&unicode_collation_protocol_guid, NULL, |
||||
(void **)&unicode_collation_protocol); |
||||
if (ret != EFI_SUCCESS) { |
||||
unicode_collation_protocol = NULL; |
||||
efi_st_error("Unicode collation protocol is not available.\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
static int test_stri_coll(void) |
||||
{ |
||||
efi_intn_t ret; |
||||
u16 c1[] = L"first"; |
||||
u16 c2[] = L"FIRST"; |
||||
u16 c3[] = L"second"; |
||||
|
||||
ret = unicode_collation_protocol->stri_coll(unicode_collation_protocol, |
||||
c1, c2); |
||||
if (ret) { |
||||
efi_st_error( |
||||
"stri_coll(\"%ps\", \"%ps\") = %zu\n", c1, c2, ret); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = unicode_collation_protocol->stri_coll(unicode_collation_protocol, |
||||
c1, c3); |
||||
if (ret >= 0) { |
||||
efi_st_error( |
||||
"stri_coll(\"%ps\", \"%ps\") = %zu\n", c1, c3, ret); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = unicode_collation_protocol->stri_coll(unicode_collation_protocol, |
||||
c3, c1); |
||||
if (ret <= 0) { |
||||
efi_st_error( |
||||
"stri_coll(\"%ps\", \"%ps\") = %zu\n", c3, c1, ret); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
static int test_metai_match(void) |
||||
{ |
||||
bool ret; |
||||
const u16 c[] = L"Das U-Boot"; |
||||
|
||||
ret = unicode_collation_protocol->metai_match( |
||||
unicode_collation_protocol, c, L"*"); |
||||
if (!ret) { |
||||
efi_st_error("metai_match returned %u\n", ret); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = unicode_collation_protocol->metai_match( |
||||
unicode_collation_protocol, c, L"Da[rstu] U-Boot"); |
||||
if (!ret) { |
||||
efi_st_error("metai_match returned %u\n", ret); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = unicode_collation_protocol->metai_match( |
||||
unicode_collation_protocol, c, L"Da[q-v] U-Boot"); |
||||
if (!ret) { |
||||
efi_st_error("metai_match returned %u\n", ret); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = unicode_collation_protocol->metai_match( |
||||
unicode_collation_protocol, c, L"Da? U-Boot"); |
||||
if (!ret) { |
||||
efi_st_error("metai_match returned %u\n", ret); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = unicode_collation_protocol->metai_match( |
||||
unicode_collation_protocol, c, L"D*Bo*t"); |
||||
if (!ret) { |
||||
efi_st_error("metai_match returned %u\n", ret); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = unicode_collation_protocol->metai_match( |
||||
unicode_collation_protocol, c, L"Da[xyz] U-Boot"); |
||||
if (ret) { |
||||
efi_st_error("metai_match returned %u\n", ret); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = unicode_collation_protocol->metai_match( |
||||
unicode_collation_protocol, c, L"Da[a-d] U-Boot"); |
||||
if (ret) { |
||||
efi_st_error("metai_match returned %u\n", ret); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = unicode_collation_protocol->metai_match( |
||||
unicode_collation_protocol, c, L"Da?? U-Boot"); |
||||
if (ret) { |
||||
efi_st_error("metai_match returned %u\n", ret); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = unicode_collation_protocol->metai_match( |
||||
unicode_collation_protocol, c, L"D*Bo*tt"); |
||||
if (ret) { |
||||
efi_st_error("metai_match returned %u\n", ret); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
static int test_str_lwr(void) |
||||
{ |
||||
u16 c[] = L"U-Boot"; |
||||
|
||||
unicode_collation_protocol->str_lwr(unicode_collation_protocol, c); |
||||
if (efi_st_strcmp_16_8(c, "u-boot")) { |
||||
efi_st_error("str_lwr returned \"%ps\"\n", c); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
static int test_str_upr(void) |
||||
{ |
||||
u16 c[] = L"U-Boot"; |
||||
|
||||
unicode_collation_protocol->str_upr(unicode_collation_protocol, c); |
||||
if (efi_st_strcmp_16_8(c, "U-BOOT")) { |
||||
efi_st_error("str_lwr returned \"%ps\"\n", c); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
static int test_fat_to_str(void) |
||||
{ |
||||
u16 str[16]; |
||||
|
||||
boottime->set_mem(str, sizeof(str), 0); |
||||
unicode_collation_protocol->fat_to_str(unicode_collation_protocol, 6, |
||||
"U-BOOT", str); |
||||
if (efi_st_strcmp_16_8(str, "U-BOOT")) { |
||||
efi_st_error("fat_to_str returned \"%ps\"\n", str); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
static int test_str_to_fat(void) |
||||
{ |
||||
char fat[16]; |
||||
bool ret; |
||||
|
||||
boottime->set_mem(fat, sizeof(fat), 0); |
||||
ret = unicode_collation_protocol->str_to_fat(unicode_collation_protocol, |
||||
L"U -Boo.t", 6, fat); |
||||
if (ret || efi_st_strcmp_16_8(L"U-BOOT", fat)) { |
||||
efi_st_error("str_to_fat returned %u, \"%s\"\n", ret, fat); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
boottime->set_mem(fat, 16, 0); |
||||
ret = unicode_collation_protocol->str_to_fat(unicode_collation_protocol, |
||||
L"U\\Boot", 6, fat); |
||||
if (!ret || efi_st_strcmp_16_8(L"U_BOOT", fat)) { |
||||
efi_st_error("str_to_fat returned %u, \"%s\"\n", ret, fat); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
/**
|
||||
* execute() - Execute unit test. |
||||
* |
||||
* ReturnValue: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int execute(void) |
||||
{ |
||||
int ret; |
||||
|
||||
if (!unicode_collation_protocol) { |
||||
efi_st_printf("Unicode collation protocol missing\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = test_stri_coll(); |
||||
if (ret != EFI_ST_SUCCESS) |
||||
return ret; |
||||
|
||||
ret = test_metai_match(); |
||||
if (ret != EFI_ST_SUCCESS) |
||||
return ret; |
||||
|
||||
ret = test_str_lwr(); |
||||
if (ret != EFI_ST_SUCCESS) |
||||
return ret; |
||||
|
||||
ret = test_str_upr(); |
||||
if (ret != EFI_ST_SUCCESS) |
||||
return ret; |
||||
|
||||
ret = test_fat_to_str(); |
||||
if (ret != EFI_ST_SUCCESS) |
||||
return ret; |
||||
|
||||
ret = test_str_to_fat(); |
||||
if (ret != EFI_ST_SUCCESS) |
||||
return ret; |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
EFI_UNIT_TEST(unicoll) = { |
||||
.name = "unicode collation", |
||||
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, |
||||
.execute = execute, |
||||
.setup = setup, |
||||
}; |
@ -0,0 +1,392 @@ |
||||
# SPDX-License-Identifier: GPL-2.0+ |
||||
# Copyright (c) 2018, Linaro Limited |
||||
# Author: Takahiro Akashi <takahiro.akashi@linaro.org> |
||||
|
||||
import os |
||||
import os.path |
||||
import pytest |
||||
import re |
||||
from subprocess import call, check_call, check_output, CalledProcessError |
||||
from fstest_defs import * |
||||
|
||||
supported_fs_basic = ['fat16', 'fat32', 'ext4'] |
||||
supported_fs_ext = ['fat16', 'fat32'] |
||||
supported_fs_mkdir = ['fat16', 'fat32'] |
||||
supported_fs_unlink = ['fat16', 'fat32'] |
||||
|
||||
# |
||||
# Filesystem test specific setup |
||||
# |
||||
def pytest_addoption(parser): |
||||
parser.addoption('--fs-type', action='append', default=None, |
||||
help='Targeting Filesystem Types') |
||||
|
||||
def pytest_configure(config): |
||||
global supported_fs_basic |
||||
global supported_fs_ext |
||||
global supported_fs_mkdir |
||||
global supported_fs_unlink |
||||
|
||||
def intersect(listA, listB): |
||||
return [x for x in listA if x in listB] |
||||
|
||||
supported_fs = config.getoption('fs_type') |
||||
if supported_fs: |
||||
print("*** FS TYPE modified: %s" % supported_fs) |
||||
supported_fs_basic = intersect(supported_fs, supported_fs_basic) |
||||
supported_fs_ext = intersect(supported_fs, supported_fs_ext) |
||||
supported_fs_mkdir = intersect(supported_fs, supported_fs_mkdir) |
||||
supported_fs_unlink = intersect(supported_fs, supported_fs_unlink) |
||||
|
||||
def pytest_generate_tests(metafunc): |
||||
if 'fs_obj_basic' in metafunc.fixturenames: |
||||
metafunc.parametrize('fs_obj_basic', supported_fs_basic, |
||||
indirect=True, scope='module') |
||||
if 'fs_obj_ext' in metafunc.fixturenames: |
||||
metafunc.parametrize('fs_obj_ext', supported_fs_ext, |
||||
indirect=True, scope='module') |
||||
if 'fs_obj_mkdir' in metafunc.fixturenames: |
||||
metafunc.parametrize('fs_obj_mkdir', supported_fs_mkdir, |
||||
indirect=True, scope='module') |
||||
if 'fs_obj_unlink' in metafunc.fixturenames: |
||||
metafunc.parametrize('fs_obj_unlink', supported_fs_unlink, |
||||
indirect=True, scope='module') |
||||
|
||||
# |
||||
# Helper functions |
||||
# |
||||
def fstype_to_ubname(fs_type): |
||||
if re.match('fat', fs_type): |
||||
return 'fat' |
||||
else: |
||||
return fs_type |
||||
|
||||
def check_ubconfig(config, fs_type): |
||||
if not config.buildconfig.get('config_cmd_%s' % fs_type, None): |
||||
pytest.skip('.config feature "CMD_%s" not enabled' % fs_type.upper()) |
||||
if not config.buildconfig.get('config_%s_write' % fs_type, None): |
||||
pytest.skip('.config feature "%s_WRITE" not enabled' |
||||
% fs_type.upper()) |
||||
|
||||
def mk_fs(config, fs_type, size, id): |
||||
fs_img = '%s.%s.img' % (id, fs_type) |
||||
fs_img = config.persistent_data_dir + '/' + fs_img |
||||
|
||||
if fs_type == 'fat16': |
||||
mkfs_opt = '-F 16' |
||||
elif fs_type == 'fat32': |
||||
mkfs_opt = '-F 32' |
||||
else: |
||||
mkfs_opt = '' |
||||
|
||||
if re.match('fat', fs_type): |
||||
fs_lnxtype = 'vfat' |
||||
else: |
||||
fs_lnxtype = fs_type |
||||
|
||||
count = (size + 1048576 - 1) / 1048576 |
||||
|
||||
try: |
||||
check_call('rm -f %s' % fs_img, shell=True) |
||||
check_call('dd if=/dev/zero of=%s bs=1M count=%d' |
||||
% (fs_img, count), shell=True) |
||||
check_call('mkfs.%s %s %s' |
||||
% (fs_lnxtype, mkfs_opt, fs_img), shell=True) |
||||
return fs_img |
||||
except CalledProcessError: |
||||
call('rm -f %s' % fs_img, shell=True) |
||||
raise |
||||
|
||||
# from test/py/conftest.py |
||||
def tool_is_in_path(tool): |
||||
for path in os.environ["PATH"].split(os.pathsep): |
||||
fn = os.path.join(path, tool) |
||||
if os.path.isfile(fn) and os.access(fn, os.X_OK): |
||||
return True |
||||
return False |
||||
|
||||
fuse_mounted = False |
||||
|
||||
def mount_fs(fs_type, device, mount_point): |
||||
global fuse_mounted |
||||
|
||||
fuse_mounted = False |
||||
try: |
||||
if tool_is_in_path('guestmount'): |
||||
fuse_mounted = True |
||||
check_call('guestmount -a %s -m /dev/sda %s' |
||||
% (device, mount_point), shell=True) |
||||
else: |
||||
mount_opt = "loop,rw" |
||||
if re.match('fat', fs_type): |
||||
mount_opt += ",umask=0000" |
||||
|
||||
check_call('sudo mount -o %s %s %s' |
||||
% (mount_opt, device, mount_point), shell=True) |
||||
|
||||
# may not be effective for some file systems |
||||
check_call('sudo chmod a+rw %s' % mount_point, shell=True) |
||||
except CalledProcessError: |
||||
raise |
||||
|
||||
def umount_fs(fs_type, mount_point): |
||||
if fuse_mounted: |
||||
call('sync') |
||||
call('guestunmount %s' % mount_point, shell=True) |
||||
else: |
||||
call('sudo umount %s' % mount_point, shell=True) |
||||
|
||||
# |
||||
# Fixture for basic fs test |
||||
# derived from test/fs/fs-test.sh |
||||
# |
||||
# NOTE: yield_fixture was deprecated since pytest-3.0 |
||||
@pytest.yield_fixture() |
||||
def fs_obj_basic(request, u_boot_config): |
||||
fs_type = request.param |
||||
fs_img = '' |
||||
|
||||
fs_ubtype = fstype_to_ubname(fs_type) |
||||
check_ubconfig(u_boot_config, fs_ubtype) |
||||
|
||||
mount_dir = u_boot_config.persistent_data_dir + '/mnt' |
||||
|
||||
small_file = mount_dir + '/' + SMALL_FILE |
||||
big_file = mount_dir + '/' + BIG_FILE |
||||
|
||||
try: |
||||
|
||||
# 3GiB volume |
||||
fs_img = mk_fs(u_boot_config, fs_type, 0xc0000000, '3GB') |
||||
|
||||
# Mount the image so we can populate it. |
||||
check_call('mkdir -p %s' % mount_dir, shell=True) |
||||
mount_fs(fs_type, fs_img, mount_dir) |
||||
|
||||
# Create a subdirectory. |
||||
check_call('mkdir %s/SUBDIR' % mount_dir, shell=True) |
||||
|
||||
# Create big file in this image. |
||||
# Note that we work only on the start 1MB, couple MBs in the 2GB range |
||||
# and the last 1 MB of the huge 2.5GB file. |
||||
# So, just put random values only in those areas. |
||||
check_call('dd if=/dev/urandom of=%s bs=1M count=1' |
||||
% big_file, shell=True) |
||||
check_call('dd if=/dev/urandom of=%s bs=1M count=2 seek=2047' |
||||
% big_file, shell=True) |
||||
check_call('dd if=/dev/urandom of=%s bs=1M count=1 seek=2499' |
||||
% big_file, shell=True) |
||||
|
||||
# Create a small file in this image. |
||||
check_call('dd if=/dev/urandom of=%s bs=1M count=1' |
||||
% small_file, shell=True) |
||||
|
||||
# Delete the small file copies which possibly are written as part of a |
||||
# previous test. |
||||
# check_call('rm -f "%s.w"' % MB1, shell=True) |
||||
# check_call('rm -f "%s.w2"' % MB1, shell=True) |
||||
|
||||
# Generate the md5sums of reads that we will test against small file |
||||
out = check_output( |
||||
'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum' |
||||
% small_file, shell=True) |
||||
md5val = [ out.split()[0] ] |
||||
|
||||
# Generate the md5sums of reads that we will test against big file |
||||
# One from beginning of file. |
||||
out = check_output( |
||||
'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum' |
||||
% big_file, shell=True) |
||||
md5val.append(out.split()[0]) |
||||
|
||||
# One from end of file. |
||||
out = check_output( |
||||
'dd if=%s bs=1M skip=2499 count=1 2> /dev/null | md5sum' |
||||
% big_file, shell=True) |
||||
md5val.append(out.split()[0]) |
||||
|
||||
# One from the last 1MB chunk of 2GB |
||||
out = check_output( |
||||
'dd if=%s bs=1M skip=2047 count=1 2> /dev/null | md5sum' |
||||
% big_file, shell=True) |
||||
md5val.append(out.split()[0]) |
||||
|
||||
# One from the start 1MB chunk from 2GB |
||||
out = check_output( |
||||
'dd if=%s bs=1M skip=2048 count=1 2> /dev/null | md5sum' |
||||
% big_file, shell=True) |
||||
md5val.append(out.split()[0]) |
||||
|
||||
# One 1MB chunk crossing the 2GB boundary |
||||
out = check_output( |
||||
'dd if=%s bs=512K skip=4095 count=2 2> /dev/null | md5sum' |
||||
% big_file, shell=True) |
||||
md5val.append(out.split()[0]) |
||||
|
||||
umount_fs(fs_type, mount_dir) |
||||
except CalledProcessError: |
||||
pytest.skip('Setup failed for filesystem: ' + fs_type) |
||||
return |
||||
else: |
||||
yield [fs_ubtype, fs_img, md5val] |
||||
finally: |
||||
umount_fs(fs_type, mount_dir) |
||||
call('rmdir %s' % mount_dir, shell=True) |
||||
if fs_img: |
||||
call('rm -f %s' % fs_img, shell=True) |
||||
|
||||
# |
||||
# Fixture for extended fs test |
||||
# |
||||
# NOTE: yield_fixture was deprecated since pytest-3.0 |
||||
@pytest.yield_fixture() |
||||
def fs_obj_ext(request, u_boot_config): |
||||
fs_type = request.param |
||||
fs_img = '' |
||||
|
||||
fs_ubtype = fstype_to_ubname(fs_type) |
||||
check_ubconfig(u_boot_config, fs_ubtype) |
||||
|
||||
mount_dir = u_boot_config.persistent_data_dir + '/mnt' |
||||
|
||||
min_file = mount_dir + '/' + MIN_FILE |
||||
tmp_file = mount_dir + '/tmpfile' |
||||
|
||||
try: |
||||
|
||||
# 128MiB volume |
||||
fs_img = mk_fs(u_boot_config, fs_type, 0x8000000, '128MB') |
||||
|
||||
# Mount the image so we can populate it. |
||||
check_call('mkdir -p %s' % mount_dir, shell=True) |
||||
mount_fs(fs_type, fs_img, mount_dir) |
||||
|
||||
# Create a test directory |
||||
check_call('mkdir %s/dir1' % mount_dir, shell=True) |
||||
|
||||
# Create a small file and calculate md5 |
||||
check_call('dd if=/dev/urandom of=%s bs=1K count=20' |
||||
% min_file, shell=True) |
||||
out = check_output( |
||||
'dd if=%s bs=1K 2> /dev/null | md5sum' |
||||
% min_file, shell=True) |
||||
md5val = [ out.split()[0] ] |
||||
|
||||
# Calculate md5sum of Test Case 4 |
||||
check_call('dd if=%s of=%s bs=1K count=20' |
||||
% (min_file, tmp_file), shell=True) |
||||
check_call('dd if=%s of=%s bs=1K seek=5 count=20' |
||||
% (min_file, tmp_file), shell=True) |
||||
out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum' |
||||
% tmp_file, shell=True) |
||||
md5val.append(out.split()[0]) |
||||
|
||||
# Calculate md5sum of Test Case 5 |
||||
check_call('dd if=%s of=%s bs=1K count=20' |
||||
% (min_file, tmp_file), shell=True) |
||||
check_call('dd if=%s of=%s bs=1K seek=5 count=5' |
||||
% (min_file, tmp_file), shell=True) |
||||
out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum' |
||||
% tmp_file, shell=True) |
||||
md5val.append(out.split()[0]) |
||||
|
||||
# Calculate md5sum of Test Case 7 |
||||
check_call('dd if=%s of=%s bs=1K count=20' |
||||
% (min_file, tmp_file), shell=True) |
||||
check_call('dd if=%s of=%s bs=1K seek=20 count=20' |
||||
% (min_file, tmp_file), shell=True) |
||||
out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum' |
||||
% tmp_file, shell=True) |
||||
md5val.append(out.split()[0]) |
||||
|
||||
check_call('rm %s' % tmp_file, shell=True) |
||||
umount_fs(fs_type, mount_dir) |
||||
except CalledProcessError: |
||||
pytest.skip('Setup failed for filesystem: ' + fs_type) |
||||
return |
||||
else: |
||||
yield [fs_ubtype, fs_img, md5val] |
||||
finally: |
||||
umount_fs(fs_type, mount_dir) |
||||
call('rmdir %s' % mount_dir, shell=True) |
||||
if fs_img: |
||||
call('rm -f %s' % fs_img, shell=True) |
||||
|
||||
# |
||||
# Fixture for mkdir test |
||||
# |
||||
# NOTE: yield_fixture was deprecated since pytest-3.0 |
||||
@pytest.yield_fixture() |
||||
def fs_obj_mkdir(request, u_boot_config): |
||||
fs_type = request.param |
||||
fs_img = '' |
||||
|
||||
fs_ubtype = fstype_to_ubname(fs_type) |
||||
check_ubconfig(u_boot_config, fs_ubtype) |
||||
|
||||
try: |
||||
# 128MiB volume |
||||
fs_img = mk_fs(u_boot_config, fs_type, 0x8000000, '128MB') |
||||
except: |
||||
pytest.skip('Setup failed for filesystem: ' + fs_type) |
||||
else: |
||||
yield [fs_ubtype, fs_img] |
||||
finally: |
||||
if fs_img: |
||||
call('rm -f %s' % fs_img, shell=True) |
||||
|
||||
# |
||||
# Fixture for unlink test |
||||
# |
||||
# NOTE: yield_fixture was deprecated since pytest-3.0 |
||||
@pytest.yield_fixture() |
||||
def fs_obj_unlink(request, u_boot_config): |
||||
fs_type = request.param |
||||
fs_img = '' |
||||
|
||||
fs_ubtype = fstype_to_ubname(fs_type) |
||||
check_ubconfig(u_boot_config, fs_ubtype) |
||||
|
||||
mount_dir = u_boot_config.persistent_data_dir + '/mnt' |
||||
|
||||
try: |
||||
|
||||
# 128MiB volume |
||||
fs_img = mk_fs(u_boot_config, fs_type, 0x8000000, '128MB') |
||||
|
||||
# Mount the image so we can populate it. |
||||
check_call('mkdir -p %s' % mount_dir, shell=True) |
||||
mount_fs(fs_type, fs_img, mount_dir) |
||||
|
||||
# Test Case 1 & 3 |
||||
check_call('mkdir %s/dir1' % mount_dir, shell=True) |
||||
check_call('dd if=/dev/urandom of=%s/dir1/file1 bs=1K count=1' |
||||
% mount_dir, shell=True) |
||||
check_call('dd if=/dev/urandom of=%s/dir1/file2 bs=1K count=1' |
||||
% mount_dir, shell=True) |
||||
|
||||
# Test Case 2 |
||||
check_call('mkdir %s/dir2' % mount_dir, shell=True) |
||||
for i in range(0, 20): |
||||
check_call('mkdir %s/dir2/0123456789abcdef%02x' |
||||
% (mount_dir, i), shell=True) |
||||
|
||||
# Test Case 4 |
||||
check_call('mkdir %s/dir4' % mount_dir, shell=True) |
||||
|
||||
# Test Case 5, 6 & 7 |
||||
check_call('mkdir %s/dir5' % mount_dir, shell=True) |
||||
check_call('dd if=/dev/urandom of=%s/dir5/file1 bs=1K count=1' |
||||
% mount_dir, shell=True) |
||||
|
||||
umount_fs(fs_type, mount_dir) |
||||
except CalledProcessError: |
||||
pytest.skip('Setup failed for filesystem: ' + fs_type) |
||||
return |
||||
else: |
||||
yield [fs_ubtype, fs_img] |
||||
finally: |
||||
umount_fs(fs_type, mount_dir) |
||||
call('rmdir %s' % mount_dir, shell=True) |
||||
if fs_img: |
||||
call('rm -f %s' % fs_img, shell=True) |
@ -0,0 +1,13 @@ |
||||
# SPDX-License-Identifier: GPL-2.0+ |
||||
|
||||
# $MIN_FILE is the name of the 20KB file in the file system image |
||||
MIN_FILE='testfile' |
||||
|
||||
# $SMALL_FILE is the name of the 1MB file in the file system image |
||||
SMALL_FILE='1MB.file' |
||||
|
||||
# $BIG_FILE is the name of the 2.5GB file in the file system image |
||||
BIG_FILE='2.5GB.file' |
||||
|
||||
ADDR=0x01000008 |
||||
LENGTH=0x00100000 |
@ -0,0 +1,287 @@ |
||||
# SPDX-License-Identifier: GPL-2.0+ |
||||
# Copyright (c) 2018, Linaro Limited |
||||
# Author: Takahiro Akashi <takahiro.akashi@linaro.org> |
||||
# |
||||
# U-Boot File System:Basic Test |
||||
|
||||
""" |
||||
This test verifies basic read/write operation on file system. |
||||
""" |
||||
|
||||
import pytest |
||||
import re |
||||
from fstest_defs import * |
||||
|
||||
@pytest.mark.boardspec('sandbox') |
||||
class TestFsBasic(object): |
||||
def test_fs1(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 1 - ls command, listing a root directory and invalid directory |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 1a - ls'): |
||||
# Test Case 1 - ls |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sls host 0:0' % fs_type]) |
||||
assert(re.search('2621440000 *%s' % BIG_FILE, ''.join(output))) |
||||
assert(re.search('1048576 *%s' % SMALL_FILE, ''.join(output))) |
||||
|
||||
with u_boot_console.log.section('Test Case 1b - ls (invalid dir)'): |
||||
# In addition, test with a nonexistent directory to see if we crash. |
||||
output = u_boot_console.run_command( |
||||
'%sls host 0:0 invalid_d' % fs_type) |
||||
if fs_type == 'ext4': |
||||
assert('Can not find directory' in output) |
||||
else: |
||||
assert('' == output) |
||||
|
||||
def test_fs2(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 2 - size command for a small file |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 2a - size (small)'): |
||||
# 1MB is 0x0010 0000 |
||||
# Test Case 2a - size of small file |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%ssize host 0:0 /%s' % (fs_type, SMALL_FILE), |
||||
'printenv filesize', |
||||
'setenv filesize']) |
||||
assert('filesize=100000' in ''.join(output)) |
||||
|
||||
with u_boot_console.log.section('Test Case 2b - size (/../<file>)'): |
||||
# Test Case 2b - size of small file via a path using '..' |
||||
output = u_boot_console.run_command_list([ |
||||
'%ssize host 0:0 /SUBDIR/../%s' % (fs_type, SMALL_FILE), |
||||
'printenv filesize', |
||||
'setenv filesize']) |
||||
assert('filesize=100000' in ''.join(output)) |
||||
|
||||
def test_fs3(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 3 - size command for a large file |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 3 - size (large)'): |
||||
# 2.5GB (1024*1024*2500) is 0x9C40 0000 |
||||
# Test Case 3 - size of big file |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%ssize host 0:0 /%s' % (fs_type, BIG_FILE), |
||||
'printenv filesize', |
||||
'setenv filesize']) |
||||
assert('filesize=9c400000' in ''.join(output)) |
||||
|
||||
def test_fs4(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 4 - load a small file, 1MB |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 4 - load (small)'): |
||||
# Test Case 4a - Read full 1MB of small file |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s' % (fs_type, ADDR, SMALL_FILE), |
||||
'printenv filesize']) |
||||
assert('filesize=100000' in ''.join(output)) |
||||
|
||||
# Test Case 4b - Read full 1MB of small file |
||||
output = u_boot_console.run_command_list([ |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[0] in ''.join(output)) |
||||
|
||||
def test_fs5(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 5 - load, reading first 1MB of 3GB file |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 5 - load (first 1MB)'): |
||||
# Test Case 5a - First 1MB of big file |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s %x 0x0' % (fs_type, ADDR, BIG_FILE, LENGTH), |
||||
'printenv filesize']) |
||||
assert('filesize=100000' in ''.join(output)) |
||||
|
||||
# Test Case 5b - First 1MB of big file |
||||
output = u_boot_console.run_command_list([ |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[1] in ''.join(output)) |
||||
|
||||
def test_fs6(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 6 - load, reading last 1MB of 3GB file |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 6 - load (last 1MB)'): |
||||
# fails for ext as no offset support |
||||
# Test Case 6a - Last 1MB of big file |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s %x 0x9c300000' |
||||
% (fs_type, ADDR, BIG_FILE, LENGTH), |
||||
'printenv filesize']) |
||||
assert('filesize=100000' in ''.join(output)) |
||||
|
||||
# Test Case 6b - Last 1MB of big file |
||||
output = u_boot_console.run_command_list([ |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[2] in ''.join(output)) |
||||
|
||||
def test_fs7(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 7 - load, 1MB from the last 1MB in 2GB |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 7 - load (last 1MB in 2GB)'): |
||||
# fails for ext as no offset support |
||||
# Test Case 7a - One from the last 1MB chunk of 2GB |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s %x 0x7ff00000' |
||||
% (fs_type, ADDR, BIG_FILE, LENGTH), |
||||
'printenv filesize']) |
||||
assert('filesize=100000' in ''.join(output)) |
||||
|
||||
# Test Case 7b - One from the last 1MB chunk of 2GB |
||||
output = u_boot_console.run_command_list([ |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[3] in ''.join(output)) |
||||
|
||||
def test_fs8(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 8 - load, reading first 1MB in 2GB |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 8 - load (first 1MB in 2GB)'): |
||||
# fails for ext as no offset support |
||||
# Test Case 8a - One from the start 1MB chunk from 2GB |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s %x 0x80000000' |
||||
% (fs_type, ADDR, BIG_FILE, LENGTH), |
||||
'printenv filesize']) |
||||
assert('filesize=100000' in ''.join(output)) |
||||
|
||||
# Test Case 8b - One from the start 1MB chunk from 2GB |
||||
output = u_boot_console.run_command_list([ |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[4] in ''.join(output)) |
||||
|
||||
def test_fs9(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 9 - load, 1MB crossing 2GB boundary |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 9 - load (crossing 2GB boundary)'): |
||||
# fails for ext as no offset support |
||||
# Test Case 9a - One 1MB chunk crossing the 2GB boundary |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s %x 0x7ff80000' |
||||
% (fs_type, ADDR, BIG_FILE, LENGTH), |
||||
'printenv filesize']) |
||||
assert('filesize=100000' in ''.join(output)) |
||||
|
||||
# Test Case 9b - One 1MB chunk crossing the 2GB boundary |
||||
output = u_boot_console.run_command_list([ |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[5] in ''.join(output)) |
||||
|
||||
def test_fs10(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 10 - load, reading beyond file end'): |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 10 - load (beyond file end)'): |
||||
# Generic failure case |
||||
# Test Case 10 - 2MB chunk from the last 1MB of big file |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s 0x00200000 0x9c300000' |
||||
% (fs_type, ADDR, BIG_FILE), |
||||
'printenv filesize', |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert('filesize=100000' in ''.join(output)) |
||||
|
||||
def test_fs11(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 11 - write' |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 11 - write'): |
||||
# Read 1MB from small file |
||||
# Write it back to test the writes |
||||
# Test Case 11a - Check that the write succeeded |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s' % (fs_type, ADDR, SMALL_FILE), |
||||
'%swrite host 0:0 %x /%s.w $filesize' |
||||
% (fs_type, ADDR, SMALL_FILE)]) |
||||
assert('1048576 bytes written' in ''.join(output)) |
||||
|
||||
# Test Case 11b - Check md5 of written to is same |
||||
# as the one read from |
||||
output = u_boot_console.run_command_list([ |
||||
'%sload host 0:0 %x /%s.w' % (fs_type, ADDR, SMALL_FILE), |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[0] in ''.join(output)) |
||||
|
||||
def test_fs12(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 12 - write to "." directory |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 12 - write (".")'): |
||||
# Next test case checks writing a file whose dirent |
||||
# is the first in the block, which is always true for "." |
||||
# The write should fail, but the lookup should work |
||||
# Test Case 12 - Check directory traversal |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%swrite host 0:0 %x /. 0x10' % (fs_type, ADDR)]) |
||||
assert('Unable to write' in ''.join(output)) |
||||
|
||||
def test_fs13(self, u_boot_console, fs_obj_basic): |
||||
""" |
||||
Test Case 13 - write to a file with "/./<filename>" |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_basic |
||||
with u_boot_console.log.section('Test Case 13 - write ("./<file>")'): |
||||
# Read 1MB from small file |
||||
# Write it via "same directory", i.e. "." dirent |
||||
# Test Case 13a - Check directory traversal |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s' % (fs_type, ADDR, SMALL_FILE), |
||||
'%swrite host 0:0 %x /./%s2 $filesize' |
||||
% (fs_type, ADDR, SMALL_FILE)]) |
||||
assert('1048576 bytes written' in ''.join(output)) |
||||
|
||||
# Test Case 13b - Check md5 of written to is same |
||||
# as the one read from |
||||
output = u_boot_console.run_command_list([ |
||||
'mw.b %x 00 100' % ADDR, |
||||
'%sload host 0:0 %x /./%s2' % (fs_type, ADDR, SMALL_FILE), |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[0] in ''.join(output)) |
||||
|
||||
# Test Case 13c - Check md5 of written to is same |
||||
# as the one read from |
||||
output = u_boot_console.run_command_list([ |
||||
'mw.b %x 00 100' % ADDR, |
||||
'%sload host 0:0 %x /%s2' % (fs_type, ADDR, SMALL_FILE), |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[0] in ''.join(output)) |
@ -0,0 +1,224 @@ |
||||
# SPDX-License-Identifier: GPL-2.0+ |
||||
# Copyright (c) 2018, Linaro Limited |
||||
# Author: Takahiro Akashi <takahiro.akashi@linaro.org> |
||||
# |
||||
# U-Boot File System:Exntented Test |
||||
|
||||
""" |
||||
This test verifies extended write operation on file system. |
||||
""" |
||||
|
||||
import pytest |
||||
import re |
||||
from fstest_defs import * |
||||
|
||||
@pytest.mark.boardspec('sandbox') |
||||
class TestFsExt(object): |
||||
def test_fs_ext1(self, u_boot_console, fs_obj_ext): |
||||
""" |
||||
Test Case 1 - write a file with absolute path |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_ext |
||||
with u_boot_console.log.section('Test Case 1 - write with abs path'): |
||||
# Test Case 1a - Check if command successfully returned |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE), |
||||
'%swrite host 0:0 %x /dir1/%s.w1 $filesize' |
||||
% (fs_type, ADDR, MIN_FILE)]) |
||||
assert('20480 bytes written' in ''.join(output)) |
||||
|
||||
# Test Case 1b - Check md5 of file content |
||||
output = u_boot_console.run_command_list([ |
||||
'mw.b %x 00 100' % ADDR, |
||||
'%sload host 0:0 %x /dir1/%s.w1' % (fs_type, ADDR, MIN_FILE), |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[0] in ''.join(output)) |
||||
|
||||
def test_fs_ext2(self, u_boot_console, fs_obj_ext): |
||||
""" |
||||
Test Case 2 - write to a file with relative path |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_ext |
||||
with u_boot_console.log.section('Test Case 2 - write with rel path'): |
||||
# Test Case 2a - Check if command successfully returned |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE), |
||||
'%swrite host 0:0 %x dir1/%s.w2 $filesize' |
||||
% (fs_type, ADDR, MIN_FILE)]) |
||||
assert('20480 bytes written' in ''.join(output)) |
||||
|
||||
# Test Case 2b - Check md5 of file content |
||||
output = u_boot_console.run_command_list([ |
||||
'mw.b %x 00 100' % ADDR, |
||||
'%sload host 0:0 %x dir1/%s.w2' % (fs_type, ADDR, MIN_FILE), |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[0] in ''.join(output)) |
||||
|
||||
def test_fs_ext3(self, u_boot_console, fs_obj_ext): |
||||
""" |
||||
Test Case 3 - write to a file with invalid path |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_ext |
||||
with u_boot_console.log.section('Test Case 3 - write with invalid path'): |
||||
# Test Case 3 - Check if command expectedly failed |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE), |
||||
'%swrite host 0:0 %x /dir1/none/%s.w3 $filesize' |
||||
% (fs_type, ADDR, MIN_FILE)]) |
||||
assert('Unable to write "/dir1/none/' in ''.join(output)) |
||||
|
||||
def test_fs_ext4(self, u_boot_console, fs_obj_ext): |
||||
""" |
||||
Test Case 4 - write at non-zero offset, enlarging file size |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_ext |
||||
with u_boot_console.log.section('Test Case 4 - write at non-zero offset, enlarging file size'): |
||||
# Test Case 4a - Check if command successfully returned |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE), |
||||
'%swrite host 0:0 %x /dir1/%s.w4 $filesize' |
||||
% (fs_type, ADDR, MIN_FILE)]) |
||||
output = u_boot_console.run_command( |
||||
'%swrite host 0:0 %x /dir1/%s.w4 $filesize 0x1400' |
||||
% (fs_type, ADDR, MIN_FILE)) |
||||
assert('20480 bytes written' in output) |
||||
|
||||
# Test Case 4b - Check size of written file |
||||
output = u_boot_console.run_command_list([ |
||||
'%ssize host 0:0 /dir1/%s.w4' % (fs_type, MIN_FILE), |
||||
'printenv filesize', |
||||
'setenv filesize']) |
||||
assert('filesize=6400' in ''.join(output)) |
||||
|
||||
# Test Case 4c - Check md5 of file content |
||||
output = u_boot_console.run_command_list([ |
||||
'mw.b %x 00 100' % ADDR, |
||||
'%sload host 0:0 %x /dir1/%s.w4' % (fs_type, ADDR, MIN_FILE), |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[1] in ''.join(output)) |
||||
|
||||
def test_fs_ext5(self, u_boot_console, fs_obj_ext): |
||||
""" |
||||
Test Case 5 - write at non-zero offset, shrinking file size |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_ext |
||||
with u_boot_console.log.section('Test Case 5 - write at non-zero offset, shrinking file size'): |
||||
# Test Case 5a - Check if command successfully returned |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE), |
||||
'%swrite host 0:0 %x /dir1/%s.w5 $filesize' |
||||
% (fs_type, ADDR, MIN_FILE)]) |
||||
output = u_boot_console.run_command( |
||||
'%swrite host 0:0 %x /dir1/%s.w5 0x1400 0x1400' |
||||
% (fs_type, ADDR, MIN_FILE)) |
||||
assert('5120 bytes written' in output) |
||||
|
||||
# Test Case 5b - Check size of written file |
||||
output = u_boot_console.run_command_list([ |
||||
'%ssize host 0:0 /dir1/%s.w5' % (fs_type, MIN_FILE), |
||||
'printenv filesize', |
||||
'setenv filesize']) |
||||
assert('filesize=2800' in ''.join(output)) |
||||
|
||||
# Test Case 5c - Check md5 of file content |
||||
output = u_boot_console.run_command_list([ |
||||
'mw.b %x 00 100' % ADDR, |
||||
'%sload host 0:0 %x /dir1/%s.w5' % (fs_type, ADDR, MIN_FILE), |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[2] in ''.join(output)) |
||||
|
||||
def test_fs_ext6(self, u_boot_console, fs_obj_ext): |
||||
""" |
||||
Test Case 6 - write nothing at the start, truncating to zero |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_ext |
||||
with u_boot_console.log.section('Test Case 6 - write nothing at the start, truncating to zero'): |
||||
# Test Case 6a - Check if command successfully returned |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE), |
||||
'%swrite host 0:0 %x /dir1/%s.w6 $filesize' |
||||
% (fs_type, ADDR, MIN_FILE)]) |
||||
output = u_boot_console.run_command( |
||||
'%swrite host 0:0 %x /dir1/%s.w6 0 0' |
||||
% (fs_type, ADDR, MIN_FILE)) |
||||
assert('0 bytes written' in output) |
||||
|
||||
# Test Case 6b - Check size of written file |
||||
output = u_boot_console.run_command_list([ |
||||
'%ssize host 0:0 /dir1/%s.w6' % (fs_type, MIN_FILE), |
||||
'printenv filesize', |
||||
'setenv filesize']) |
||||
assert('filesize=0' in ''.join(output)) |
||||
|
||||
def test_fs_ext7(self, u_boot_console, fs_obj_ext): |
||||
""" |
||||
Test Case 7 - write at the end (append) |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_ext |
||||
with u_boot_console.log.section('Test Case 7 - write at the end (append)'): |
||||
# Test Case 7a - Check if command successfully returned |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE), |
||||
'%swrite host 0:0 %x /dir1/%s.w7 $filesize' |
||||
% (fs_type, ADDR, MIN_FILE)]) |
||||
output = u_boot_console.run_command( |
||||
'%swrite host 0:0 %x /dir1/%s.w7 $filesize $filesize' |
||||
% (fs_type, ADDR, MIN_FILE)) |
||||
assert('20480 bytes written' in output) |
||||
|
||||
# Test Case 7b - Check size of written file |
||||
output = u_boot_console.run_command_list([ |
||||
'%ssize host 0:0 /dir1/%s.w7' % (fs_type, MIN_FILE), |
||||
'printenv filesize', |
||||
'setenv filesize']) |
||||
assert('filesize=a000' in ''.join(output)) |
||||
|
||||
# Test Case 7c - Check md5 of file content |
||||
output = u_boot_console.run_command_list([ |
||||
'mw.b %x 00 100' % ADDR, |
||||
'%sload host 0:0 %x /dir1/%s.w7' % (fs_type, ADDR, MIN_FILE), |
||||
'md5sum %x $filesize' % ADDR, |
||||
'setenv filesize']) |
||||
assert(md5val[3] in ''.join(output)) |
||||
|
||||
def test_fs_ext8(self, u_boot_console, fs_obj_ext): |
||||
""" |
||||
Test Case 8 - write at offset beyond the end of file |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_ext |
||||
with u_boot_console.log.section('Test Case 8 - write beyond the end'): |
||||
# Test Case 8a - Check if command expectedly failed |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE), |
||||
'%swrite host 0:0 %x /dir1/%s.w8 $filesize' |
||||
% (fs_type, ADDR, MIN_FILE)]) |
||||
output = u_boot_console.run_command( |
||||
'%swrite host 0:0 %x /dir1/%s.w8 0x1400 %x' |
||||
% (fs_type, ADDR, MIN_FILE, 0x100000 + 0x1400)) |
||||
assert('Unable to write "/dir1' in output) |
||||
|
||||
def test_fs_ext9(self, u_boot_console, fs_obj_ext): |
||||
""" |
||||
Test Case 9 - write to a non-existing file at non-zero offset |
||||
""" |
||||
fs_type,fs_img,md5val = fs_obj_ext |
||||
with u_boot_console.log.section('Test Case 9 - write to non-existing file with non-zero offset'): |
||||
# Test Case 9a - Check if command expectedly failed |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE), |
||||
'%swrite host 0:0 %x /dir1/%s.w9 0x1400 0x1400' |
||||
% (fs_type, ADDR, MIN_FILE)]) |
||||
assert('Unable to write "/dir1' in ''.join(output)) |
@ -0,0 +1,112 @@ |
||||
# SPDX-License-Identifier: GPL-2.0+ |
||||
# Copyright (c) 2018, Linaro Limited |
||||
# Author: Takahiro Akashi <takahiro.akashi@linaro.org> |
||||
# |
||||
# U-Boot File System:mkdir Test |
||||
|
||||
""" |
||||
This test verifies mkdir operation on file system. |
||||
""" |
||||
|
||||
import pytest |
||||
|
||||
@pytest.mark.boardspec('sandbox') |
||||
class TestMkdir(object): |
||||
def test_mkdir1(self, u_boot_console, fs_obj_mkdir): |
||||
""" |
||||
Test Case 1 - create a directory under a root |
||||
""" |
||||
fs_type,fs_img = fs_obj_mkdir |
||||
with u_boot_console.log.section('Test Case 1 - mkdir'): |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%smkdir host 0:0 dir1' % fs_type, |
||||
'%sls host 0:0 /' % fs_type]) |
||||
assert('dir1/' in ''.join(output)) |
||||
|
||||
output = u_boot_console.run_command( |
||||
'%sls host 0:0 dir1' % fs_type) |
||||
assert('./' in output) |
||||
assert('../' in output) |
||||
|
||||
def test_mkdir2(self, u_boot_console, fs_obj_mkdir): |
||||
""" |
||||
Test Case 2 - create a directory under a sub-directory |
||||
""" |
||||
fs_type,fs_img = fs_obj_mkdir |
||||
with u_boot_console.log.section('Test Case 2 - mkdir (sub-sub directory)'): |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%smkdir host 0:0 dir1/dir2' % fs_type, |
||||
'%sls host 0:0 dir1' % fs_type]) |
||||
assert('dir2/' in ''.join(output)) |
||||
|
||||
output = u_boot_console.run_command( |
||||
'%sls host 0:0 dir1/dir2' % fs_type) |
||||
assert('./' in output) |
||||
assert('../' in output) |
||||
|
||||
def test_mkdir3(self, u_boot_console, fs_obj_mkdir): |
||||
""" |
||||
Test Case 3 - trying to create a directory with a non-existing |
||||
path should fail |
||||
""" |
||||
fs_type,fs_img = fs_obj_mkdir |
||||
with u_boot_console.log.section('Test Case 3 - mkdir (non-existing path)'): |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%smkdir host 0:0 none/dir3' % fs_type]) |
||||
assert('Unable to create a directory' in ''.join(output)) |
||||
|
||||
def test_mkdir4(self, u_boot_console, fs_obj_mkdir): |
||||
""" |
||||
Test Case 4 - trying to create "." should fail |
||||
""" |
||||
fs_type,fs_img = fs_obj_mkdir |
||||
with u_boot_console.log.section('Test Case 4 - mkdir (".")'): |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%smkdir host 0:0 .' % fs_type]) |
||||
assert('Unable to create a directory' in ''.join(output)) |
||||
|
||||
def test_mkdir5(self, u_boot_console, fs_obj_mkdir): |
||||
""" |
||||
Test Case 5 - trying to create ".." should fail |
||||
""" |
||||
fs_type,fs_img = fs_obj_mkdir |
||||
with u_boot_console.log.section('Test Case 5 - mkdir ("..")'): |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%smkdir host 0:0 ..' % fs_type]) |
||||
assert('Unable to create a directory' in ''.join(output)) |
||||
|
||||
def test_mkdir6(self, u_boot_console, fs_obj_mkdir): |
||||
""" |
||||
'Test Case 6 - create as many directories as amount of directory |
||||
entries goes beyond a cluster size)' |
||||
""" |
||||
fs_type,fs_img = fs_obj_mkdir |
||||
with u_boot_console.log.section('Test Case 6 - mkdir (create many)'): |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%smkdir host 0:0 dir6' % fs_type, |
||||
'%sls host 0:0 /' % fs_type]) |
||||
assert('dir6/' in ''.join(output)) |
||||
|
||||
for i in range(0, 20): |
||||
output = u_boot_console.run_command( |
||||
'%smkdir host 0:0 dir6/0123456789abcdef%02x' |
||||
% (fs_type, i)) |
||||
output = u_boot_console.run_command('%sls host 0:0 dir6' % fs_type) |
||||
assert('0123456789abcdef00/' in output) |
||||
assert('0123456789abcdef13/' in output) |
||||
|
||||
output = u_boot_console.run_command( |
||||
'%sls host 0:0 dir6/0123456789abcdef13/.' % fs_type) |
||||
assert('./' in output) |
||||
assert('../' in output) |
||||
|
||||
output = u_boot_console.run_command( |
||||
'%sls host 0:0 dir6/0123456789abcdef13/..' % fs_type) |
||||
assert('0123456789abcdef00/' in output) |
||||
assert('0123456789abcdef13/' in output) |
@ -0,0 +1,109 @@ |
||||
# SPDX-License-Identifier: GPL-2.0+ |
||||
# Copyright (c) 2018, Linaro Limited |
||||
# Author: Takahiro Akashi <takahiro.akashi@linaro.org> |
||||
# |
||||
# U-Boot File System:unlink Test |
||||
|
||||
""" |
||||
This test verifies unlink operation (deleting a file or a directory) |
||||
on file system. |
||||
""" |
||||
|
||||
import pytest |
||||
|
||||
@pytest.mark.boardspec('sandbox') |
||||
class TestUnlink(object): |
||||
def test_unlink1(self, u_boot_console, fs_obj_unlink): |
||||
""" |
||||
Test Case 1 - delete a file |
||||
""" |
||||
fs_type,fs_img = fs_obj_unlink |
||||
with u_boot_console.log.section('Test Case 1 - unlink (file)'): |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%srm host 0:0 dir1/file1' % fs_type, |
||||
'%sls host 0:0 dir1/file1' % fs_type]) |
||||
assert('' == ''.join(output)) |
||||
|
||||
output = u_boot_console.run_command( |
||||
'%sls host 0:0 dir1/' % fs_type) |
||||
assert(not 'file1' in output) |
||||
assert('file2' in output) |
||||
|
||||
def test_unlink2(self, u_boot_console, fs_obj_unlink): |
||||
""" |
||||
Test Case 2 - delete many files |
||||
""" |
||||
fs_type,fs_img = fs_obj_unlink |
||||
with u_boot_console.log.section('Test Case 2 - unlink (many)'): |
||||
output = u_boot_console.run_command('host bind 0 %s' % fs_img) |
||||
|
||||
for i in range(0, 20): |
||||
output = u_boot_console.run_command_list([ |
||||
'%srm host 0:0 dir2/0123456789abcdef%02x' % (fs_type, i), |
||||
'%sls host 0:0 dir2/0123456789abcdef%02x' % (fs_type, i)]) |
||||
assert('' == ''.join(output)) |
||||
|
||||
output = u_boot_console.run_command( |
||||
'%sls host 0:0 dir2' % fs_type) |
||||
assert('0 file(s), 2 dir(s)' in output) |
||||
|
||||
def test_unlink3(self, u_boot_console, fs_obj_unlink): |
||||
""" |
||||
Test Case 3 - trying to delete a non-existing file should fail |
||||
""" |
||||
fs_type,fs_img = fs_obj_unlink |
||||
with u_boot_console.log.section('Test Case 3 - unlink (non-existing)'): |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%srm host 0:0 dir1/nofile' % fs_type]) |
||||
assert('nofile: doesn\'t exist' in ''.join(output)) |
||||
|
||||
def test_unlink4(self, u_boot_console, fs_obj_unlink): |
||||
""" |
||||
Test Case 4 - delete an empty directory |
||||
""" |
||||
fs_type,fs_img = fs_obj_unlink |
||||
with u_boot_console.log.section('Test Case 4 - unlink (directory)'): |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%srm host 0:0 dir4' % fs_type]) |
||||
assert('' == ''.join(output)) |
||||
|
||||
output = u_boot_console.run_command( |
||||
'%sls host 0:0 /' % fs_type) |
||||
assert(not 'dir4' in output) |
||||
|
||||
def test_unlink5(self, u_boot_console, fs_obj_unlink): |
||||
""" |
||||
Test Case 5 - trying to deleting a non-empty directory ".." |
||||
should fail |
||||
""" |
||||
fs_type,fs_img = fs_obj_unlink |
||||
with u_boot_console.log.section('Test Case 5 - unlink ("non-empty directory")'): |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%srm host 0:0 dir5' % fs_type]) |
||||
assert('directory is not empty' in ''.join(output)) |
||||
|
||||
def test_unlink6(self, u_boot_console, fs_obj_unlink): |
||||
""" |
||||
Test Case 6 - trying to deleting a "." should fail |
||||
""" |
||||
fs_type,fs_img = fs_obj_unlink |
||||
with u_boot_console.log.section('Test Case 6 - unlink (".")'): |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%srm host 0:0 dir5/.' % fs_type]) |
||||
assert('directory is not empty' in ''.join(output)) |
||||
|
||||
def test_unlink7(self, u_boot_console, fs_obj_unlink): |
||||
""" |
||||
Test Case 7 - trying to deleting a ".." should fail |
||||
""" |
||||
fs_type,fs_img = fs_obj_unlink |
||||
with u_boot_console.log.section('Test Case 7 - unlink ("..")'): |
||||
output = u_boot_console.run_command_list([ |
||||
'host bind 0 %s' % fs_img, |
||||
'%srm host 0:0 dir5/..' % fs_type]) |
||||
assert('directory is not empty' in ''.join(output)) |
@ -0,0 +1,543 @@ |
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Unit tests for Unicode functions |
||||
* |
||||
* Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de> |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <charset.h> |
||||
#include <command.h> |
||||
#include <errno.h> |
||||
#include <test/test.h> |
||||
#include <test/suites.h> |
||||
#include <test/ut.h> |
||||
|
||||
/* Linker list entry for a Unicode test */ |
||||
#define UNICODE_TEST(_name) UNIT_TEST(_name, 0, unicode_test) |
||||
|
||||
/* Constants c1-c4 and d1-d4 encode the same letters */ |
||||
|
||||
/* Six characters translating to one utf-8 byte each. */ |
||||
static const u16 c1[] = {0x55, 0x2d, 0x42, 0x6f, 0x6f, 0x74, 0x00}; |
||||
/* One character translating to two utf-8 bytes */ |
||||
static const u16 c2[] = {0x6b, 0x61, 0x66, 0x62, 0xe1, 0x74, 0x75, 0x72, 0x00}; |
||||
/* Three characters translating to three utf-8 bytes each */ |
||||
static const u16 c3[] = {0x6f5c, 0x6c34, 0x8266, 0x00}; |
||||
/* Three letters translating to four utf-8 bytes each */ |
||||
static const u16 c4[] = {0xd801, 0xdc8d, 0xd801, 0xdc96, 0xd801, 0xdc87, |
||||
0x0000}; |
||||
|
||||
/* Illegal utf-16 strings */ |
||||
static const u16 i1[] = {0x69, 0x31, 0xdc87, 0x6c, 0x00}; |
||||
static const u16 i2[] = {0x69, 0x32, 0xd801, 0xd801, 0x6c, 0x00}; |
||||
static const u16 i3[] = {0x69, 0x33, 0xd801, 0x00}; |
||||
|
||||
/* Six characters translating to one utf-16 word each. */ |
||||
static const char d1[] = {0x55, 0x2d, 0x42, 0x6f, 0x6f, 0x74, 0x00}; |
||||
/* Eight characters translating to one utf-16 word each */ |
||||
static const char d2[] = {0x6b, 0x61, 0x66, 0x62, 0xc3, 0xa1, 0x74, 0x75, |
||||
0x72, 0x00}; |
||||
/* Three characters translating to one utf-16 word each */ |
||||
static const char d3[] = {0xe6, 0xbd, 0x9c, 0xe6, 0xb0, 0xb4, 0xe8, 0x89, |
||||
0xa6, 0x00}; |
||||
/* Three letters translating to two utf-16 word each */ |
||||
static const char d4[] = {0xf0, 0x90, 0x92, 0x8d, 0xf0, 0x90, 0x92, 0x96, |
||||
0xf0, 0x90, 0x92, 0x87, 0x00}; |
||||
|
||||
/* Illegal utf-8 strings */ |
||||
static const char j1[] = {0x6a, 0x31, 0xa1, 0x6c, 0x00}; |
||||
static const char j2[] = {0x6a, 0x32, 0xc3, 0xc3, 0x6c, 0x00}; |
||||
static const char j3[] = {0x6a, 0x33, 0xf0, 0x90, 0xf0, 0x00}; |
||||
|
||||
/* U-Boot uses UTF-16 strings in the EFI context only. */ |
||||
#if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD) |
||||
static int ut_string16(struct unit_test_state *uts) |
||||
{ |
||||
char buf[20]; |
||||
|
||||
/* Test length and precision */ |
||||
memset(buf, 0xff, sizeof(buf)); |
||||
sprintf(buf, "%8.6ls", c2); |
||||
ut_asserteq(' ', buf[1]); |
||||
ut_assert(!strncmp(&buf[2], d2, 7)); |
||||
ut_assert(!buf[9]); |
||||
|
||||
memset(buf, 0xff, sizeof(buf)); |
||||
sprintf(buf, "%8.6ls", c4); |
||||
ut_asserteq(' ', buf[4]); |
||||
ut_assert(!strncmp(&buf[5], d4, 12)); |
||||
ut_assert(!buf[17]); |
||||
|
||||
memset(buf, 0xff, sizeof(buf)); |
||||
sprintf(buf, "%-8.2ls", c4); |
||||
ut_asserteq(' ', buf[8]); |
||||
ut_assert(!strncmp(buf, d4, 8)); |
||||
ut_assert(!buf[14]); |
||||
|
||||
/* Test handling of illegal utf-16 sequences */ |
||||
memset(buf, 0xff, sizeof(buf)); |
||||
sprintf(buf, "%ls", i1); |
||||
ut_asserteq_str("i1?l", buf); |
||||
|
||||
memset(buf, 0xff, sizeof(buf)); |
||||
sprintf(buf, "%ls", i2); |
||||
ut_asserteq_str("i2?l", buf); |
||||
|
||||
memset(buf, 0xff, sizeof(buf)); |
||||
sprintf(buf, "%ls", i3); |
||||
ut_asserteq_str("i3?", buf); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_string16); |
||||
#endif |
||||
|
||||
static int ut_utf8_get(struct unit_test_state *uts) |
||||
{ |
||||
const char *s; |
||||
s32 code; |
||||
int i; |
||||
|
||||
/* Check characters less than 0x800 */ |
||||
s = d2; |
||||
for (i = 0; i < 8; ++i) { |
||||
code = utf8_get((const char **)&s); |
||||
/* c2 is the utf-8 encoding of d2 */ |
||||
ut_asserteq(c2[i], code); |
||||
if (!code) |
||||
break; |
||||
} |
||||
ut_asserteq_ptr(s, d2 + 9) |
||||
|
||||
/* Check characters less than 0x10000 */ |
||||
s = d3; |
||||
for (i = 0; i < 4; ++i) { |
||||
code = utf8_get((const char **)&s); |
||||
/* c3 is the utf-8 encoding of d3 */ |
||||
ut_asserteq(c3[i], code); |
||||
if (!code) |
||||
break; |
||||
} |
||||
ut_asserteq_ptr(s, d3 + 9) |
||||
|
||||
/* Check character greater 0xffff */ |
||||
s = d4; |
||||
code = utf8_get((const char **)&s); |
||||
ut_asserteq(0x0001048d, code); |
||||
ut_asserteq_ptr(s, d4 + 4); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf8_get); |
||||
|
||||
static int ut_utf8_put(struct unit_test_state *uts) |
||||
{ |
||||
char buffer[8] = { 0, }; |
||||
char *pos; |
||||
|
||||
/* Commercial at, translates to one character */ |
||||
pos = buffer; |
||||
ut_assert(!utf8_put('@', &pos)) |
||||
ut_asserteq(1, pos - buffer); |
||||
ut_asserteq('@', buffer[0]); |
||||
ut_assert(!buffer[1]); |
||||
|
||||
/* Latin letter G with acute, translates to two charactes */ |
||||
pos = buffer; |
||||
ut_assert(!utf8_put(0x1f4, &pos)); |
||||
ut_asserteq(2, pos - buffer); |
||||
ut_asserteq_str("\xc7\xb4", buffer); |
||||
|
||||
/* Tagalog letter i, translates to three characters */ |
||||
pos = buffer; |
||||
ut_assert(!utf8_put(0x1701, &pos)); |
||||
ut_asserteq(3, pos - buffer); |
||||
ut_asserteq_str("\xe1\x9c\x81", buffer); |
||||
|
||||
/* Hamster face, translates to four characters */ |
||||
pos = buffer; |
||||
ut_assert(!utf8_put(0x1f439, &pos)); |
||||
ut_asserteq(4, pos - buffer); |
||||
ut_asserteq_str("\xf0\x9f\x90\xb9", buffer); |
||||
|
||||
/* Illegal code */ |
||||
pos = buffer; |
||||
ut_asserteq(-1, utf8_put(0xd888, &pos)); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf8_put); |
||||
|
||||
static int ut_utf8_utf16_strlen(struct unit_test_state *uts) |
||||
{ |
||||
ut_asserteq(6, utf8_utf16_strlen(d1)); |
||||
ut_asserteq(8, utf8_utf16_strlen(d2)); |
||||
ut_asserteq(3, utf8_utf16_strlen(d3)); |
||||
ut_asserteq(6, utf8_utf16_strlen(d4)); |
||||
|
||||
/* illegal utf-8 sequences */ |
||||
ut_asserteq(4, utf8_utf16_strlen(j1)); |
||||
ut_asserteq(4, utf8_utf16_strlen(j2)); |
||||
ut_asserteq(3, utf8_utf16_strlen(j3)); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf8_utf16_strlen); |
||||
|
||||
static int ut_utf8_utf16_strnlen(struct unit_test_state *uts) |
||||
{ |
||||
ut_asserteq(3, utf8_utf16_strnlen(d1, 3)); |
||||
ut_asserteq(6, utf8_utf16_strnlen(d1, 13)); |
||||
ut_asserteq(6, utf8_utf16_strnlen(d2, 6)); |
||||
ut_asserteq(2, utf8_utf16_strnlen(d3, 2)); |
||||
ut_asserteq(4, utf8_utf16_strnlen(d4, 2)); |
||||
ut_asserteq(6, utf8_utf16_strnlen(d4, 3)); |
||||
|
||||
/* illegal utf-8 sequences */ |
||||
ut_asserteq(4, utf8_utf16_strnlen(j1, 16)); |
||||
ut_asserteq(4, utf8_utf16_strnlen(j2, 16)); |
||||
ut_asserteq(3, utf8_utf16_strnlen(j3, 16)); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf8_utf16_strnlen); |
||||
|
||||
/**
|
||||
* ut_u16_strcmp() - Compare to u16 strings. |
||||
* |
||||
* @a1: first string |
||||
* @a2: second string |
||||
* @count: number of u16 to compare |
||||
* Return: -1 if a1 < a2, 0 if a1 == a2, 1 if a1 > a2 |
||||
*/ |
||||
static int ut_u16_strcmp(const u16 *a1, const u16 *a2, size_t count) |
||||
{ |
||||
for (; (*a1 || *a2) && count; ++a1, ++a2, --count) { |
||||
if (*a1 < *a2) |
||||
return -1; |
||||
if (*a1 > *a2) |
||||
return 1; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
static int ut_utf8_utf16_strcpy(struct unit_test_state *uts) |
||||
{ |
||||
u16 buf[16]; |
||||
u16 *pos; |
||||
|
||||
pos = buf; |
||||
utf8_utf16_strcpy(&pos, d1); |
||||
ut_asserteq(6, pos - buf); |
||||
ut_assert(!ut_u16_strcmp(buf, c1, SIZE_MAX)); |
||||
|
||||
pos = buf; |
||||
utf8_utf16_strcpy(&pos, d2); |
||||
ut_asserteq(8, pos - buf); |
||||
ut_assert(!ut_u16_strcmp(buf, c2, SIZE_MAX)); |
||||
|
||||
pos = buf; |
||||
utf8_utf16_strcpy(&pos, d3); |
||||
ut_asserteq(3, pos - buf); |
||||
ut_assert(!ut_u16_strcmp(buf, c3, SIZE_MAX)); |
||||
|
||||
pos = buf; |
||||
utf8_utf16_strcpy(&pos, d4); |
||||
ut_asserteq(6, pos - buf); |
||||
ut_assert(!ut_u16_strcmp(buf, c4, SIZE_MAX)); |
||||
|
||||
/* Illegal utf-8 strings */ |
||||
pos = buf; |
||||
utf8_utf16_strcpy(&pos, j1); |
||||
ut_asserteq(4, pos - buf); |
||||
ut_assert(!ut_u16_strcmp(buf, L"j1?l", SIZE_MAX)); |
||||
|
||||
pos = buf; |
||||
utf8_utf16_strcpy(&pos, j2); |
||||
ut_asserteq(4, pos - buf); |
||||
ut_assert(!ut_u16_strcmp(buf, L"j2?l", SIZE_MAX)); |
||||
|
||||
pos = buf; |
||||
utf8_utf16_strcpy(&pos, j3); |
||||
ut_asserteq(3, pos - buf); |
||||
ut_assert(!ut_u16_strcmp(buf, L"j3?", SIZE_MAX)); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf8_utf16_strcpy); |
||||
|
||||
int ut_utf8_utf16_strncpy(struct unit_test_state *uts) |
||||
{ |
||||
u16 buf[16]; |
||||
u16 *pos; |
||||
|
||||
pos = buf; |
||||
memset(buf, 0, sizeof(buf)); |
||||
utf8_utf16_strncpy(&pos, d1, 4); |
||||
ut_asserteq(4, pos - buf); |
||||
ut_assert(!buf[4]); |
||||
ut_assert(!ut_u16_strcmp(buf, c1, 4)); |
||||
|
||||
pos = buf; |
||||
memset(buf, 0, sizeof(buf)); |
||||
utf8_utf16_strncpy(&pos, d2, 10); |
||||
ut_asserteq(8, pos - buf); |
||||
ut_assert(buf[4]); |
||||
ut_assert(!ut_u16_strcmp(buf, c2, SIZE_MAX)); |
||||
|
||||
pos = buf; |
||||
memset(buf, 0, sizeof(buf)); |
||||
utf8_utf16_strncpy(&pos, d3, 2); |
||||
ut_asserteq(2, pos - buf); |
||||
ut_assert(!buf[2]); |
||||
ut_assert(!ut_u16_strcmp(buf, c3, 2)); |
||||
|
||||
pos = buf; |
||||
memset(buf, 0, sizeof(buf)); |
||||
utf8_utf16_strncpy(&pos, d4, 2); |
||||
ut_asserteq(4, pos - buf); |
||||
ut_assert(!buf[4]); |
||||
ut_assert(!ut_u16_strcmp(buf, c4, 4)); |
||||
|
||||
pos = buf; |
||||
memset(buf, 0, sizeof(buf)); |
||||
utf8_utf16_strncpy(&pos, d4, 10); |
||||
ut_asserteq(6, pos - buf); |
||||
ut_assert(buf[5]); |
||||
ut_assert(!ut_u16_strcmp(buf, c4, SIZE_MAX)); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf8_utf16_strncpy); |
||||
|
||||
static int ut_utf16_get(struct unit_test_state *uts) |
||||
{ |
||||
const u16 *s; |
||||
s32 code; |
||||
int i; |
||||
|
||||
/* Check characters less than 0x10000 */ |
||||
s = c2; |
||||
for (i = 0; i < 9; ++i) { |
||||
code = utf16_get((const u16 **)&s); |
||||
ut_asserteq(c2[i], code); |
||||
if (!code) |
||||
break; |
||||
} |
||||
ut_asserteq_ptr(c2 + 8, s); |
||||
|
||||
/* Check character greater 0xffff */ |
||||
s = c4; |
||||
code = utf16_get((const u16 **)&s); |
||||
ut_asserteq(0x0001048d, code); |
||||
ut_asserteq_ptr(c4 + 2, s); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf16_get); |
||||
|
||||
static int ut_utf16_put(struct unit_test_state *uts) |
||||
{ |
||||
u16 buffer[4] = { 0, }; |
||||
u16 *pos; |
||||
|
||||
/* Commercial at, translates to one word */ |
||||
pos = buffer; |
||||
ut_assert(!utf16_put('@', &pos)); |
||||
ut_asserteq(1, pos - buffer); |
||||
ut_asserteq((u16)'@', buffer[0]); |
||||
ut_assert(!buffer[1]); |
||||
|
||||
/* Hamster face, translates to two words */ |
||||
pos = buffer; |
||||
ut_assert(!utf16_put(0x1f439, &pos)); |
||||
ut_asserteq(2, pos - buffer); |
||||
ut_asserteq((u16)0xd83d, buffer[0]); |
||||
ut_asserteq((u16)0xdc39, buffer[1]); |
||||
ut_assert(!buffer[2]); |
||||
|
||||
/* Illegal code */ |
||||
pos = buffer; |
||||
ut_asserteq(-1, utf16_put(0xd888, &pos)); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf16_put); |
||||
|
||||
int ut_utf16_strnlen(struct unit_test_state *uts) |
||||
{ |
||||
ut_asserteq(3, utf16_strnlen(c1, 3)); |
||||
ut_asserteq(6, utf16_strnlen(c1, 13)); |
||||
ut_asserteq(6, utf16_strnlen(c2, 6)); |
||||
ut_asserteq(2, utf16_strnlen(c3, 2)); |
||||
ut_asserteq(2, utf16_strnlen(c4, 2)); |
||||
ut_asserteq(3, utf16_strnlen(c4, 3)); |
||||
|
||||
/* illegal utf-16 word sequences */ |
||||
ut_asserteq(4, utf16_strnlen(i1, 16)); |
||||
ut_asserteq(4, utf16_strnlen(i2, 16)); |
||||
ut_asserteq(3, utf16_strnlen(i3, 16)); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf16_strnlen); |
||||
|
||||
int ut_utf16_utf8_strlen(struct unit_test_state *uts) |
||||
{ |
||||
ut_asserteq(6, utf16_utf8_strlen(c1)); |
||||
ut_asserteq(9, utf16_utf8_strlen(c2)); |
||||
ut_asserteq(9, utf16_utf8_strlen(c3)); |
||||
ut_asserteq(12, utf16_utf8_strlen(c4)); |
||||
|
||||
/* illegal utf-16 word sequences */ |
||||
ut_asserteq(4, utf16_utf8_strlen(i1)); |
||||
ut_asserteq(4, utf16_utf8_strlen(i2)); |
||||
ut_asserteq(3, utf16_utf8_strlen(i3)); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf16_utf8_strlen); |
||||
|
||||
int ut_utf16_utf8_strnlen(struct unit_test_state *uts) |
||||
{ |
||||
ut_asserteq(3, utf16_utf8_strnlen(c1, 3)); |
||||
ut_asserteq(6, utf16_utf8_strnlen(c1, 13)); |
||||
ut_asserteq(7, utf16_utf8_strnlen(c2, 6)); |
||||
ut_asserteq(6, utf16_utf8_strnlen(c3, 2)); |
||||
ut_asserteq(8, utf16_utf8_strnlen(c4, 2)); |
||||
ut_asserteq(12, utf16_utf8_strnlen(c4, 3)); |
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf16_utf8_strnlen); |
||||
|
||||
int ut_utf16_utf8_strcpy(struct unit_test_state *uts) |
||||
{ |
||||
char buf[16]; |
||||
char *pos; |
||||
|
||||
pos = buf; |
||||
utf16_utf8_strcpy(&pos, c1); |
||||
ut_asserteq(6, pos - buf); |
||||
ut_asserteq_str(d1, buf); |
||||
|
||||
pos = buf; |
||||
utf16_utf8_strcpy(&pos, c2); |
||||
ut_asserteq(9, pos - buf); |
||||
ut_asserteq_str(d2, buf); |
||||
|
||||
pos = buf; |
||||
utf16_utf8_strcpy(&pos, c3); |
||||
ut_asserteq(9, pos - buf); |
||||
ut_asserteq_str(d3, buf); |
||||
|
||||
pos = buf; |
||||
utf16_utf8_strcpy(&pos, c4); |
||||
ut_asserteq(12, pos - buf); |
||||
ut_asserteq_str(d4, buf); |
||||
|
||||
/* Illegal utf-16 strings */ |
||||
pos = buf; |
||||
utf16_utf8_strcpy(&pos, i1); |
||||
ut_asserteq(4, pos - buf); |
||||
ut_asserteq_str("i1?l", buf); |
||||
|
||||
pos = buf; |
||||
utf16_utf8_strcpy(&pos, i2); |
||||
ut_asserteq(4, pos - buf); |
||||
ut_asserteq_str("i2?l", buf); |
||||
|
||||
pos = buf; |
||||
utf16_utf8_strcpy(&pos, i3); |
||||
ut_asserteq(3, pos - buf); |
||||
ut_asserteq_str("i3?", buf); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf16_utf8_strcpy); |
||||
|
||||
int ut_utf16_utf8_strncpy(struct unit_test_state *uts) |
||||
{ |
||||
char buf[16]; |
||||
char *pos; |
||||
|
||||
pos = buf; |
||||
memset(buf, 0, sizeof(buf)); |
||||
utf16_utf8_strncpy(&pos, c1, 4); |
||||
ut_asserteq(4, pos - buf); |
||||
ut_assert(!buf[4]); |
||||
ut_assert(!strncmp(buf, d1, 4)); |
||||
|
||||
pos = buf; |
||||
memset(buf, 0, sizeof(buf)); |
||||
utf16_utf8_strncpy(&pos, c2, 10); |
||||
ut_asserteq(9, pos - buf); |
||||
ut_assert(buf[4]); |
||||
ut_assert(!strncmp(buf, d2, SIZE_MAX)); |
||||
|
||||
pos = buf; |
||||
memset(buf, 0, sizeof(buf)); |
||||
utf16_utf8_strncpy(&pos, c3, 2); |
||||
ut_asserteq(6, pos - buf); |
||||
ut_assert(!buf[6]); |
||||
ut_assert(!strncmp(buf, d3, 6)); |
||||
|
||||
pos = buf; |
||||
memset(buf, 0, sizeof(buf)); |
||||
utf16_utf8_strncpy(&pos, c4, 2); |
||||
ut_asserteq(8, pos - buf); |
||||
ut_assert(!buf[8]); |
||||
ut_assert(!strncmp(buf, d4, 8)); |
||||
|
||||
pos = buf; |
||||
memset(buf, 0, sizeof(buf)); |
||||
utf16_utf8_strncpy(&pos, c4, 10); |
||||
ut_asserteq(12, pos - buf); |
||||
ut_assert(buf[5]); |
||||
ut_assert(!strncmp(buf, d4, SIZE_MAX)); |
||||
|
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf16_utf8_strncpy); |
||||
|
||||
int ut_utf_to_lower(struct unit_test_state *uts) |
||||
{ |
||||
ut_asserteq('@', utf_to_lower('@')); |
||||
ut_asserteq('a', utf_to_lower('A')); |
||||
ut_asserteq('z', utf_to_lower('Z')); |
||||
ut_asserteq('[', utf_to_lower('[')); |
||||
ut_asserteq('m', utf_to_lower('m')); |
||||
/* Latin letter O with diaresis (umlaut) */ |
||||
ut_asserteq(0x00f6, utf_to_lower(0x00d6)); |
||||
#ifdef CONFIG_EFI_UNICODE_CAPITALIZATION |
||||
/* Cyrillic letter I*/ |
||||
ut_asserteq(0x0438, utf_to_lower(0x0418)); |
||||
#endif |
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf_to_lower); |
||||
|
||||
int ut_utf_to_upper(struct unit_test_state *uts) |
||||
{ |
||||
ut_asserteq('`', utf_to_upper('`')); |
||||
ut_asserteq('A', utf_to_upper('a')); |
||||
ut_asserteq('Z', utf_to_upper('z')); |
||||
ut_asserteq('{', utf_to_upper('{')); |
||||
ut_asserteq('M', utf_to_upper('M')); |
||||
/* Latin letter O with diaresis (umlaut) */ |
||||
ut_asserteq(0x00d6, utf_to_upper(0x00f6)); |
||||
#ifdef CONFIG_EFI_UNICODE_CAPITALIZATION |
||||
/* Cyrillic letter I */ |
||||
ut_asserteq(0x0418, utf_to_upper(0x0438)); |
||||
#endif |
||||
return 0; |
||||
} |
||||
UNICODE_TEST(ut_utf_to_upper); |
||||
|
||||
int do_ut_unicode(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
||||
{ |
||||
struct unit_test *tests = ll_entry_start(struct unit_test, unicode_test); |
||||
const int n_ents = ll_entry_count(struct unit_test, unicode_test); |
||||
|
||||
return cmd_ut_category("Unicode", tests, n_ents, argc, argv); |
||||
} |
Loading…
Reference in new issue