Skip to content

Commit

Permalink
Run as much of the progress report as we can in test mode, so it can …
Browse files Browse the repository at this point in the history
…be stress tested

* Instead of simply exiting the progress calls, we now perform the progress bar
  computations and run the various ASSERTS, so we can stress test them in some new
  progress tests
* Also apply minor additional code improvements.
  • Loading branch information
pbatard committed Feb 28, 2024
1 parent cf00bb3 commit 6a6589b
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 25 deletions.
6 changes: 2 additions & 4 deletions src/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,8 @@ EFI_STATUS EFIAPI efi_main(
if (EFI_ERROR(Status))
goto out;

if (IsTestMode) {
// Print any extra data we want to validate
Print(L"[TEST] TotalBytes = 0x%lX\n", HashList.TotalBytes);
}
// Print any extra data we want to validate
PrintTest(L"TotalBytes = 0x%lX", HashList.TotalBytes);

// Set up the progress bar data
Progress.Type = (HashList.TotalBytes == 0) ? PROGRESS_TYPE_FILE : PROGRESS_TYPE_BYTE;
Expand Down
7 changes: 6 additions & 1 deletion src/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,15 @@ typedef UINT32 CHAR32;
#define ARRAY_SIZE(Array) (sizeof(Array) / sizeof((Array)[0]))
#endif

/* Standard MIN() macro */
/* Standard MIN/MAX macro */
#ifndef MIN
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#endif

#ifndef MAX
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
#endif

/* FreePool() replacement, that NULLs the freed pointer. */
#define SafeFree(p) do { FreePool(p); p = NULL;} while(0)

Expand Down Expand Up @@ -192,6 +196,7 @@ typedef struct {
#define PrintError(fmt, ...) do { SetTextPosition(MARGIN_H, AlertYPos++); \
SetText(TEXT_RED); Print(L"[FAIL]"); DefText(); \
Print(L" " fmt L": [%d] %r\n", ##__VA_ARGS__, (Status&0x7FFFFFFF), Status); } while (0)
#define PrintTest(fmt, ...) do { if (IsTestMode) Print(L"[TEST] " fmt L"\n", ##__VA_ARGS__); } while(0)

/* Convenience macro to position text on screen (when not running in test mode). */
#define SetTextPosition(x, y) do { if (!IsTestMode) gST->ConOut->SetCursorPosition(gST->ConOut, x, y);} while (0)
Expand Down
46 changes: 26 additions & 20 deletions src/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ VOID PrintCentered(
{
UINTN MessagePos;

MessagePos = Console.Cols / 2 - SafeStrLen(Message) / 2;
V_ASSERT(MessagePos > MARGIN_H);
if (!IsTestMode) {
MessagePos = Console.Cols / 2 - SafeStrLen(Message) / 2;
V_ASSERT(MessagePos > MARGIN_H);
SetTextPosition(0, YPos);
Print(EmptyLine);
SetTextPosition(MessagePos, YPos);
Expand All @@ -103,7 +103,6 @@ VOID PrintFailedEntry(
return;

// Truncate the path in case it's very long.
// TODO: Ideally we'd want long path reduction similar to what Windows does.
if (SafeStrLen(Path) > 80)
Path[80] = L'\0';
if (!IsTestMode) {
Expand All @@ -116,7 +115,7 @@ VOID PrintFailedEntry(
Print(L"[FAIL]");
DefText();
// Display a more explicit message (than "CRC Error") for files that fail MD5
if ((Status & 0x7FFFFFFF) == 27)
if (Status == EFI_CRC_ERROR)
Print(L" File '%s': [27] MD5 Checksum Error\n", Path);
else
Print(L" File '%s': [%d] %r\n", Path, (Status & 0x7FFFFFFF), Status);
Expand All @@ -135,8 +134,8 @@ VOID InitProgress(

Progress->Active = FALSE;

if (Console.Cols < COLS_MIN || Console.Rows < ROWS_MIN || Console.Cols >= STRING_MAX ||
Progress->Message == NULL || IsTestMode)
if (Console.Cols < COLS_MIN || Console.Rows < ROWS_MIN ||
Console.Cols >= STRING_MAX || Progress->Message == NULL)
return;

if (SafeStrLen(Progress->Message) > Console.Cols - MARGIN_H * 2 - 8)
Expand All @@ -152,12 +151,14 @@ VOID InitProgress(
Progress->LastCol = 0;
Progress->PPos = MessagePos + SafeStrLen(Progress->Message) + 2;

SetTextPosition(MessagePos, Progress->YPos);
Print(L"%s: 0.0%%", Progress->Message);
if (!IsTestMode) {
SetTextPosition(MessagePos, Progress->YPos);
Print(L"%s: 0.0%%", Progress->Message);

SetTextPosition(MARGIN_H, Progress->YPos + 1);
for (i = 0; i < Console.Cols - MARGIN_H * 2; i++)
Print(L"░");
SetTextPosition(MARGIN_H, Progress->YPos + 1);
for (i = 0; i < Console.Cols - MARGIN_H * 2; i++)
Print(L"░");
}

Progress->Active = TRUE;
}
Expand All @@ -174,22 +175,26 @@ VOID UpdateProgress(
UINTN CurCol, PerMille;

if (Progress == NULL || !Progress->Active || Progress->Maximum == 0 ||
Console.Cols < COLS_MIN || Console.Cols >= STRING_MAX || IsTestMode)
Console.Cols < COLS_MIN || Console.Cols >= STRING_MAX)
return;

if (Progress->Current > Progress->Maximum)
Progress->Current = Progress->Maximum;

// Update the percentage figure
PerMille = (UINTN)((Progress->Current * 1000) / Progress->Maximum);
SetTextPosition(Progress->PPos, Progress->YPos);
Print(L"%d.%d%%", PerMille / 10, PerMille % 10);
if (!IsTestMode) {
SetTextPosition(Progress->PPos, Progress->YPos);
Print(L"%d.%d%%", PerMille / 10, PerMille % 10);
}

// Update the progress bar
CurCol = (UINTN)((Progress->Current * (Console.Cols - MARGIN_H * 2)) / Progress->Maximum);
for (; CurCol > Progress->LastCol && Progress->LastCol < Console.Cols; Progress->LastCol++) {
SetTextPosition(MARGIN_H + Progress->LastCol, Progress->YPos + 1);
Print(L"%c", BLOCKELEMENT_FULL_BLOCK);
if (!IsTestMode) {
for (; CurCol > Progress->LastCol && Progress->LastCol < Console.Cols; Progress->LastCol++) {
SetTextPosition(MARGIN_H + Progress->LastCol, Progress->YPos + 1);
Print(L"%c", BLOCKELEMENT_FULL_BLOCK);
}
}

if (Progress->Current == Progress->Maximum)
Expand All @@ -210,12 +215,13 @@ VOID CountDown(
UINTN MessagePos, CounterPos;
INTN i;

if (IsTestMode)
return;

MessagePos = Console.Cols / 2 - SafeStrLen(Message) / 2 - 1;
CounterPos = MessagePos + SafeStrLen(Message) + 2;
V_ASSERT(MessagePos > MARGIN_H);

if (IsTestMode)
return;

SetTextPosition(0, Console.Rows - 2);
Print(EmptyLine);
SetTextPosition(MessagePos, Console.Rows - 2);
Expand Down
30 changes: 30 additions & 0 deletions tests/test_list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,33 @@
Test bootloader
< rm -f image/efi/boot/*_original.efi
< rm image/file*

# Chainload original bootloader without md5sum
> 7z x ./tests/chainload.7z -y -o./image/efi/boot
> rm -f md5sum.txt
Test bootloader
< rm -f image/efi/boot/*_original.efi

# Progress with TotalBytes too small
> echo "# md5sum_totalbytes = 0x1" > image/md5sum.txt
> for i in {64..1024..64}; do dd if=/dev/urandom of=image/file$i bs=1k count=$i; done
> (cd image; md5sum file* >> md5sum.txt)
[TEST] TotalBytes = 0x1
16/16 files processed [0 failed]
< rm image/file*

# Progress with TotalBytes exact
> echo "# md5sum_totalbytes = 0x880000" > image/md5sum.txt
> for i in {64..1024..64}; do dd if=/dev/urandom of=image/file$i bs=1k count=$i; done
> (cd image; md5sum file* >> md5sum.txt)
[TEST] TotalBytes = 0x880000
16/16 files processed [0 failed]
< rm image/file*

# Progress with TotalBytes too large
> echo "# md5sum_totalbytes = 0x1234567890abcdef" > image/md5sum.txt
> for i in {64..1024..64}; do dd if=/dev/urandom of=image/file$i bs=1k count=$i; done
> (cd image; md5sum file* >> md5sum.txt)
[TEST] TotalBytes = 0x1234567890ABCDEF
16/16 files processed [0 failed]
< rm image/file*

0 comments on commit 6a6589b

Please sign in to comment.