X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=test%2Fsymtab_test.c;h=9beae8d58e320ebf3d2303786a66cc8e41563a3b;hb=refs%2Fchanges%2F25%2F5925%2F2;hp=1742e0157a6cca9ea173a1a60a56bae29163c058;hpb=77526eb4f4ef7b2be5fda0c8d719d3c46c75c5c7;p=ric-plt%2Flib%2Frmr.git diff --git a/test/symtab_test.c b/test/symtab_test.c index 1742e01..9beae8d 100644 --- a/test/symtab_test.c +++ b/test/symtab_test.c @@ -1,7 +1,7 @@ /* ================================================================================== - Copyright (c) 2019 Nokia - Copyright (c) 2018-2019 AT&T Intellectual Property. + Copyright (c) 2019-2021 Nokia + Copyright (c) 2018-2021 AT&T Intellectual Property. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -24,9 +24,11 @@ the symbol table portion of RMr. Run with: ksh unit_test.ksh symtab_test.c Date: 1 April 2019 - Author: E. Scott Daniels + Author: E. Scott Daniels */ +#include + #define NO_DUMMY_RMR 1 // no dummy rmr functions; we don't pull in rmr.h or agnostic.h #define NO_EMULATION #define NO_PRIVATE_HEADERS @@ -39,6 +41,7 @@ #include "symtab.c" // module under test +int terrors = 0; // thread errors int state = GOOD; // overall pass/fail state 0==fail int counter; // global counter for for-each tests @@ -89,6 +92,99 @@ static int nfetch( void* st, int key, int expected ) { return error; } +// ----------------- thread based tests ------------------------------------------------------------------- +#define NUM_KEYS 512 // number of unique keys +#define NUM_ATTEMPTS 1000000 + +/* + This is started in a thread and will attempt 10,000 reads on the symtable + in an attempt to ensure that there are no concurrent read/write issues. +*/ +static void* reader( void* st ) { + char key[1024]; + int i; + int ncount = 0; // number not found + int fcount = 0; // number found + + for( i = 0; i < NUM_ATTEMPTS; i++ ) { + snprintf( key, sizeof( key ), "key_%d", i % NUM_KEYS ); + if( rmr_sym_get( st, key, 1 ) == NULL ) { + ncount++; + } else { + fcount++; + } + } + + fprintf( stderr, " reader finished: n=%d f=%d\n", ncount, fcount ); // there is no right answer + return NULL; +} + +/* + This is started in a thread and will attempt 10,000 writes on the symtable + in an attempt to ensure that there are no concurrent read/write issues. Keys are + written as key_n where n is an integer between 0 and 999 inclusive. +*/ +static void* writer( void* st ) { + char key[1024]; + int i; + int ncount = 0; // number first inserts + int rcount = 0; // number replacements + char* value = NULL; + int num_keys = 256; + + fprintf( stderr, " writer now turning\n" ); + for( i = 0; i < NUM_ATTEMPTS; i++ ) { + value++; + snprintf( key, sizeof( key ), "key_%d", i % NUM_KEYS ); + rmr_sym_del( st, key, 1 ); + if( rmr_sym_put( st, key, 1, value ) ) { + ncount++; + } else { + rcount++; + } + } + + if( ncount != NUM_ATTEMPTS ) { + fprintf( stderr, " writer finished: n=%d r=%d\n", ncount, rcount ); // there is no right answer + terrors++; + } else { + fprintf( stderr, " writer finished: n=%d r=%d\n", ncount, rcount ); // there is no right answer + } + + return NULL; +} + +/* + Drive a concurrent read/write test to ensure no race issues. +*/ +static int thread_test( ) { + pthread_t tids[10]; + int n2start = 3; + int i; + void* st; + + st = rmr_sym_alloc( 128 ); // should force collisions + + fprintf( stderr, " starting writer\n" ); + pthread_create( &tids[0], NULL, writer, st ); + + for( i = 1; i <= n2start; i++ ) { + fprintf( stderr, " starting reader %d\n", i ); + pthread_create( &tids[i], NULL, reader, st ); + } + + fprintf( stderr, " thread controller is waiting\n" ); + for( i = 0; i <= n2start; i++ ) { + pthread_join( tids[i], NULL ); // status is unimportant, just hold until all are done + fprintf( stderr, " thread %d has reported complete\n", i ); + } + + + rmr_sym_stats( st, 1 ); + return terrors; +} + +// --------------------------------------------------------------------------------------------------------- /* Driven by foreach class -- just incr the counter. @@ -151,6 +247,8 @@ int main( ) { rmr_sym_free( NULL ); // ensure it doesn't barf when given a nil pointer rmr_sym_free( st ); + errors += thread_test(); // test as best we can for race issues + test_summary( errors, "symtab tests" ); if( state + errors == 0 ) { fprintf( stderr, " all symtab tests were OK\n\n" ); @@ -158,6 +256,7 @@ int main( ) { fprintf( stderr, " %d errors in symtab code\n\n", errors ); } + return !!(state + errors); }