fast_test.c

FIX Adapted for STreaming API unit test harness

00001 // $Id: fast__test_8c-example.html,v 1.2 2006/02/09 19:12:40 Daniel.May Exp $
00002 // The fast_test utility is a unit testing facility to assist in verifying a fast implementation on different
00003 // target platforms.  It performs a variety of tests on the core fastapi functions.
00004 //
00005 // Copyright (c), Pantor Engineering AB, 2005
00006 // All rights reserved.
00007 
00013 #include <signal.h>
00014 #include <setjmp.h>
00015 
00016 #include "fastapi.h"
00017 
00018 static fast_codec_t* decoder = NULL;
00019 static fast_codec_t* encoder = NULL;
00020 
00021 static int curr_id   = 0;
00022 static int curr_mode = 0;
00023 static int curr_code = 0;
00024 
00025 static const char* curr_text = NULL;
00026 
00027 static int execed_count = 0;
00028 static int failed_count = 0;
00029 static int passed_count = 0;
00030 
00031 #define MAKE_I32_TAG(o,t,s) MAKE_TAG (FAST_TYPE_I32, o, t, s)
00032 #define MAKE_STR_TAG(o,t,s) MAKE_TAG (FAST_TYPE_STR, o, t, s)
00033 #define MAKE_U32_TAG(o,t,s) MAKE_TAG (FAST_TYPE_U32, o, t, s)
00034 
00036 
00037 static void cleanup (void)
00038 {
00039    if (decoder != NULL && decoder->magic == FAST_CODEC_MAGIC)
00040    {
00041       fast_destroy_codec (decoder);
00042       decoder = NULL;
00043    }
00044 
00045    if (encoder != NULL && encoder->magic == FAST_CODEC_MAGIC)
00046    {
00047       fast_destroy_codec (encoder);
00048       encoder = NULL;
00049    }
00050 }
00051 
00052 static void started (void)
00053 {
00054    fprintf (stderr, "%04d [started] '%s'\n", curr_id, curr_text);
00055 
00056    execed_count ++;
00057 }
00058 
00059 static int failed (void)
00060 {
00061    fprintf (stderr, "%04d [failed]\n\n", curr_id);
00062    cleanup ();
00063 
00064    failed_count ++;
00065    return 0;
00066 }
00067 
00068 static int passed (void)
00069 {
00070    fprintf (stderr, "%04d [passed]\n\n", curr_id);
00071    cleanup ();
00072 
00073    passed_count ++;
00074    return 0;
00075 }
00076 
00077 #define FAIL 0
00078 #define PASS 1
00079 
00080 typedef int (*test_fn) (void);
00081 
00082 static void execute (int id, int mode, test_fn fn, const char* text)
00083 {
00084    curr_id   = id;
00085    curr_text = text;
00086    curr_mode = mode;
00087    curr_code = 0;
00088 
00089    started ();
00090    (void) (fn () == 0 ? passed () : failed ());
00091 }
00092 
00093 static int expect (fast_codec_t* codec, fast_error_t error_code, int code)
00094 {
00095    if (codec == NULL || codec->magic != FAST_CODEC_MAGIC)
00096    {
00097       if (code == 0)
00098       {
00099          fprintf (stderr, "     unexpected: NULL codec undetected\n");
00100          return -1;
00101       }
00102       else if (error_code == FAST_ERR_CODEC)
00103       {
00104          fprintf (stderr, "     expected: NULL codec\n");
00105          return 0;
00106       }
00107       else
00108       {
00109          fprintf (stderr, "     unexpected: NULL codec\n");
00110          return -1;
00111       }
00112    }
00113 
00114    if (error_code != FAST_ERR_NONE)
00115    {
00116       if (code == 0)
00117       {
00118          fprintf (stderr, "     unexpected success\n");
00119          return -1;
00120       }
00121       else
00122       {
00123          const char* text = fast_error_string (codec);
00124 
00125          if (codec->error->code == error_code)
00126          {
00127             fprintf (stderr, "     expected: %s\n", text);
00128             return 0;
00129          }
00130          else
00131          {
00132             fprintf (stderr, "     unexpected: %s\n", text);
00133             return -1;
00134          }
00135       }
00136    }
00137    else if (code < 0)
00138    {
00139       fprintf (stderr, "     unexpected: %s\n",
00140                fast_error_string (codec));
00141       return -1;
00142    }
00143    return 0;
00144 }
00145 
00147 
00148 #if 0
00149 static void test_0001 (void) // Destroy without create
00150 {
00151    //_expect (encoder, FAST_ERR_CODEC, fast_destroy_codec (encoder));
00152 }
00153 
00154 static void test_0002 (void) // Call fast_destroy_codec twice
00155 {
00156    encoder = fast_create_codec ();
00157 
00158    fast_destroy_codec (encoder);
00159    fast_destroy_codec (encoder);
00160 }
00161 #endif
00162 
00164 
00165 static void insert_into_buffer (fast_buffer_t* buffer, u8* data, int size)
00166 {
00167    assert (size <= buffer->end - buffer->tail);
00168 
00169    memcpy (buffer->head, data, size);
00170    buffer->tail += size;
00171 }
00172 
00173 static void copy_buffer (fast_buffer_t* source, fast_buffer_t* target)
00174 {
00175    int size = source->tail - source->head;
00176 
00177    assert (size <= target->end - target->tail);
00178 
00179    memcpy (target->tail, source->head, size);
00180    target->tail += size;
00181 }
00182 
00183 static void dump_buffer (fast_buffer_t* b, const char* msg)
00184 {
00185    fprintf (stderr, "     '%s' head=%d tail=%d used=%d\n",
00186             msg, b->head - b->data, b->tail - b->data,
00187             b->tail - b->head);
00188 }
00189 
00191 
00192 static int encode_decode_i32_none (void)
00193 {
00194    static i32 data [12] =
00195    {
00196       -65, -64, -3, -2, -1, 0, 1, 2, 3, 62, 63, 64
00197    };
00198 
00199    fast_tag_t tag = MAKE_I32_TAG (FAST_OP_NONE, 0, 0);
00200 
00201    i32 temp [12];
00202 
00203    int count = 12;
00204    int code;
00205    int p1;
00206 
00207    encoder = fast_create_codec ();
00208    decoder = fast_create_codec ();
00209 
00210    encoder->skip_io = 1;
00211    decoder->skip_io = 1;
00212 
00213    // Start encoding a message
00214    if (expect (encoder, FAST_ERR_NONE,
00215                fast_encode_new_msg (encoder, tag)) < 0)
00216       return -1;
00217 
00218    for (p1 = 0 ; p1 < count ; p1 ++)
00219    {
00220       code = fast_encode_i32 (encoder, tag, data [p1]);
00221       if (code < 0) break;
00222    }
00223 
00224    if (p1 < count)
00225       return expect (encoder, FAST_ERR_NONE, -1);
00226 
00227    // Message encoding done
00228    if (expect (encoder, FAST_ERR_NONE,
00229                fast_encode_end_msg (encoder, tag)) < 0)
00230       return -1;
00231 
00232    // Copy encoder output to decoder input
00233    copy_buffer (encoder->output, decoder->input);
00234 
00235    // Start decoding a message
00236    if (expect (decoder, FAST_ERR_NONE,
00237                fast_decode_new_msg (decoder, tag)) < 0)
00238       return -1;
00239 
00240    for (p1 = 0 ; p1 < count ; p1 ++)
00241    {
00242       code = fast_decode_i32 (decoder, tag, & temp [p1]);
00243       if (code < 0) break;
00244    }
00245 
00246    if (p1 < count)
00247       return expect (decoder, FAST_ERR_NONE, -1);
00248 
00249    // Message decoding done
00250    if (expect (decoder, FAST_ERR_NONE,
00251                fast_decode_end_msg (decoder, tag)) < 0)
00252       return -1;
00253 
00254    {
00255       int errors = 0;
00256 
00257       for (p1 = 0 ; p1 < count ; p1 ++)
00258       {
00259          if (data [p1] != temp [p1])
00260          {
00261             fprintf (stderr, "     unexpected: data=%d != temp=%d\n",
00262                      data [p1], temp [p1]);
00263 
00264             errors ++;
00265          }
00266       }
00267 
00268       if (errors > 0)
00269          return -1;
00270    }
00271 
00272    return 0;
00273 }
00274 
00275 static int encode_decode_u32_none (void)
00276 {
00277    static u32 data [12] =
00278    {
00279       0, 1, 2, 3, 62, 63, 64, 127, 128, 16383, 16384, 16385
00280    };
00281 
00282    fast_tag_t tag = MAKE_U32_TAG (FAST_OP_NONE, 0, 0);
00283 
00284    u32 temp [12];
00285 
00286    int count = 12;
00287    int code;
00288    int p1;
00289 
00290    encoder = fast_create_codec ();
00291    decoder = fast_create_codec ();
00292 
00293    encoder->skip_io = 1;
00294    decoder->skip_io = 1;
00295 
00296    // Start encoding a message
00297    if (expect (encoder, FAST_ERR_NONE,
00298                fast_encode_new_msg (encoder, tag)) < 0)
00299       return -1;
00300 
00301    for (p1 = 0 ; p1 < count ; p1 ++)
00302    {
00303       code = fast_encode_u32 (encoder, tag, data [p1]);
00304       if (code < 0) break;
00305    }
00306 
00307    if (p1 < count)
00308       return expect (encoder, FAST_ERR_NONE, -1);
00309 
00310    // Message encoding done
00311    if (expect (encoder, FAST_ERR_NONE,
00312                fast_encode_end_msg (encoder, tag)) < 0)
00313       return -1;
00314 
00315    // Copy encoder output to decoder input
00316    copy_buffer (encoder->output, decoder->input);
00317 
00318    // Start decoding a message
00319    if (expect (decoder, FAST_ERR_NONE,
00320                fast_decode_new_msg (decoder, tag)) < 0)
00321       return -1;
00322 
00323    for (p1 = 0 ; p1 < count ; p1 ++)
00324    {
00325       code = fast_decode_u32 (decoder, tag, & temp [p1]);
00326       if (code < 0) break;
00327    }
00328 
00329    if (p1 < count)
00330       return expect (decoder, FAST_ERR_NONE, -1);
00331 
00332    // Message decoding done
00333    if (expect (decoder, FAST_ERR_NONE,
00334                fast_decode_end_msg (decoder, tag)) < 0)
00335       return -1;
00336 
00337    {
00338       int errors = 0;
00339 
00340       for (p1 = 0 ; p1 < count ; p1 ++)
00341       {
00342          if (data [p1] != temp [p1])
00343          {
00344             fprintf (stderr, "     unexpected: data=%d != temp=%d\n",
00345                      data [p1], temp [p1]);
00346 
00347             errors ++;
00348          }
00349       }
00350 
00351       if (errors > 0)
00352          return -1;
00353    }
00354 
00355    return 0;
00356 }
00357 
00359 
00360 static int decode_i32_bad_size (void)
00361 {
00362    static u8 data [7] =
00363    {
00364       0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
00365    };
00366 
00367    fast_tag_t tag = MAKE_I32_TAG (FAST_OP_NONE, 0, 0);
00368    i32 temp;
00369 
00370    decoder = fast_create_codec ();
00371    decoder->skip_io = 1;
00372 
00373    insert_into_buffer (decoder->input, data, sizeof (data));
00374 
00375    fast_decode_new_msg (decoder, tag);
00376 
00377    if (expect (decoder, FAST_ERR_SIZE,
00378                fast_decode_i32 (decoder, tag, & temp)) < 0)
00379       return -1;
00380 
00381    return 0;
00382 }
00383 
00384 static int decode_i32_none_no_value (void)
00385 {
00386    static u8 data [1] = { 0x80 };
00387 
00388    fast_tag_t tag = MAKE_I32_TAG (FAST_OP_NONE, 0, 0);
00389    i32 temp;
00390 
00391    decoder = fast_create_codec ();
00392    decoder->skip_io = 1;
00393 
00394    insert_into_buffer (decoder->input, data, sizeof (data));
00395 
00396    if (expect (decoder, FAST_ERR_VALUE,
00397                fast_decode_i32 (decoder, tag, & temp)) < 0)
00398       return -1;
00399 
00400    return 0;
00401 }
00402 
00403 static int decode_i32_incr_no_value (void)
00404 {
00405    static u8 data [1] = { 0x80 };
00406 
00407    fast_tag_t tag = MAKE_I32_TAG (FAST_OP_INCR, 0, 0);
00408    i32 temp;
00409 
00410    decoder = fast_create_codec ();
00411    decoder->skip_io = 1;
00412 
00413    insert_into_buffer (decoder->input, data, sizeof (data));
00414 
00415    if (expect (decoder, FAST_ERR_VALUE,
00416                fast_decode_i32 (decoder, tag, & temp)) < 0)
00417       return -1;
00418 
00419    return 0;
00420 }
00421 
00423 
00424 static int encode_i32_bad_slot (void)
00425 {
00426    fast_tag_t tag = MAKE_TAG (FAST_TYPE_I32, FAST_OP_COPY, 0,
00427                               MAX_PMAP_BITS + 1);
00428 
00429    encoder = fast_create_codec ();
00430 
00431    if (expect (encoder, FAST_ERR_SIZE,
00432                fast_encode_i32 (encoder, tag, 0)) < 0)
00433       return -1;
00434 
00435    return 0;
00436 }
00437 
00438 static int encode_i32_delta_bad_op (void)
00439 {
00440    fast_tag_t tag = MAKE_I32_TAG (FAST_OP_DELTA, 0, 0);
00441 
00442    encoder = fast_create_codec ();
00443 
00444    if (expect (encoder, FAST_ERR_TAG_OP,
00445                fast_encode_i32 (encoder, tag, 3)) < 0)
00446       return -1;
00447 
00448    return 0;
00449 }
00450 
00451 static int encode_i32_incr_bad_op (void)
00452 {
00453    fast_tag_t tag = MAKE_I32_TAG (FAST_OP_INCR, 0, 0);
00454 
00455    encoder = fast_create_codec ();
00456 
00457    if (expect (encoder, FAST_ERR_TAG_OP,
00458                fast_encode_i32 (encoder, tag, 0)) < 0)
00459       return -1;
00460 
00461    return 0;
00462 }
00463 
00464 static int encode_i32_null_codec (void)
00465 {
00466    if (expect (encoder, FAST_ERR_CODEC,
00467                fast_encode_i32 (NULL, 0, 0)) < 0)
00468       return -1;
00469 
00470    return 0;
00471 }
00472 
00473 static int encode_i32_str_tag (void)
00474 {
00475    fast_tag_t tag = MAKE_TAG (FAST_TYPE_STR, FAST_OP_NONE, 0, 0);
00476 
00477    encoder = fast_create_codec ();
00478 
00479    if (expect (encoder, FAST_ERR_TAG_TYPE,
00480                fast_encode_i32 (encoder, tag, 0)) < 0)
00481       return -1;
00482 
00483    return 0;
00484 }
00485 
00486 static int encode_i32_u32_tag (void)
00487 {
00488    fast_tag_t tag = MAKE_TAG (FAST_TYPE_U32, FAST_OP_NONE, 0, 0);
00489 
00490    encoder = fast_create_codec ();
00491 
00492    if (expect (encoder, FAST_ERR_TAG_TYPE,
00493                fast_encode_i32 (encoder, tag, 0)) < 0)
00494       return -1;
00495 
00496    return 0;
00497 }
00498 
00500 
00501 static int encode_str_incr (void)
00502 {
00503    fast_tag_t tag = MAKE_STR_TAG (FAST_OP_INCR, 0, 0);
00504 
00505    encoder = fast_create_codec ();
00506 
00507    if (expect (encoder, FAST_ERR_TAG_OP,
00508                fast_encode_str (encoder, tag, (u8*) "foo", 3)) < 0)
00509       return -1;
00510 
00511    return 0;
00512 }
00513 
00514 #if 0 // not checked in fast_encode_str
00515 static int encode_str_oversized (void)
00516 {
00517    fast_tag_t tag = MAKE_STR_TAG (FAST_OP_NONE, 0, 0);
00518 
00519    encoder = fast_create_codec ();
00520 
00521    if (expect (encoder, FAST_ERR_SIZE,
00522                fast_encode_str (encoder, tag, (u8*) "", 1025)) < 0)
00523       return -1;
00524 
00525    return 0;
00526 }
00527 #endif
00528 
00529 static int encode_str_zero_length (void)
00530 {
00531    fast_tag_t tag = MAKE_STR_TAG (FAST_OP_NONE, 0, 0);
00532 
00533    encoder = fast_create_codec ();
00534 
00535    if (expect (encoder, FAST_ERR_SIZE,
00536                fast_encode_str (encoder, tag, (u8*) "", 0)) < 0)
00537       return -1;
00538 
00539    return 0;
00540 }
00541 
00543 
00544 static int encode_end_msg_only (void)
00545 {
00546    encoder = fast_create_codec ();
00547 
00548    if (expect (encoder, FAST_ERR_CALL_SEQ,
00549                fast_encode_end_msg (encoder, 0)) < 0)
00550       return -1;
00551 
00552    return 0;
00553 }
00554 
00555 static int encode_new_msg_twice (void)
00556 {
00557    encoder = fast_create_codec ();
00558 
00559    if (expect (encoder, FAST_ERR_NONE,
00560                fast_encode_new_msg (encoder, 0)) < 0)
00561       return -1;
00562 
00563    if (expect (encoder, FAST_ERR_CALL_SEQ,
00564                fast_encode_new_msg (encoder, 0)) < 0)
00565       return -1;
00566 
00567    return 0;
00568 }
00569 
00570 static int encode_msg_buffer_overflow (void)
00571 {
00572    fast_tag_t tag = MAKE_I32_TAG (FAST_OP_NONE, 0, 0);
00573 
00574    int code;
00575    int p1;
00576 
00577    encoder = fast_create_codec ();
00578 
00579    for (p1 = 0 ; p1 < 10000 ; p1 ++)
00580    {
00581       code = fast_encode_i32 (encoder, tag, p1);
00582 
00583       if (code < 0)
00584          break;
00585    }
00586 
00587    if (expect (encoder, FAST_ERR_SIZE, code) < 0)
00588       return -1;
00589 
00590    return 0;
00591 }
00592 
00593 static int encode_output_buffer_overflow (void)
00594 {
00595    fast_tag_t tag = MAKE_I32_TAG (FAST_OP_NONE, 0, 0);
00596 
00597    int code;
00598    int p1;
00599 
00600    encoder = fast_create_codec ();
00601 
00602    encoder->skip_io = 1;
00603 
00604    for (p1 = 0 ; p1 < 10000 ; p1 ++)
00605    {
00606       code = fast_encode_new_msg (encoder, tag);
00607 
00608       if (code < 0)
00609          break;
00610 
00611       code = fast_encode_i32 (encoder, tag, p1);
00612 
00613       if (code < 0)
00614          break;
00615 
00616       code = fast_encode_end_msg (encoder, tag);
00617 
00618       if (code < 0)
00619          break;
00620    }
00621 
00622    if (expect (encoder, FAST_ERR_SIZE, code) < 0)
00623       return -1;
00624 
00625    return 0;
00626 }
00627 
00629 
00630 #define ENTRY(result, name) { result, name, #name }
00631 
00632 typedef struct test_entry
00633 {
00634    int result;
00635    test_fn fn;
00636    const char* name;
00637 }
00638 test_entry;
00639 
00640 static test_entry test_array [] =
00641 {
00642    ENTRY (FAIL, decode_i32_bad_size),
00643    ENTRY (FAIL, decode_i32_none_no_value),
00644    ENTRY (FAIL, decode_i32_incr_no_value),
00645 
00646    ENTRY (FAIL, encode_i32_bad_slot),
00647    ENTRY (FAIL, encode_i32_delta_bad_op),
00648    ENTRY (FAIL, encode_i32_incr_bad_op),
00649    ENTRY (FAIL, encode_i32_null_codec),
00650    ENTRY (FAIL, encode_i32_str_tag),
00651    ENTRY (FAIL, encode_i32_u32_tag),
00652 
00653    ENTRY (FAIL, encode_str_incr),
00654    //_ENTRY (FAIL, encode_str_oversized),
00655    ENTRY (FAIL, encode_str_zero_length),
00656 
00657    ENTRY (FAIL, encode_end_msg_only),
00658    ENTRY (FAIL, encode_new_msg_twice),
00659    ENTRY (FAIL, encode_msg_buffer_overflow),
00660    ENTRY (FAIL, encode_output_buffer_overflow),
00661 
00662    ENTRY (PASS, encode_decode_i32_none),
00663    ENTRY (PASS, encode_decode_u32_none),
00664 
00665    { 0, NULL },
00666 };
00667 
00668 int main (int argc, char* argv [])
00669 {
00670    int p1;
00671 
00672    for (p1 = 0 ; test_array [p1].fn != NULL ; p1 ++)
00673    {
00674       test_entry* entry = & test_array [p1];
00675 
00676       execute (p1, entry->result, entry->fn, entry->name);
00677    }
00678 
00679    fprintf (stderr, "== all tests done, %s passed.\n",
00680             passed_count == execed_count ? "ALL" : "NOT all");
00681    fprintf (stderr, "== executed %8d\n", execed_count);
00682    fprintf (stderr, "== passed   %8d\n", passed_count);
00683    fprintf (stderr, "== failed   %8d\n", failed_count);
00684 
00685    return 0;
00686 }

Generated on Thu Feb 9 13:11:33 2006 for fastapi by doxygen 1.4.6-NO    FAST ProtocolSM