From 84b12d80881d8cda4598122ad4b0f8ba78d1ee4b Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Thu, 1 Apr 2021 12:44:47 -0400 Subject: [PATCH] Fix #939, rework shell test The shell may add extra output beyond the intended content, but the shell-test was only looking for exact match. Extra output may include whitespace and/or an echo of the command itself. This reworks the shell test to allow for this extra output, as long as the intended string appears in the content of the file it will pass. --- src/tests/shell-test/shell-test.c | 82 +++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 21 deletions(-) diff --git a/src/tests/shell-test/shell-test.c b/src/tests/shell-test/shell-test.c index f05ff0f9f..1cbf63d31 100644 --- a/src/tests/shell-test/shell-test.c +++ b/src/tests/shell-test/shell-test.c @@ -30,15 +30,36 @@ #define OS_TEST_SHELL_FILENAME "/drive0/shell_test.txt" +const char OS_TEST_SHELL_COMMAND[] = "echo"; +const char OS_TEST_SHELL_STRING[] = "ValueToEchoInTheFile"; + +/* + * Extra chars to allow for quoting and whitespace. + * + * There needs to be spaces between arguments, and depending + * on the shell config and its behavior it may echo extra whitespace + * and/or other chars, and a newline itself may be multiple chars (CR+LF). + * + * This allows up to this many extra chars surrounding the test string. + */ +#define OS_TEST_SHELL_MAX_EXTRA_CHARS 8 + +/* + * Sizes for the echo buffer and command buffer + * (both include some extra chars) + */ +#define OS_TEST_SHELL_ECHO_BUFFER_SIZE (sizeof(OS_TEST_SHELL_STRING) + OS_TEST_SHELL_MAX_EXTRA_CHARS) +#define OS_TEST_SHELL_CMD_BUFFER_SIZE (sizeof(OS_TEST_SHELL_COMMAND) + OS_TEST_SHELL_ECHO_BUFFER_SIZE) + /* *************************************** MAIN ************************************** */ void TestOutputToFile(void) { - char cmd[33]; + char cmd[OS_TEST_SHELL_CMD_BUFFER_SIZE + 1]; /* +1 char for term byte */ char filename[OS_MAX_PATH_LEN]; - char buffer[21]; - char copyofbuffer[21]; + char buffer[OS_TEST_SHELL_ECHO_BUFFER_SIZE + 1]; /* +1 char for term byte */ size_t size; + int32 filepos; int32 status; osal_id_t fd; @@ -48,17 +69,12 @@ void TestOutputToFile(void) strncpy(filename, "/drive0/Filename1", sizeof(filename) - 1); filename[sizeof(filename) - 1] = 0; - strcpy(buffer, "ValueToEchoInTheFile"); - strcpy(copyofbuffer, buffer); /* hold a copy of the buffer */ - /* Open In R/W mode */ status = OS_OpenCreate(&fd, OS_TEST_SHELL_FILENAME, OS_FILE_FLAG_CREATE, OS_READ_WRITE); UtAssert_True(status >= OS_SUCCESS, "status after creat = %d", (int)status); - /* Write the string */ - size = strlen(buffer); - - snprintf(cmd, sizeof(cmd), "echo -n \"%s\"", buffer); + /* assemble command */ + snprintf(cmd, sizeof(cmd), "%s \"%s\"", OS_TEST_SHELL_COMMAND, OS_TEST_SHELL_STRING); status = OS_ShellOutputToFile(cmd, fd); if (status == OS_ERR_NOT_IMPLEMENTED) @@ -69,19 +85,43 @@ void TestOutputToFile(void) { UtAssert_True(status >= OS_SUCCESS, "status after shell output to file = %d", (int)status); - strcpy(buffer, ""); - - /* lseek back to the beginning of the file */ - status = OS_lseek(fd, 0, 0); - UtAssert_True(status >= OS_SUCCESS, "status after lseek = %d", (int)status); - - /*Read what we wrote to the file */ - status = OS_read(fd, (void *)buffer, size); - UtAssert_True(status == size, "status after read = %d size = %lu", (int)status, (unsigned long)size); - if (status >= OS_SUCCESS) + /* output content should be at least this size */ + size = sizeof(OS_TEST_SHELL_STRING) - 1; + + /* Use lseek to determine size of the file */ + filepos = OS_lseek(fd, 0, OS_SEEK_END); + UtAssert_True(filepos >= size, "size of output file=%d, echoed string len=%lu", (int)filepos, + (unsigned long)size); + + /* + * Different shells vary in how the echoed output actually appears in the file. + * + * Depending on config it may echo the command itself in addition to the output, + * and there may be whitespace/newlines that should be ignored. + * + * Either way the content should appear toward the _end_ of the file. + */ + if (filepos < OS_TEST_SHELL_ECHO_BUFFER_SIZE) { - UtAssert_True(strcmp(buffer, copyofbuffer) == 0, "Read: %s, Written: %s", buffer, copyofbuffer); + filepos = 0; } + else + { + filepos -= OS_TEST_SHELL_ECHO_BUFFER_SIZE; + } + + status = OS_lseek(fd, filepos, OS_SEEK_SET); + UtAssert_True(status == filepos, "lseek to position %d, result=%d", (int)filepos, (int)status); + + /* Read what we wrote to the file */ + /* By memset() first and reading one byte less than the buffer, the result is ensured to be terminated */ + memset(buffer, 0, sizeof(buffer)); + status = OS_read(fd, buffer, sizeof(buffer) - 1); + UtAssert_True(status >= size, "status after read = %d, min valid size = %lu", (int)status, (unsigned long)size); + + /* The test should pass if the expected string is anywhere in the buffer */ + UtAssert_True(strstr(buffer, OS_TEST_SHELL_STRING) != NULL, "Read: \'%s\', Expected: \'%s\'", buffer, + OS_TEST_SHELL_STRING); } /* close the file */