From f1f79812c10bd6f1659c4f4f0e3788a80834e435 Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Thu, 18 Feb 2016 11:15:22 -0600 Subject: Fix failing threadpool_auto_increment test. The threadpool_auto_increment test fails infrequently for a couple of reasons * The threadpool listener was notified of fewer tasks being pushed than were actually pushed * The "was_empty" flag was set to an unexpected value. The problem is that the test pushes three tasks into the threadpool. Test expects the threadpool to essentially gather those three tasks, and then distribute those to the threadpool threads. It also expects that as the tasks are pushed in, the threadpool listener is alerted immediately that the tasks have been pushed. In reality, a task can be distributed to the threadpool threads quicker than expected, meaning that the threadpool has already emptied by the time each subsequent task is pushed. In addition, the internal threadpool queue can be delayed so that the threadpool listener is not alerted that a task has been pushed even after the task has been executed. From the test's point of view, there's no way to be able to predict exactly the order that task execution/listener notifications will occur, and there is no way to know which listener notifications will indicate that the threadpool was previously empty. For this reason, the test has been updated to only check the things it can check. It ensures that all tasks get executed, that the threads go idle after the tasks are executed, and that the listener is told the proper number of tasks that were pushed. Change-Id: I7673120d74adad64ae6894594a606e102d9a1f2c --- tests/test_threadpool.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/test_threadpool.c b/tests/test_threadpool.c index afb981be6..d8acf26f9 100644 --- a/tests/test_threadpool.c +++ b/tests/test_threadpool.c @@ -921,6 +921,41 @@ end: return res; } +static enum ast_test_result_state wait_until_thread_state_task_pushed(struct ast_test *test, + struct test_listener_data *tld, int num_active, int num_idle, int num_tasks) +{ + enum ast_test_result_state res = AST_TEST_PASS; + struct timeval start; + struct timespec end; + + res = wait_until_thread_state(test, tld, num_active, num_idle); + if (res == AST_TEST_FAIL) { + return res; + } + + start = ast_tvnow(); + end.tv_sec = start.tv_sec + 5; + end.tv_nsec = start.tv_usec * 1000; + + ast_mutex_lock(&tld->lock); + + while (tld->num_tasks != num_tasks) { + if (ast_cond_timedwait(&tld->cond, &tld->lock, &end) == ETIMEDOUT) { + break; + } + } + + if (tld->num_tasks != num_tasks) { + ast_test_status_update(test, "Number of tasks pushed %d does not match expected %d\n", + tld->num_tasks, num_tasks); + res = AST_TEST_FAIL; + } + + ast_mutex_unlock(&tld->lock); + + return res; +} + AST_TEST_DEFINE(threadpool_auto_increment) { struct ast_threadpool *pool = NULL; @@ -1021,11 +1056,10 @@ AST_TEST_DEFINE(threadpool_auto_increment) goto end; } - res = wait_until_thread_state(test, tld, 0, 3); + res = wait_until_thread_state_task_pushed(test, tld, 0, 3, 4); if (res == AST_TEST_FAIL) { goto end; } - res = listener_check(test, listener, 1, 0, 4, 0, 3, 1); end: ast_threadpool_shutdown(pool); -- cgit v1.2.3