tests/thread_zombie/: new test for zombie state threads
ps is optional
This commit is contained in:
parent
c581d2c055
commit
cc0243f585
7
tests/thread_zombie/Makefile
Normal file
7
tests/thread_zombie/Makefile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
|
DISABLE_MODULE += auto_init
|
||||||
|
# For better testing use ps
|
||||||
|
#USEMODULE += ps
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.include
|
||||||
9
tests/thread_zombie/Makefile.ci
Normal file
9
tests/thread_zombie/Makefile.ci
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
BOARD_INSUFFICIENT_MEMORY := \
|
||||||
|
arduino-duemilanove \
|
||||||
|
arduino-leonardo \
|
||||||
|
arduino-nano \
|
||||||
|
arduino-uno \
|
||||||
|
atmega328p \
|
||||||
|
nucleo-f031k6 \
|
||||||
|
stm32f030f4-demo
|
||||||
|
#
|
||||||
275
tests/thread_zombie/main.c
Normal file
275
tests/thread_zombie/main.c
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Freie Universität Berlin,
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup tests
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Thread test application
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julian Holzwarth <julian.holzwarth@fu-berlin.de>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "thread.h"
|
||||||
|
#include "test_utils/interactive_sync.h"
|
||||||
|
#ifdef MODULE_PS
|
||||||
|
#include "ps.h"
|
||||||
|
#endif /* MODULE_PS */
|
||||||
|
|
||||||
|
#define TEST_THREAD_STACKSIZE ((2 * THREAD_STACKSIZE_IDLE) + \
|
||||||
|
THREAD_EXTRA_STACKSIZE_PRINTF)
|
||||||
|
|
||||||
|
/* stacks for testing threads */
|
||||||
|
static char t2_stack[TEST_THREAD_STACKSIZE];
|
||||||
|
static char t3_stack[TEST_THREAD_STACKSIZE];
|
||||||
|
static char t4_stack[TEST_THREAD_STACKSIZE];
|
||||||
|
|
||||||
|
/* function for testing threads */
|
||||||
|
void *second_thread(void *arg)
|
||||||
|
{
|
||||||
|
printf("Thread: %d is starting\n", (int)arg);
|
||||||
|
printf("Thread: %d calls zombify\n", (int)arg);
|
||||||
|
thread_zombify();
|
||||||
|
puts("ERROR zombie runs again!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
test_utils_interactive_sync();
|
||||||
|
|
||||||
|
/* save thread count on test start */
|
||||||
|
int current_thread_count;
|
||||||
|
int start_thread_count = sched_num_threads;
|
||||||
|
|
||||||
|
printf("Number of threads before the test = %d\n", start_thread_count);
|
||||||
|
|
||||||
|
/* creating threads for testing */
|
||||||
|
puts("Creating first thread (sleeping)");
|
||||||
|
kernel_pid_t first_pid = thread_create(
|
||||||
|
t2_stack, sizeof(t2_stack),
|
||||||
|
THREAD_PRIORITY_MAIN - 1,
|
||||||
|
THREAD_CREATE_SLEEPING | THREAD_CREATE_STACKTEST,
|
||||||
|
second_thread, (void *)1, "nr1");
|
||||||
|
|
||||||
|
#ifdef MODULE_PS
|
||||||
|
ps();
|
||||||
|
puts("");
|
||||||
|
#endif /* MODULE_PS */
|
||||||
|
|
||||||
|
puts("Creating second thread (sleeping)");
|
||||||
|
kernel_pid_t second_pid = thread_create(
|
||||||
|
t3_stack, sizeof(t3_stack),
|
||||||
|
THREAD_PRIORITY_MAIN - 1,
|
||||||
|
THREAD_CREATE_SLEEPING | THREAD_CREATE_STACKTEST,
|
||||||
|
second_thread, (void *)2, "nr2");
|
||||||
|
#ifdef MODULE_PS
|
||||||
|
ps();
|
||||||
|
puts("");
|
||||||
|
#endif /* MODULE_PS */
|
||||||
|
|
||||||
|
puts("Creating third thread (sleeping)");
|
||||||
|
kernel_pid_t third_pid = thread_create(
|
||||||
|
t4_stack, sizeof(t4_stack),
|
||||||
|
THREAD_PRIORITY_MAIN - 1,
|
||||||
|
THREAD_CREATE_SLEEPING | THREAD_CREATE_STACKTEST,
|
||||||
|
second_thread, (void *)3, "nr3");
|
||||||
|
#ifdef MODULE_PS
|
||||||
|
ps();
|
||||||
|
puts("");
|
||||||
|
#endif /* MODULE_PS */
|
||||||
|
|
||||||
|
current_thread_count = sched_num_threads;
|
||||||
|
printf("Current number of threads = %d\n", current_thread_count);
|
||||||
|
|
||||||
|
/* check if all threads got created */
|
||||||
|
if (start_thread_count + 3 != current_thread_count) {
|
||||||
|
puts("Error wrong thread count");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wakeup first thread and check if the thread zombified itself */
|
||||||
|
puts("Waking up first thread");
|
||||||
|
thread_wakeup(first_pid);
|
||||||
|
|
||||||
|
#ifdef MODULE_PS
|
||||||
|
ps();
|
||||||
|
puts("");
|
||||||
|
#endif /* MODULE_PS */
|
||||||
|
|
||||||
|
current_thread_count = sched_num_threads;
|
||||||
|
printf("Current number of threads = %d\n", current_thread_count);
|
||||||
|
if (thread_getstatus(first_pid) != STATUS_ZOMBIE) {
|
||||||
|
puts("Error Wrong Status: first thread is not a zombie!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (start_thread_count + 3 != current_thread_count) {
|
||||||
|
puts("Error wrong thread count");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wakeup second thread and check if the thread zombified itself */
|
||||||
|
puts("Waking up second thread");
|
||||||
|
thread_wakeup(second_pid);
|
||||||
|
|
||||||
|
#ifdef MODULE_PS
|
||||||
|
ps();
|
||||||
|
puts("");
|
||||||
|
#endif /* MODULE_PS */
|
||||||
|
|
||||||
|
current_thread_count = sched_num_threads;
|
||||||
|
printf("Current number of threads = %d\n", current_thread_count);
|
||||||
|
|
||||||
|
if (thread_getstatus(first_pid) != STATUS_ZOMBIE) {
|
||||||
|
puts("Error Wrong Status: first thread is not a zombie!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (thread_getstatus(second_pid) != STATUS_ZOMBIE) {
|
||||||
|
puts("Error Wrong Status: second thread is not a zombie!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (start_thread_count + 3 != current_thread_count) {
|
||||||
|
puts("Error wrong thread count");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* kill first zombie thread and check if the thread still exist (it should not) */
|
||||||
|
puts("Kill first thread");
|
||||||
|
|
||||||
|
if (thread_kill_zombie(first_pid) != 1) {
|
||||||
|
puts("Error thread_kill_zombie returned an error");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MODULE_PS
|
||||||
|
ps();
|
||||||
|
puts("");
|
||||||
|
#endif /* MODULE_PS */
|
||||||
|
|
||||||
|
current_thread_count = sched_num_threads;
|
||||||
|
printf("Current number of threads = %d\n", current_thread_count);
|
||||||
|
|
||||||
|
if (thread_getstatus(first_pid) != STATUS_NOT_FOUND) {
|
||||||
|
puts("Error first Thread does still exist");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (thread_getstatus(second_pid) != STATUS_ZOMBIE) {
|
||||||
|
puts("Error Wrong Status: second thread is not a zombie!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (start_thread_count + 2 != current_thread_count) {
|
||||||
|
puts("Error wrong thread count");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wakeup third thread and check if the thread zombified itself */
|
||||||
|
puts("Waking up third thread");
|
||||||
|
thread_wakeup(third_pid);
|
||||||
|
|
||||||
|
#ifdef MODULE_PS
|
||||||
|
ps();
|
||||||
|
puts("");
|
||||||
|
#endif /* MODULE_PS */
|
||||||
|
|
||||||
|
if (thread_getstatus(first_pid) != STATUS_NOT_FOUND) {
|
||||||
|
puts("Error first Thread does still exist");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (thread_getstatus(second_pid) != STATUS_ZOMBIE) {
|
||||||
|
puts("Error Wrong Status: third thread is not a zombie!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (thread_getstatus(third_pid) != STATUS_ZOMBIE) {
|
||||||
|
puts("Error Wrong Status: second thread is not a zombie!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (start_thread_count + 2 != current_thread_count) {
|
||||||
|
puts("Error wrong thread count");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if threads are created normally after killing a zombie */
|
||||||
|
puts("Creating fourth thread (sleeping)");
|
||||||
|
kernel_pid_t last_pid = thread_create(
|
||||||
|
t2_stack, sizeof(t2_stack),
|
||||||
|
THREAD_PRIORITY_MAIN - 1,
|
||||||
|
THREAD_CREATE_SLEEPING | THREAD_CREATE_STACKTEST,
|
||||||
|
second_thread, (void *)4, "nr4");
|
||||||
|
|
||||||
|
#ifdef MODULE_PS
|
||||||
|
ps();
|
||||||
|
puts("");
|
||||||
|
#endif /* MODULE_PS */
|
||||||
|
|
||||||
|
if (thread_getstatus(last_pid) != STATUS_SLEEPING) {
|
||||||
|
puts("Error last Thread is not sleeping");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (last_pid != first_pid) {
|
||||||
|
puts("Error thread did not reuse first thread pid");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (thread_getstatus(second_pid) != STATUS_ZOMBIE) {
|
||||||
|
puts("Error Wrong Status: third thread is not a zombie!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (thread_getstatus(third_pid) != STATUS_ZOMBIE) {
|
||||||
|
puts("Error Wrong Status: second thread is not a zombie!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (start_thread_count + 2 != current_thread_count) {
|
||||||
|
puts("Error wrong thread count");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MODULE_PS
|
||||||
|
ps();
|
||||||
|
puts("");
|
||||||
|
#endif /* MODULE_PS */
|
||||||
|
|
||||||
|
current_thread_count = sched_num_threads;
|
||||||
|
printf("Current number of threads = %d\n", current_thread_count);
|
||||||
|
|
||||||
|
/* check if all threads got created */
|
||||||
|
if (start_thread_count + 3 != current_thread_count) {
|
||||||
|
puts("Error wrong thread count");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
24
tests/thread_zombie/tests/01-run.py
Executable file
24
tests/thread_zombie/tests/01-run.py
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (C) 2019 Freie Universität Berlin,
|
||||||
|
#
|
||||||
|
# This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
# General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
# directory for more details.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from testrunner import run
|
||||||
|
|
||||||
|
|
||||||
|
def testfunc(child):
|
||||||
|
child.expect("OK")
|
||||||
|
child.expect("OK")
|
||||||
|
child.expect("OK")
|
||||||
|
child.expect("OK")
|
||||||
|
child.expect("OK")
|
||||||
|
child.expect("OK")
|
||||||
|
child.expect("OK")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(run(testfunc))
|
||||||
Loading…
x
Reference in New Issue
Block a user