source: trunk/libtransmission/utils-test.c @ 12204

Last change on this file since 12204 was 12204, checked in by jordan, 11 years ago

(trunk) #4138 "use stdbool.h instead of tr_bool" -- done.

File size: 13.0 KB
Line 
1#include <math.h>
2#include <stdio.h> /* fprintf */
3#include <string.h> /* strcmp */
4
5#include "transmission.h"
6#include "bitfield.h"
7#include "ConvertUTF.h" /* tr_utf8_validate*/
8#include "platform.h"
9#include "crypto.h"
10#include "utils.h"
11#include "web.h"
12
13/* #define VERBOSE */
14#undef VERBOSE
15#define NUM_LOOPS 1
16#define SPEED_TEST 0
17
18#if SPEED_TEST
19 #define VERBOSE
20 #undef NUM_LOOPS
21 #define NUM_LOOPS 200
22#endif
23
24static int test = 0;
25
26#ifdef VERBOSE
27  #define check( A ) \
28    { \
29        ++test; \
30        if( A ){ \
31            fprintf( stderr, "PASS test #%d (%s, %d)\n", test, __FILE__, __LINE__ ); \
32        } else { \
33            fprintf( stderr, "FAIL test #%d (%s, %d)\n", test, __FILE__, __LINE__ ); \
34            return test; \
35        } \
36    }
37#else
38  #define check( A ) \
39    { \
40        ++test; \
41        if( !( A ) ){ \
42            fprintf( stderr, "FAIL test #%d (%s, %d)\n", test, __FILE__, __LINE__ ); \
43            return test; \
44        } \
45    }
46#endif
47
48static int
49test_bitfield_count_range( void )
50{
51    int i;
52    int n;
53    int begin;
54    int end;
55    int count1;
56    int count2;
57    const int bitCount = 100 + tr_cryptoWeakRandInt( 1000 );
58    tr_bitfield * bf;
59
60    /* generate a random bitfield */
61    bf = tr_bitfieldNew( bitCount );
62    for( i=0, n=tr_cryptoWeakRandInt(bitCount); i<n; ++i )
63        tr_bitfieldAdd( bf, tr_cryptoWeakRandInt(bitCount) );
64
65    begin = tr_cryptoWeakRandInt( bitCount );
66    do {
67        end = tr_cryptoWeakRandInt( bitCount );
68    } while( end == begin );
69    if( end < begin ) {
70        const int tmp = begin;
71        begin = end;
72        end = tmp;
73    }
74
75    count1 = 0;
76    for( i=begin; i<end; ++i )
77        if( tr_bitfieldHas( bf, i ) )
78            ++count1;
79    count2 = tr_bitfieldCountRange( bf, begin, end );
80    check( count1 == count2 );
81
82    tr_bitfieldFree( bf );
83    return 0;
84}
85
86static int
87test_bitfields( void )
88{
89    unsigned int  i;
90    unsigned int  bitcount = 5000000;
91    tr_bitfield * field = tr_bitfieldNew( bitcount );
92
93    /* test tr_bitfieldAdd */
94    for( i = 0; i < bitcount; ++i )
95        if( !( i % 7 ) )
96            tr_bitfieldAdd( field, i );
97    for( i = 0; i < bitcount; ++i )
98        check( tr_bitfieldHas( field, i ) == ( !( i % 7 ) ) );
99
100    /* test tr_bitfieldAddRange */
101    tr_bitfieldAddRange( field, 0, bitcount );
102    for( i = 0; i < bitcount; ++i )
103        check( tr_bitfieldHas( field, i ) );
104
105    /* test tr_bitfieldRemRange in the middle of a boundary */
106    tr_bitfieldRemRange( field, 4, 21 );
107    for( i = 0; i < 64; ++i )
108        check( tr_bitfieldHas( field, i ) == ( ( i < 4 ) || ( i >= 21 ) ) );
109
110    /* test tr_bitfieldRemRange on the boundaries */
111    tr_bitfieldAddRange( field, 0, 64 );
112    tr_bitfieldRemRange( field, 8, 24 );
113    for( i = 0; i < 64; ++i )
114        check( tr_bitfieldHas( field, i ) == ( ( i < 8 ) || ( i >= 24 ) ) );
115
116    /* test tr_bitfieldRemRange when begin & end is on the same word */
117    tr_bitfieldAddRange( field, 0, 64 );
118    tr_bitfieldRemRange( field, 4, 5 );
119    for( i = 0; i < 64; ++i )
120        check( tr_bitfieldHas( field, i ) == ( ( i < 4 ) || ( i >= 5 ) ) );
121
122    /* test tr_bitfieldAddRange */
123    tr_bitfieldRemRange( field, 0, 64 );
124    tr_bitfieldAddRange( field, 4, 21 );
125    for( i = 0; i < 64; ++i )
126        check( tr_bitfieldHas( field, i ) == ( ( 4 <= i ) && ( i < 21 ) ) );
127
128    /* test tr_bitfieldAddRange on the boundaries */
129    tr_bitfieldRemRange( field, 0, 64 );
130    tr_bitfieldAddRange( field, 8, 24 );
131    for( i = 0; i < 64; ++i )
132        check( tr_bitfieldHas( field, i ) == ( ( 8 <= i ) && ( i < 24 ) ) );
133
134    /* test tr_bitfieldAddRange when begin & end is on the same word */
135    tr_bitfieldRemRange( field, 0, 64 );
136    tr_bitfieldAddRange( field, 4, 5 );
137    for( i = 0; i < 64; ++i )
138        check( tr_bitfieldHas( field, i ) == ( ( 4 <= i ) && ( i < 5 ) ) );
139
140    tr_bitfieldFree( field );
141    return 0;
142}
143
144static int
145test_strip_positional_args( void )
146{
147    const char * in;
148    const char * out;
149    const char * expected;
150
151    in = "Hello %1$s foo %2$.*f";
152    expected = "Hello %s foo %.*f";
153    out = tr_strip_positional_args( in );
154    check( out != NULL )
155    check( !strcmp( out, expected ) )
156
157    in = "Hello %1$'d foo %2$'f";
158    expected = "Hello %d foo %f";
159    out = tr_strip_positional_args( in );
160    check( out != NULL )
161    check( !strcmp( out, expected ) )
162
163    return 0;
164}
165
166static int
167test_strstrip( void )
168{
169    char *in, *out;
170
171    /* strstrip */
172    in = tr_strdup( "   test    " );
173    out = tr_strstrip( in );
174    check( in == out );
175    check( !strcmp( in, "test" ) );
176    tr_free( in );
177
178    /* strstrip */
179    in = tr_strdup( " test test " );
180    out = tr_strstrip( in );
181    check( in == out );
182    check( !strcmp( in, "test test" ) );
183    tr_free( in );
184
185    /* strstrip */
186    in = tr_strdup( "test" );
187    out = tr_strstrip( in );
188    check( in == out );
189    check( !strcmp( in, "test" ) );
190    tr_free( in );
191
192    return 0;
193}
194
195static int
196test_buildpath( void )
197{
198    char * out;
199
200    out = tr_buildPath( "foo", "bar", NULL );
201    check( !strcmp( out, "foo" TR_PATH_DELIMITER_STR "bar" ) );
202    tr_free( out );
203
204    out = tr_buildPath( "", "foo", "bar", NULL );
205    check( !strcmp( out, TR_PATH_DELIMITER_STR "foo" TR_PATH_DELIMITER_STR "bar" ) );
206    tr_free( out );
207
208    return 0;
209}
210
211static int
212test_utf8( void )
213{
214    const char * in;
215    char * out;
216
217    in = "hello world";
218    out = tr_utf8clean( in, -1 );
219    check( out != NULL )
220    check( !strcmp( out, in ) )
221    tr_free( out );
222
223    in = "hello world";
224    out = tr_utf8clean( in, 5 );
225    check( out != NULL )
226    check( !strcmp( out, "hello" ) )
227    tr_free( out );
228
229    /* this version is not utf-8 */
230    in = "Òðóäíî áûòü Áîãîì";
231    out = tr_utf8clean( in, 17 );
232    check( out != NULL )
233    check( ( strlen( out ) == 17 ) || ( strlen( out ) == 32 ) )
234    check( tr_utf8_validate( out, -1, NULL ) )
235    tr_free( out );
236
237    /* same string, but utf-8 clean */
238    in = "ÒðóÀíî áûòÌ Áîãîì";
239    out = tr_utf8clean( in, -1 );
240    check( out != NULL )
241    check( tr_utf8_validate( out, -1, NULL ) )
242    check ( !strcmp( in, out ) )
243    tr_free( out );
244
245    return 0;
246}
247
248static int
249test_numbers( void )
250{
251    int i;
252    int count;
253    int * numbers;
254
255    numbers = tr_parseNumberRange( "1-10,13,16-19", -1, &count );
256    check( count == 15 );
257    check( numbers != NULL );
258    check( numbers[0] == 1 );
259    check( numbers[5] == 6 );
260    check( numbers[9] == 10 );
261    check( numbers[10] == 13 );
262    check( numbers[11] == 16 );
263    check( numbers[14] == 19 );
264    tr_free( numbers );
265
266    numbers = tr_parseNumberRange( "1-5,3-7,2-6", -1, &count );
267    check( count == 7 );
268    check( numbers != NULL );
269    for( i=0; i<count; ++i )
270        check( numbers[i] == i+1 );
271    tr_free( numbers );
272
273    numbers = tr_parseNumberRange( "1-Hello", -1, &count );
274    check( count == 0 );
275    check( numbers == NULL );
276
277    numbers = tr_parseNumberRange( "1-", -1, &count );
278    check( count == 0 );
279    check( numbers == NULL );
280
281    numbers = tr_parseNumberRange( "Hello", -1, &count );
282    check( count == 0 );
283    check( numbers == NULL );
284
285    return 0;
286}
287
288static int
289compareInts( const void * va, const void * vb )
290{
291    const int a = *(const int *)va;
292    const int b = *(const int*)vb;
293    return a - b;
294}
295
296static int
297test_lowerbound( void )
298{
299    int i;
300    const int A[] = { 1, 2, 3, 3, 3, 5, 8 };
301    const int expected_pos[] = { 0, 1, 2, 5, 5, 6, 6, 6, 7, 7 };
302    const int expected_exact[] = { true, true, true, false, true, false, false, true, false, false };
303    const int N = sizeof(A) / sizeof(A[0]);
304
305    for( i=1; i<=10; ++i )
306    {
307        bool exact;
308        const int pos = tr_lowerBound( &i, A, N, sizeof(int), compareInts, &exact );
309
310#if 0
311        fprintf( stderr, "searching for %d. ", i );
312        fprintf( stderr, "result: index = %d, ", pos );
313        if( pos != N )
314            fprintf( stderr, "A[%d] == %d\n", pos, A[pos] );
315        else
316            fprintf( stderr, "which is off the end.\n" );
317#endif
318        check( pos == expected_pos[i-1] )
319        check( exact == expected_exact[i-1] )
320    }
321
322    return 0;
323}
324
325static int
326test_memmem( void )
327{
328    char const haystack[12] = "abcabcabcabc";
329    char const needle[3] = "cab";
330
331    check( tr_memmem( haystack, sizeof haystack, haystack, sizeof haystack) == haystack )
332    check( tr_memmem( haystack, sizeof haystack, needle, sizeof needle) == haystack + 2 )
333    check( tr_memmem( needle, sizeof needle, haystack, sizeof haystack) == NULL )
334
335    return 0;
336}
337
338static int
339test_hex( void )
340{
341    char hex1[41];
342    char hex2[41];
343    uint8_t sha1[20];
344    /*uint8_t sha2[20];*/
345
346    memcpy( hex1, "fb5ef5507427b17e04b69cef31fa3379b456735a", 41 );
347    tr_hex_to_sha1( sha1, hex1 );
348    tr_sha1_to_hex( hex2, sha1 );
349    check( !strcmp( hex1, hex2 ) )
350
351    return 0;
352}
353
354static int
355test_array( void )
356{
357    int i;
358    int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
359    int n = sizeof( array ) / sizeof( array[0] );
360
361    tr_removeElementFromArray( array, 5u, sizeof( int ), n-- );
362    for( i=0; i<n; ++i )
363        check( array[i] == ( i<5 ? i : i+1 ) );
364
365    tr_removeElementFromArray( array, 0u, sizeof( int ), n-- );
366    for( i=0; i<n; ++i )
367        check( array[i] == ( i<4 ? i+1 : i+2 ) );
368
369    tr_removeElementFromArray( array, n-1, sizeof( int ), n ); n--;
370    for( i=0; i<n; ++i )
371        check( array[i] == ( i<4 ? i+1 : i+2 ) );
372
373    return 0;
374}
375
376static int
377test_url( void )
378{
379    int port;
380    char * scheme;
381    char * host;
382    char * path;
383    char * str;
384    const char * url;
385
386    url = "http://www.some-tracker.org/some/path";
387    check( !tr_urlParse( url, -1, &scheme, &host, &port, &path ) )
388    check( !strcmp( scheme, "http" ) )
389    check( !strcmp( host, "www.some-tracker.org" ) )
390    check( !strcmp( path, "/some/path" ) )
391    check( port == 80 )
392    tr_free( scheme );
393    tr_free( path );
394    tr_free( host );
395
396    url = "http://www.some-tracker.org:80/some/path";
397    check( !tr_urlParse( url, -1, &scheme, &host, &port, &path ) )
398    check( !strcmp( scheme, "http" ) )
399    check( !strcmp( host, "www.some-tracker.org" ) )
400    check( !strcmp( path, "/some/path" ) )
401    check( port == 80 )
402    tr_free( scheme );
403    tr_free( path );
404    tr_free( host );
405
406    url = "http%3A%2F%2Fwww.example.com%2F~user%2F%3Ftest%3D1%26test1%3D2";
407    str = tr_http_unescape( url, strlen( url ) );
408    check( !strcmp( str, "http://www.example.com/~user/?test=1&test1=2" ) )
409    tr_free( str );
410
411    return 0;
412}
413
414static int
415test_truncd( void )
416{
417    char buf[32];
418    const double nan = sqrt( -1 );
419
420    tr_snprintf( buf, sizeof( buf ), "%.2f%%", 99.999 );
421    check( !strcmp( buf, "100.00%" ) );
422
423    tr_snprintf( buf, sizeof( buf ), "%.2f%%", tr_truncd( 99.999, 2 ) );
424    check( !strcmp( buf, "99.99%" ) );
425
426    tr_snprintf( buf, sizeof( buf ), "%.4f", tr_truncd( 403650.656250, 4 ) );
427    check( !strcmp( buf, "403650.6562" ) );
428
429    tr_snprintf( buf, sizeof( buf ), "%.2f", tr_truncd( 2.15, 2 ) );
430    check( !strcmp( buf, "2.15" ) );
431
432    tr_snprintf( buf, sizeof( buf ), "%.2f", tr_truncd( 2.05, 2 ) );
433    check( !strcmp( buf, "2.05" ) );
434
435    tr_snprintf( buf, sizeof( buf ), "%.2f", tr_truncd( 3.3333, 2 ) );
436    check( !strcmp( buf, "3.33" ) );
437
438    tr_snprintf( buf, sizeof( buf ), "%.0f", tr_truncd( 3.3333, 0 ) );
439    check( !strcmp( buf, "3" ) );
440
441    tr_snprintf( buf, sizeof( buf ), "%.2f", tr_truncd( nan, 2 ) );
442    check( strstr( buf, "nan" ) != NULL );
443
444    return 0;
445}
446
447struct blah
448{
449    uint8_t  hash[SHA_DIGEST_LENGTH];  /* pieces hash */
450    int8_t   priority;                 /* TR_PRI_HIGH, _NORMAL, or _LOW */
451    int8_t   dnd;                      /* "do not download" flag */
452    time_t   timeChecked;              /* the last time we tested this piece */
453};
454
455
456int
457main( void )
458{
459    char *in, *out;
460    int   len;
461    int   i;
462    int   l;
463
464    /* base64 */
465    out = tr_base64_encode( "YOYO!", -1, &len );
466    check( out );
467    check( !strcmp( out, "WU9ZTyE=" ) );
468    check( len == 8 );
469    in = tr_base64_decode( out, -1, &len );
470    check( in );
471    check( !strcmp( in, "YOYO!" ) );
472    check( len == 5 );
473    tr_free( in );
474    tr_free( out );
475    out = tr_base64_encode( NULL, 0, &len );
476    check( out == NULL );
477    check( len == 0 );
478
479    if( ( i = test_hex( ) ) )
480        return i;
481    if( ( i = test_lowerbound( ) ) )
482        return i;
483    if( ( i = test_strip_positional_args( ) ) )
484        return i;
485    if( ( i = test_strstrip( ) ) )
486        return i;
487    if( ( i = test_buildpath( ) ) )
488        return i;
489    if( ( i = test_utf8( ) ) )
490        return i;
491    if( ( i = test_numbers( ) ) )
492        return i;
493    if( ( i = test_memmem( ) ) )
494        return i;
495    if( ( i = test_array( ) ) )
496        return i;
497    if( ( i = test_url( ) ) )
498        return i;
499    if( ( i = test_truncd( ) ) )
500        return i;
501
502    /* test that tr_cryptoRandInt() stays in-bounds */
503    for( i = 0; i < 100000; ++i )
504    {
505        const int val = tr_cryptoRandInt( 100 );
506        check( val >= 0 );
507        check( val < 100 );
508    }
509
510    /* simple bitfield tests */
511    for( l = 0; l < NUM_LOOPS; ++l )
512        if( ( i = test_bitfields( ) ) )
513            return i;
514
515    /* bitfield count range */
516    for( l=0; l<1000000; ++l )
517        if(( i = test_bitfield_count_range( )))
518            return i;
519
520    return 0;
521}
522
Note: See TracBrowser for help on using the repository browser.