1/* @(#) unit test of udpxy data-stream cache */ 2 3#include <sys/types.h> 4#include <stdio.h> 5#include <assert.h> 6#include <stdlib.h> 7 8#include "util.h" 9#include "cache.h" 10#include "dpkt.h" 11#include "udpxy.h" 12 13extern FILE* g_flog; 14 15extern const char CMD_UDP[]; 16 17#define BUFSZ (64 * 1024) 18#define NUM_MSGS (BUFSZ / ETHERNET_MTU) 19#define CACHE_MAXSZ (BUFSZ * 10) 20 21static struct dscache* cache = NULL; 22static struct dstream_ctx spc; 23 24 25static int 26test_init() 27{ 28 int rc = 0; 29 30 (void) fprintf( g_flog, "\n%s: TEST STARTED\n", __func__ ); 31 32 rc = init_dstream_ctx( &spc, CMD_UDP, NULL, NUM_MSGS ); 33 if( 0 != rc ) 34 return -1; 35 36 cache = dscache_init( CACHE_MAXSZ, &spc, BUFSZ, 3 ); 37 if( NULL == cache ) 38 return -1; 39 40 dscache_free( cache ); 41 free_dstream_ctx( &spc ); 42 43 (void) fprintf( g_flog, "\n%s: TEST FINISHED\n", __func__ ); 44 return 0; 45} 46 47 48static void 49dump_chunk( FILE* out, const struct chunk* chnk, 50 const char* tag ) 51{ 52 assert( out && chnk ); 53 54 (void) fprintf( out, "%s(%p)=[l:%ld,u:%ld,n:%p]\n", 55 (tag ? tag : "chunk"), (const void*)chnk, 56 (long)chnk->length, 57 (long)chnk->used_length, (const void*)chnk->next ); 58} 59 60 61 62static int 63test_read_into() 64{ 65 int rc = 0, numiter = 10; 66 ssize_t i; 67 struct chunk *rchnk = NULL, *wchnk = NULL; 68 69 (void) fprintf( g_flog, "\n%s: TEST STARTED\n", __func__ ); 70 71 rc = init_dstream_ctx( &spc, CMD_UDP, NULL, NUM_MSGS ); 72 if( 0 != rc ) 73 return -1; 74 75 cache = dscache_init( CACHE_MAXSZ, &spc, BUFSZ, 3 ); 76 if( NULL == cache ) 77 return -1; 78 79 do { 80 (void) fprintf( g_flog, "%d: -------- BEGIN\n", 81 numiter ); 82 83 rchnk = dscache_rget( cache, &rc ); 84 if( !rchnk ) break; 85 86 dump_chunk( g_flog, rchnk, "R" ); 87 88 for( i = 0; i < (rchnk->length - 64); ++i ) 89 rchnk->data[i] = 'U'; 90 91 (void) fprintf( g_flog, "%d: data updated [%ld]\n", 92 numiter, (long)i ); 93 94 rc = dscache_rset( cache, i ); 95 if( 0 != rc ) break; 96 97 wchnk = dscache_wget( cache, &rc ); 98 if( !wchnk ) break; 99 100 (void) fprintf( g_flog, "%d: grabbed W-chunk(%p)\n", 101 numiter, (const void*)wchnk ); 102 dump_chunk( g_flog, wchnk, "W" ); 103 104 for( i = 0; (i < wchnk->used_length) && !rc; ++i ) { 105 if( 'U' != wchnk->data[i] ) 106 rc = 1; 107 } 108 109 (void) fprintf( g_flog, "%d: W-chunk(%p) read\n", 110 numiter, (const void*)wchnk ); 111 112 (void) fprintf( g_flog, "%d: -------- END\n", numiter ); 113 } while( --numiter > 0 ); 114 115 if( rc ) { 116 (void) fprintf( g_flog, "Error = [%d]\n", rc ); 117 } 118 119 dscache_free( cache ); 120 free_dstream_ctx( &spc ); 121 122 (void) fprintf( g_flog, "\n%s: TEST FINISHED\n", __func__ ); 123 return rc; 124} 125 126 127int 128main( int argc, char* const argv[] ) 129{ 130 int rc = 0, tlevel = 0; 131 const char* trace_str = getenv( "UDPXY_TRACE_CACHE" ); 132 133 134 (void)(&argc && &argv); 135 136 g_flog = stderr; 137 if( trace_str ) { 138 tlevel = atoi( trace_str ); 139 if( !tlevel && '0' != trace_str[0] ) { 140 (void) fprintf( g_flog, "Error specifying trace level [%s]\n", 141 trace_str ); 142 return 1; 143 } 144 145 set_cache_trace( tlevel ); 146 } 147 148 do { 149 if( 0 != (rc = test_init()) ) 150 break; 151 if( 0 != (rc = test_read_into()) ) 152 break; 153 154 } while(0); 155 156 return rc; 157} 158 159 160/* __EOF__ */ 161 162