mirror of
https://github.com/Pithikos/C-Thread-Pool
synced 2024-11-21 21:21:23 +03:00
Refactored tests
This commit is contained in:
parent
8658cde5a7
commit
e60a838d19
33
tests/funcs
Normal file
33
tests/funcs
Normal file
@ -0,0 +1,33 @@
|
||||
#! /bin/bash
|
||||
|
||||
#
|
||||
# This file should be included by other shell scripts that
|
||||
# want to use any of the functions
|
||||
#
|
||||
|
||||
|
||||
function needle { #needle #haystack
|
||||
python -c "import re; print(re.search(r'$1', '$2').group(0))"
|
||||
if (( $? != 0 )); then
|
||||
msg="Python script error"
|
||||
err "$msg" "$msg"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function extract_num { #needle with number #haystack
|
||||
string=$(needle "$1" "$2")
|
||||
needle "[0-9]*" "$string"
|
||||
if (( $? != 0 )); then
|
||||
msg="Python script error"
|
||||
err "$msg" "$msg"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function err { #string #log
|
||||
echo "------------------- ERROR ------------------------"
|
||||
echo "$1"
|
||||
echo "$2" >> memleaks.log
|
||||
exit 1
|
||||
}
|
135
tests/memleaks
135
tests/memleaks
@ -5,97 +5,23 @@
|
||||
# valgrind is used so make sure you have it installed
|
||||
#
|
||||
|
||||
|
||||
|
||||
# --------------------------- Generic ----------------------------------
|
||||
|
||||
function needle { #needle #haystack
|
||||
python -c "import re; print(re.search(r'$1', '$2').group(0))"
|
||||
if (( $? != 0 )); then
|
||||
err "Python script error"
|
||||
fi
|
||||
}
|
||||
function extract_num { #needle with number #haystack
|
||||
string=$(needle "$1" "$2")
|
||||
needle "[0-9]*" "$string"
|
||||
if (( $? != 0 )); then
|
||||
err "Python script error"
|
||||
fi
|
||||
}
|
||||
function err { #string #log
|
||||
echo "------------------- ERROR ------------------------"
|
||||
echo "$1"
|
||||
echo "$2" >> memleaks.log
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
. funcs
|
||||
|
||||
|
||||
# ---------------------------- Tests -----------------------------------
|
||||
|
||||
|
||||
function test_single_thread_alloc {
|
||||
|
||||
read -d '' code <<"EOF"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include "../thpool.h"
|
||||
|
||||
int main(){
|
||||
|
||||
thpool_t* threadpool;
|
||||
threadpool = thpool_init(1);
|
||||
thpool_destroy(threadpool);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "Testing single thread creation and destruction in pool"
|
||||
echo "$code" > _test_.c
|
||||
gcc _test_.c ../thpool.c -pthread -o test
|
||||
output=$(valgrind --leak-check=full --track-origins=yes ./test 2>&1 /dev/null)
|
||||
function test_thread_free { #threads
|
||||
echo "Testing creation and destruction of threads(=$1)"
|
||||
gcc src/no_work.c ../thpool.c -pthread -o test
|
||||
output=$(valgrind --leak-check=full --track-origins=yes ./test "$1" 2>&1 > /dev/null)
|
||||
heap_usage=$(echo "$output" | grep "total heap usage")
|
||||
allocs=$(extract_num "[0-9]* allocs" "$heap_usage")
|
||||
frees=$(extract_num "[0-9]* frees" "$heap_usage")
|
||||
if [ "$allocs" == "$frees" ]; then
|
||||
return
|
||||
if (( "$allocs" == 0 )); then
|
||||
err "Allocated 0 times. Something is wrong.." "$output"
|
||||
fi
|
||||
err "Allocated $allocs times but freed only $frees" "$output"
|
||||
}
|
||||
|
||||
|
||||
function test_many_thread_allocs {
|
||||
|
||||
read -d '' code <<"EOF"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include "../thpool.h"
|
||||
|
||||
int main(){
|
||||
|
||||
thpool_t* threadpool;
|
||||
threadpool = thpool_init(4); // VALGRIND SPENDS 1 SEC TO KILL EACH THREAD
|
||||
// SO KEEP THIS LOW
|
||||
thpool_destroy(threadpool);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "Testing multiple threads creation and destruction in pool (est ~4secs)"
|
||||
echo "$code" > _test_.c
|
||||
gcc _test_.c ../thpool.c -pthread -o test
|
||||
output=$(valgrind --leak-check=full --track-origins=yes ./test 2>&1 /dev/null)
|
||||
heap_usage=$(echo "$output" | grep "total heap usage")
|
||||
allocs=$(extract_num "[0-9]* allocs" "$heap_usage")
|
||||
frees=$(extract_num "[0-9]* frees" "$heap_usage")
|
||||
if [ "$allocs" == "$frees" ]; then
|
||||
if (( "$allocs" == "$frees" )); then
|
||||
return
|
||||
fi
|
||||
err "Allocated $allocs times but freed only $frees" "$output"
|
||||
@ -103,44 +29,33 @@ EOF
|
||||
|
||||
|
||||
# This is the same with test_many_thread_allocs but multiplied
|
||||
function test_many_thread_allocs_multi {
|
||||
|
||||
read -d '' code <<"EOF"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include "../thpool.h"
|
||||
|
||||
int main(){
|
||||
|
||||
thpool_t* threadpool;
|
||||
threadpool = thpool_init(4); // VALGRIND SPENDS 1 SEC TO KILL EACH THREAD
|
||||
// SO KEEP THIS LOW
|
||||
thpool_destroy(threadpool);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "Testing multiple threads creation and destruction in pool (est ~40secs)"
|
||||
echo "$code" > _test_.c
|
||||
gcc _test_.c ../thpool.c -pthread -o test
|
||||
for i in {1..10}; do
|
||||
output=$(valgrind --leak-check=full --track-origins=yes ./test 2>&1 /dev/null)
|
||||
function test_thread_free_multi { #threads #times
|
||||
echo "Testing multiple threads creation and destruction in pool (this can take a while)"
|
||||
gcc src/no_work.c ../thpool.c -pthread -o test
|
||||
for ((i = 1; i <= $1; i++)); do
|
||||
output=$(valgrind --leak-check=full --track-origins=yes ./test "$1" 2>&1 > /dev/null)
|
||||
heap_usage=$(echo "$output" | grep "total heap usage")
|
||||
allocs=$(extract_num "[0-9]* allocs" "$heap_usage")
|
||||
frees=$(extract_num "[0-9]* frees" "$heap_usage")
|
||||
if [ "$allocs" != "$frees" ]; then
|
||||
if (( "$allocs" == 0 )); then
|
||||
err "Allocated 0 times. Something is wrong.." "$output"
|
||||
fi
|
||||
if (( "$allocs" != "$frees" )); then
|
||||
err "Allocated $allocs times but freed only $frees" "$output"
|
||||
fi
|
||||
echo "Allocs: $allocs Frees: $frees"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Run tests
|
||||
test_single_thread_alloc
|
||||
test_many_thread_allocs
|
||||
test_many_thread_allocs_multi
|
||||
test_thread_free 1
|
||||
test_thread_free 2
|
||||
test_thread_free 4
|
||||
test_thread_free 8
|
||||
test_thread_free 1
|
||||
test_thread_free 100
|
||||
test_thread_free_multi 4 20
|
||||
|
||||
echo "No memory leaks"
|
||||
|
41
tests/src/conc_increment.c
Normal file
41
tests/src/conc_increment.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../thpool.h"
|
||||
|
||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
int sum=0;
|
||||
|
||||
|
||||
void add_one() {
|
||||
pthread_mutex_lock(&mutex);
|
||||
sum ++;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
|
||||
char* p;
|
||||
if (argc != 3){
|
||||
puts("This testfile needs excactly two arguments");
|
||||
exit(1);
|
||||
}
|
||||
int jobs = strtol(argv[1], &p, 10);
|
||||
int threads = strtol(argv[2], &p, 10);
|
||||
|
||||
thpool_t* threadpool;
|
||||
threadpool = thpool_init(threads);
|
||||
|
||||
int n;
|
||||
for (n=0; n<jobs; n++){
|
||||
thpool_add_work(threadpool, (void*)add_one, NULL);
|
||||
}
|
||||
|
||||
thpool_wait(threadpool);
|
||||
|
||||
printf("%d\n", sum);
|
||||
|
||||
return 0;
|
||||
}
|
22
tests/src/no_work.c
Normal file
22
tests/src/no_work.c
Normal file
@ -0,0 +1,22 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../thpool.h"
|
||||
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
|
||||
char* p;
|
||||
if (argc != 2){
|
||||
puts("This testfile needs excactly one arguments");
|
||||
exit(1);
|
||||
}
|
||||
int threads = strtol(argv[1], &p, 10);
|
||||
|
||||
thpool_t* thpool;
|
||||
thpool = thpool_init(threads);
|
||||
thpool_destroy(thpool);
|
||||
|
||||
return 0;
|
||||
}
|
180
tests/threadpool
180
tests/threadpool
@ -1,182 +1,28 @@
|
||||
#! /bin/bash
|
||||
|
||||
#
|
||||
# This file has several tests to check for memory leaks.
|
||||
# valgrind is used so make sure you have it installed
|
||||
# This file has several functional tests similar to what a user
|
||||
# might use in his/her code
|
||||
#
|
||||
|
||||
. funcs
|
||||
|
||||
|
||||
# --------------------------- Generic ----------------------------------
|
||||
|
||||
function needle { #needle #haystack
|
||||
python -c "import re; print(re.search(r'$1', '$2').group(0))"
|
||||
}
|
||||
function extract_num { #needle with number #haystack
|
||||
string=$(needle "$1" "$2")
|
||||
needle "[0-9]*" "$string"
|
||||
}
|
||||
function err { #string #log
|
||||
echo "------------------- ERROR ------------------------"
|
||||
echo "$1"
|
||||
echo "$2" >> memleaks.log
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ---------------------------- Tests -----------------------------------
|
||||
|
||||
|
||||
function test_mass_addition {
|
||||
|
||||
read -d '' code <<"EOF"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include "../thpool.h"
|
||||
|
||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
int sum=0;
|
||||
|
||||
void add_one() {
|
||||
pthread_mutex_lock(&mutex);
|
||||
sum ++;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
int main(){
|
||||
|
||||
thpool_t* threadpool;
|
||||
threadpool = thpool_init(10);
|
||||
|
||||
int n;
|
||||
for (n=0; n<1000; n++){
|
||||
thpool_add_work(threadpool, (void*)add_one, NULL);
|
||||
}
|
||||
|
||||
thpool_wait(threadpool);
|
||||
|
||||
printf("%d", sum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "Adding up to 1000 with 10 threads"
|
||||
echo "$code" > _test_.c
|
||||
gcc _test_.c ../thpool.c -pthread -o test
|
||||
output=$(./test 2>&1 /dev/null)
|
||||
if [ "$output" == "1000" ]; then
|
||||
function test_mass_addition { #endsum #threads
|
||||
echo "Adding up to $1 with $2 threads"
|
||||
gcc src/conc_increment.c ../thpool.c -pthread -o test
|
||||
output=$(./test $1 $2)
|
||||
num=$(echo $output | awk '{print $(NF)}')
|
||||
if [ "$num" == "$1" ]; then
|
||||
return
|
||||
fi
|
||||
err "Expected 1000 but got $output" "$output"
|
||||
err "Expected $1 but got $output" "$output"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function test_mass_addition2 {
|
||||
|
||||
read -d '' code <<"EOF"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include "../thpool.h"
|
||||
|
||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
int sum=0;
|
||||
|
||||
void add_one() {
|
||||
pthread_mutex_lock(&mutex);
|
||||
sum ++;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
int main(){
|
||||
|
||||
thpool_t* threadpool;
|
||||
threadpool = thpool_init(1000);
|
||||
|
||||
int n;
|
||||
for (n=0; n<100; n++){
|
||||
thpool_add_work(threadpool, (void*)add_one, NULL);
|
||||
}
|
||||
|
||||
thpool_wait(threadpool);
|
||||
|
||||
printf("%d", sum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "Adding up to 100 with 1000 threads"
|
||||
echo "$code" > _test_.c
|
||||
gcc _test_.c ../thpool.c -pthread -o test
|
||||
output=$(./test 2>&1 /dev/null)
|
||||
if [ "$output" == "100" ]; then
|
||||
return
|
||||
fi
|
||||
err "Expected 100 but got $output" "$output"
|
||||
}
|
||||
|
||||
|
||||
|
||||
function test_mass_addition3 {
|
||||
|
||||
read -d '' code <<"EOF"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include "../thpool.h"
|
||||
|
||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
int sum=0;
|
||||
|
||||
void add_one() {
|
||||
pthread_mutex_lock(&mutex);
|
||||
sum ++;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
int main(){
|
||||
|
||||
thpool_t* threadpool;
|
||||
threadpool = thpool_init(1000);
|
||||
|
||||
int n;
|
||||
for (n=0; n<100000; n++){
|
||||
thpool_add_work(threadpool, (void*)add_one, NULL);
|
||||
}
|
||||
|
||||
thpool_wait(threadpool);
|
||||
|
||||
printf("%d", sum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "Adding up to 100000 with 1000 threads"
|
||||
echo "$code" > _test_.c
|
||||
gcc _test_.c ../thpool.c -pthread -o test
|
||||
output=$(./test 2>&1 /dev/null)
|
||||
if [ "$output" == "100000" ]; then
|
||||
return
|
||||
fi
|
||||
err "Expected 100000 but got $output" "$output"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Run tests
|
||||
test_mass_addition
|
||||
test_mass_addition2
|
||||
test_mass_addition3
|
||||
test_mass_addition 100 4
|
||||
test_mass_addition 100 1000
|
||||
test_mass_addition 100000 1000
|
||||
|
||||
echo "No errors"
|
||||
|
11
thpool.c
11
thpool.c
@ -1,14 +1,15 @@
|
||||
/* ********************************
|
||||
* Author: Johan Hanssen Seferidis
|
||||
* Date: 12/08/2011
|
||||
* License: MIT
|
||||
* Author: Johan Hanssen Seferidis
|
||||
* License: MIT
|
||||
* Description: Library providing a threading pool where you can add
|
||||
* work. For an example on usage refer to the main file
|
||||
* found in the same package
|
||||
* work. For an example on usage refer to the main file
|
||||
* found in the same package
|
||||
*
|
||||
*//** @file thpool.h *//*
|
||||
*
|
||||
********************************/
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
Loading…
Reference in New Issue
Block a user