Skip to content

Commit

Permalink
tests: pipes: Add pipe flush tests
Browse files Browse the repository at this point in the history
Extends the pipes tests to include tests for k_pipe_flush() and
k_pipe_buffer_flush().

Signed-off-by: Peter Mitsis <[email protected]>
  • Loading branch information
peter-mitsis authored and nashif committed Jan 10, 2022
1 parent d1353a4 commit 192265c
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 2 deletions.
7 changes: 5 additions & 2 deletions tests/kernel/pipe/pipe/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ extern void test_pipe_get_invalid_size(void);
extern void test_pipe_get_min_xfer(void);
extern void test_pipe_put_min_xfer(void);
extern void test_pipe_define_at_runtime(void);
extern void test_pipe_flush(void);

extern struct k_pipe test_pipe;
extern struct k_pipe small_pipe;
extern struct k_sem put_sem, get_sem, sync_sem, multiple_send_sem;
extern struct k_stack stack_1;
extern struct k_thread get_single_tid;
Expand All @@ -27,7 +29,7 @@ extern struct k_thread get_single_tid;
void test_main(void)
{
k_thread_access_grant(k_current_get(),
&test_pipe, &put_sem, &get_sem,
&test_pipe, &small_pipe, &put_sem, &get_sem,
&sync_sem, &multiple_send_sem,
&get_single_tid, &stack_1);

Expand All @@ -42,7 +44,8 @@ void test_main(void)
ztest_user_unit_test(test_pipe_get_invalid_size),
ztest_user_unit_test(test_pipe_get_min_xfer),
ztest_user_unit_test(test_pipe_put_min_xfer),
ztest_unit_test(test_pipe_define_at_runtime)
ztest_unit_test(test_pipe_define_at_runtime),
ztest_unit_test(test_pipe_flush)
);

ztest_run_test_suite(test_pipe);
Expand Down
130 changes: 130 additions & 0 deletions tests/kernel/pipe/pipe/src/test_pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ K_PIPE_DEFINE(test_pipe, 256, 4);
#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACKSIZE)
#define PIPE_SIZE (256)

K_PIPE_DEFINE(small_pipe, 10, 4);

K_THREAD_STACK_DEFINE(stack_1, STACK_SIZE);

K_SEM_DEFINE(get_sem, 0, 1);
Expand Down Expand Up @@ -1024,3 +1026,131 @@ void test_pipe_define_at_runtime(void)
PIPE_SIZE, &read,
PIPE_SIZE, TIMEOUT_VAL), -EAGAIN, NULL);
}

/**
* @brief Helper thread to test k_pipe_flush() and k_pipe_buffer_flush()
*
* This helper thread attempts to write 50 bytes to the pipe identified by
* [p1], which has an internal buffer size of 10. This helper thread is
* expected to fill the internal buffer, and then block until it can complete
* the write.
*/
void test_pipe_flush_helper(void *p1, void *p2, void *p3)
{
struct k_pipe *pipe = (struct k_pipe *)p1;
char buffer[50];
size_t i;
size_t bytes_written;
int rv;

for (i = 0; i < sizeof(buffer); i++) {
buffer[i] = i;
}

rv = k_pipe_put(pipe, buffer, sizeof(buffer), &bytes_written,
sizeof(buffer), K_FOREVER);

zassert_true(rv == 0, "k_pipe_put() failed with %d", rv);
zassert_true(bytes_written == sizeof(buffer),
"Expected %zu bytes written, not %zu",
sizeof(buffer), bytes_written);
}

/**
* @brief Test flushing a pipe
*
* @ingroup kernel_pipe_tests
*
* @details
* Test Objective:
* - Check if the kernel flushes a pipe properly at runtime.
*
* Testing techniques:
* - function and block box testing,Interface testing,
* Dynamic analysis and testing.
*
* Prerequisite Conditions:
* - CONFIG_TEST_USERSPACE.
*
* Input Specifications:
* - N/A
*
* Test Procedure:
* -# Define and initialize a pipe at run time
* -# Use this pipe to transfer data.
* -# Have a thread fill and block on writing to the pipe
* -# Flush the pipe and check that the pipe is completely empty
* -# Have a thread fill and block on writing to the pipe
* -# Flush only the pipe's buffer and check the results
*
* Expected Test Result:
* - Reading from the pipe after k_pipe_flush() results in no data to read.
* - Reading from the pipe after k_pipe_buffer_flush() results in read data,
* but missing the original data that was in the buffer prior to the flush.
*
* Pass/Fail Criteria:
* - Successful if check points in test procedure are all passed, otherwise
* failure.
*
* Assumptions and Constraints:
* - N/A
*/
void test_pipe_flush(void)
{
unsigned char results_buffer[50];
size_t bytes_read;
size_t i;
int rv;

memset(results_buffer, 0, sizeof(results_buffer));

(void)k_thread_create(&get_single_tid, stack_1, STACK_SIZE,
test_pipe_flush_helper, &small_pipe, NULL, NULL,
K_PRIO_PREEMPT(0), K_INHERIT_PERMS | K_USER,
K_NO_WAIT);

k_sleep(K_MSEC(50)); /* give helper thread time to execute */

/* Completely flush the pipe */

k_pipe_flush(&small_pipe);

rv = k_pipe_get(&small_pipe, results_buffer, sizeof(results_buffer),
&bytes_read, 0, K_MSEC(100));

zassert_true(rv == 0, "k_pipe_get() failed with %d\n", rv);
zassert_true(bytes_read == 0,
"k_pipe_get() unexpectedly read %zu bytes\n", bytes_read);

rv = k_thread_join(&get_single_tid, K_MSEC(50));
zassert_true(rv == 0, "Wait for helper thread failed (%d)", rv);

(void)k_thread_create(&get_single_tid, stack_1, STACK_SIZE,
test_pipe_flush_helper, &small_pipe, NULL, NULL,
K_PRIO_PREEMPT(0), K_INHERIT_PERMS | K_USER,
K_NO_WAIT);

k_sleep(K_MSEC(50)); /* give helper thread time to execute */

/*
* Only flush the pipe's buffer. This is expected to leave 40 bytes
* left to receive.
*/

k_pipe_buffer_flush(&small_pipe);

rv = k_pipe_get(&small_pipe, results_buffer, sizeof(results_buffer),
&bytes_read, 0, K_MSEC(100));

zassert_true(rv == 0, "k_pipe_get() failed with %d\n", rv);
zassert_true(bytes_read == 40,
"k_pipe_get() unexpectedly read %zu bytes\n", bytes_read);
for (i = 0; i < 40; i++) {
zassert_true(results_buffer[i] == (unsigned char)(i + 10),
"At offset %zd, expected byte %02x, not %02x\n",
i, (i + 10), results_buffer[i]);
}

rv = k_thread_join(&get_single_tid, K_MSEC(50));
zassert_true(rv == 0, "Wait for helper thread failed (%d)", rv);
}

0 comments on commit 192265c

Please sign in to comment.