test_msgpack.c revision 290067
1290067Sbapt/* 2290067Sbapt * Copyright (c) 2015, Vsevolod Stakhov 3290067Sbapt * All rights reserved. 4290067Sbapt * 5290067Sbapt * Redistribution and use in source and binary forms, with or without 6290067Sbapt * modification, are permitted provided that the following conditions are met: 7290067Sbapt * * Redistributions of source code must retain the above copyright 8290067Sbapt * notice, this list of conditions and the following disclaimer. 9290067Sbapt * * Redistributions in binary form must reproduce the above copyright 10290067Sbapt * notice, this list of conditions and the following disclaimer in the 11290067Sbapt * documentation and/or other materials provided with the distribution. 12290067Sbapt * 13290067Sbapt * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY 14290067Sbapt * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15290067Sbapt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16290067Sbapt * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY 17290067Sbapt * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18290067Sbapt * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19290067Sbapt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20290067Sbapt * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21290067Sbapt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22290067Sbapt * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23290067Sbapt */ 24290067Sbapt 25290067Sbapt#include "ucl.h" 26290067Sbapt#include "ucl_internal.h" 27290067Sbapt#include <ctype.h> 28290067Sbapt 29290067Sbaptstatic const int niter = 1000; 30290067Sbaptstatic const int ntests = 100; 31290067Sbaptstatic const int nelt = 10; 32290067Sbapt 33290067Sbaptstatic int recursion = 0; 34290067Sbapt 35290067Sbapttypedef ucl_object_t* (*ucl_msgpack_test)(void); 36290067Sbapt 37290067Sbaptstatic ucl_object_t* ucl_test_integer (void); 38290067Sbaptstatic ucl_object_t* ucl_test_string (void); 39290067Sbaptstatic ucl_object_t* ucl_test_boolean (void); 40290067Sbaptstatic ucl_object_t* ucl_test_map (void); 41290067Sbaptstatic ucl_object_t* ucl_test_array (void); 42290067Sbapt 43290067Sbaptucl_msgpack_test tests[] = { 44290067Sbapt ucl_test_integer, 45290067Sbapt ucl_test_string, 46290067Sbapt ucl_test_boolean, 47290067Sbapt ucl_test_map, 48290067Sbapt ucl_test_array, 49290067Sbapt}; 50290067Sbapt 51290067Sbapt#define NTESTS (sizeof(tests) / sizeof(tests[0])) 52290067Sbapt 53290067Sbapttypedef struct 54290067Sbapt{ 55290067Sbapt uint64_t state; 56290067Sbapt uint64_t inc; 57290067Sbapt} pcg32_random_t; 58290067Sbapt 59290067Sbaptpcg32_random_t rng; 60290067Sbapt 61290067Sbapt/* 62290067Sbapt * From http://www.pcg-random.org/ 63290067Sbapt */ 64290067Sbaptstatic uint32_t 65290067Sbaptpcg32_random (void) 66290067Sbapt{ 67290067Sbapt uint64_t oldstate = rng.state; 68290067Sbapt 69290067Sbapt rng.state = oldstate * 6364136223846793005ULL + (rng.inc | 1); 70290067Sbapt uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; 71290067Sbapt uint32_t rot = oldstate >> 59u; 72290067Sbapt return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); 73290067Sbapt} 74290067Sbapt 75290067Sbaptstatic const char * 76290067Sbaptrandom_key (size_t *lenptr) 77290067Sbapt{ 78290067Sbapt static char keybuf[512]; 79290067Sbapt int keylen, i; 80290067Sbapt char c; 81290067Sbapt 82290067Sbapt keylen = pcg32_random () % (sizeof (keybuf) - 1) + 1; 83290067Sbapt 84290067Sbapt for (i = 0; i < keylen; i ++) { 85290067Sbapt do { 86290067Sbapt c = pcg32_random () & 0xFF; 87290067Sbapt } while (!isgraph (c)); 88290067Sbapt 89290067Sbapt keybuf[i] = c; 90290067Sbapt } 91290067Sbapt 92290067Sbapt *lenptr = keylen; 93290067Sbapt return keybuf; 94290067Sbapt} 95290067Sbapt 96290067Sbaptint 97290067Sbaptmain (int argc, char **argv) 98290067Sbapt{ 99290067Sbapt int fd, i, j; 100290067Sbapt uint32_t sel; 101290067Sbapt ucl_object_t *obj, *elt; 102290067Sbapt struct ucl_parser *parser; 103290067Sbapt size_t klen, elen, elen2; 104290067Sbapt const char *key; 105290067Sbapt unsigned char *emitted, *emitted2; 106290067Sbapt FILE *out; 107290067Sbapt const char *fname_out = NULL; 108290067Sbapt 109290067Sbapt switch (argc) { 110290067Sbapt case 2: 111290067Sbapt fname_out = argv[1]; 112290067Sbapt break; 113290067Sbapt } 114290067Sbapt 115290067Sbapt /* Seed prng */ 116290067Sbapt fd = open ("/dev/urandom", O_RDONLY); 117290067Sbapt assert (fd != -1); 118290067Sbapt assert (read (fd, &rng, sizeof (rng)) == sizeof (rng)); 119290067Sbapt close (fd); 120290067Sbapt 121290067Sbapt for (i = 0; i < niter; i ++) { 122290067Sbapt if (fname_out != NULL) { 123290067Sbapt out = fopen (fname_out, "w"); 124290067Sbapt if (out == NULL) { 125290067Sbapt exit (-errno); 126290067Sbapt } 127290067Sbapt } 128290067Sbapt else { 129290067Sbapt out = NULL; 130290067Sbapt } 131290067Sbapt 132290067Sbapt /* Generate phase */ 133290067Sbapt obj = ucl_object_typed_new (UCL_OBJECT); 134290067Sbapt 135290067Sbapt for (j = 0; j < ntests; j ++) { 136290067Sbapt sel = pcg32_random () % NTESTS; 137290067Sbapt 138290067Sbapt key = random_key (&klen); 139290067Sbapt recursion = 0; 140290067Sbapt elt = tests[sel](); 141290067Sbapt assert (elt != NULL); 142290067Sbapt assert (klen != 0); 143290067Sbapt 144290067Sbapt ucl_object_insert_key (obj, elt, key, klen, true); 145290067Sbapt } 146290067Sbapt 147290067Sbapt emitted = ucl_object_emit_len (obj, UCL_EMIT_MSGPACK, &elen); 148290067Sbapt 149290067Sbapt assert (emitted != NULL); 150290067Sbapt 151290067Sbapt if (out) { 152290067Sbapt fprintf (out, "%*.s\n", (int)elen, emitted); 153290067Sbapt 154290067Sbapt fclose (out); 155290067Sbapt } 156290067Sbapt ucl_object_unref (obj); 157290067Sbapt 158290067Sbapt parser = ucl_parser_new (0); 159290067Sbapt 160290067Sbapt if (!ucl_parser_add_chunk_full (parser, emitted, elen, 0, 161290067Sbapt UCL_DUPLICATE_APPEND, UCL_PARSE_MSGPACK)) { 162290067Sbapt fprintf (stderr, "error parsing input: %s", 163290067Sbapt ucl_parser_get_error (parser)); 164290067Sbapt assert (0); 165290067Sbapt } 166290067Sbapt 167290067Sbapt obj = ucl_parser_get_object (parser); 168290067Sbapt assert (obj != NULL); 169290067Sbapt 170290067Sbapt emitted2 = ucl_object_emit_len (obj, UCL_EMIT_MSGPACK, &elen2); 171290067Sbapt 172290067Sbapt assert (emitted2 != NULL); 173290067Sbapt assert (elen2 == elen); 174290067Sbapt assert (memcmp (emitted, emitted2, elen) == 0); 175290067Sbapt 176290067Sbapt ucl_parser_free (parser); 177290067Sbapt ucl_object_unref (obj); 178290067Sbapt free (emitted); 179290067Sbapt free (emitted2); 180290067Sbapt } 181290067Sbapt 182290067Sbapt return 0; 183290067Sbapt} 184290067Sbapt 185290067Sbapt 186290067Sbaptstatic ucl_object_t* 187290067Sbaptucl_test_integer (void) 188290067Sbapt{ 189290067Sbapt ucl_object_t *res; 190290067Sbapt int count, i; 191290067Sbapt uint64_t cur; 192290067Sbapt 193290067Sbapt res = ucl_object_typed_new (UCL_ARRAY); 194290067Sbapt count = pcg32_random () % nelt; 195290067Sbapt 196290067Sbapt for (i = 0; i < count; i ++) { 197290067Sbapt cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random (); 198290067Sbapt ucl_array_append (res, ucl_object_fromint (cur % 128)); 199290067Sbapt cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random (); 200290067Sbapt ucl_array_append (res, ucl_object_fromint (-cur % 128)); 201290067Sbapt cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random (); 202290067Sbapt ucl_array_append (res, ucl_object_fromint (cur % 65536)); 203290067Sbapt cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random (); 204290067Sbapt ucl_array_append (res, ucl_object_fromint (cur % INT32_MAX)); 205290067Sbapt cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random (); 206290067Sbapt ucl_array_append (res, ucl_object_fromint (cur)); 207290067Sbapt } 208290067Sbapt 209290067Sbapt return res; 210290067Sbapt} 211290067Sbapt 212290067Sbaptstatic ucl_object_t* 213290067Sbaptucl_test_string (void) 214290067Sbapt{ 215290067Sbapt ucl_object_t *res, *elt; 216290067Sbapt int count, i; 217290067Sbapt uint32_t cur_len; 218290067Sbapt char *str; 219290067Sbapt 220290067Sbapt res = ucl_object_typed_new (UCL_ARRAY); 221290067Sbapt count = pcg32_random () % nelt; 222290067Sbapt 223290067Sbapt for (i = 0; i < count; i ++) { 224290067Sbapt while ((cur_len = pcg32_random ()) % 128 == 0); 225290067Sbapt 226290067Sbapt str = malloc (cur_len % 128); 227290067Sbapt ucl_array_append (res, ucl_object_fromstring_common (str, cur_len % 128, 228290067Sbapt UCL_STRING_RAW)); 229290067Sbapt free (str); 230290067Sbapt 231290067Sbapt while ((cur_len = pcg32_random ()) % 512 == 0); 232290067Sbapt str = malloc (cur_len % 512); 233290067Sbapt ucl_array_append (res, ucl_object_fromstring_common (str, cur_len % 512, 234290067Sbapt UCL_STRING_RAW)); 235290067Sbapt free (str); 236290067Sbapt 237290067Sbapt while ((cur_len = pcg32_random ()) % 128 == 0); 238290067Sbapt str = malloc (cur_len % 128); 239290067Sbapt elt = ucl_object_fromstring_common (str, cur_len % 128, 240290067Sbapt UCL_STRING_RAW); 241290067Sbapt elt->flags |= UCL_OBJECT_BINARY; 242290067Sbapt ucl_array_append (res, elt); 243290067Sbapt free (str); 244290067Sbapt 245290067Sbapt while ((cur_len = pcg32_random ()) % 512 == 0); 246290067Sbapt str = malloc (cur_len % 512); 247290067Sbapt elt = ucl_object_fromstring_common (str, cur_len % 512, 248290067Sbapt UCL_STRING_RAW); 249290067Sbapt elt->flags |= UCL_OBJECT_BINARY; 250290067Sbapt ucl_array_append (res, elt); 251290067Sbapt free (str); 252290067Sbapt } 253290067Sbapt 254290067Sbapt return res; 255290067Sbapt} 256290067Sbapt 257290067Sbaptstatic ucl_object_t* 258290067Sbaptucl_test_boolean (void) 259290067Sbapt{ 260290067Sbapt ucl_object_t *res; 261290067Sbapt int count, i; 262290067Sbapt 263290067Sbapt res = ucl_object_typed_new (UCL_ARRAY); 264290067Sbapt count = pcg32_random () % nelt; 265290067Sbapt 266290067Sbapt for (i = 0; i < count; i ++) { 267290067Sbapt ucl_array_append (res, ucl_object_frombool (pcg32_random () % 2)); 268290067Sbapt } 269290067Sbapt 270290067Sbapt return res; 271290067Sbapt} 272290067Sbapt 273290067Sbaptstatic ucl_object_t* 274290067Sbaptucl_test_map (void) 275290067Sbapt{ 276290067Sbapt ucl_object_t *res, *cur; 277290067Sbapt int count, i; 278290067Sbapt uint32_t cur_len, sel; 279290067Sbapt size_t klen; 280290067Sbapt const char *key; 281290067Sbapt 282290067Sbapt res = ucl_object_typed_new (UCL_OBJECT); 283290067Sbapt count = pcg32_random () % nelt; 284290067Sbapt 285290067Sbapt recursion ++; 286290067Sbapt 287290067Sbapt for (i = 0; i < count; i ++) { 288290067Sbapt 289290067Sbapt if (recursion > 10) { 290290067Sbapt sel = pcg32_random () % (NTESTS - 2); 291290067Sbapt } 292290067Sbapt else { 293290067Sbapt sel = pcg32_random () % NTESTS; 294290067Sbapt } 295290067Sbapt 296290067Sbapt key = random_key (&klen); 297290067Sbapt cur = tests[sel](); 298290067Sbapt assert (cur != NULL); 299290067Sbapt assert (klen != 0); 300290067Sbapt 301290067Sbapt ucl_object_insert_key (res, cur, key, klen, true); 302290067Sbapt 303290067Sbapt /* Multi value key */ 304290067Sbapt cur = tests[sel](); 305290067Sbapt assert (cur != NULL); 306290067Sbapt 307290067Sbapt ucl_object_insert_key (res, cur, key, klen, true); 308290067Sbapt } 309290067Sbapt 310290067Sbapt return res; 311290067Sbapt} 312290067Sbapt 313290067Sbaptstatic ucl_object_t* 314290067Sbaptucl_test_array (void) 315290067Sbapt{ 316290067Sbapt ucl_object_t *res, *cur; 317290067Sbapt int count, i; 318290067Sbapt uint32_t cur_len, sel; 319290067Sbapt 320290067Sbapt res = ucl_object_typed_new (UCL_ARRAY); 321290067Sbapt count = pcg32_random () % nelt; 322290067Sbapt 323290067Sbapt recursion ++; 324290067Sbapt 325290067Sbapt for (i = 0; i < count; i ++) { 326290067Sbapt if (recursion > 10) { 327290067Sbapt sel = pcg32_random () % (NTESTS - 2); 328290067Sbapt } 329290067Sbapt else { 330290067Sbapt sel = pcg32_random () % NTESTS; 331290067Sbapt } 332290067Sbapt 333290067Sbapt cur = tests[sel](); 334290067Sbapt assert (cur != NULL); 335290067Sbapt 336290067Sbapt ucl_array_append (res, cur); 337290067Sbapt } 338290067Sbapt 339290067Sbapt return res; 340290067Sbapt} 341