Path: blob/main/contrib/libucl/tests/test_msgpack.c
39586 views
/*1* Copyright (c) 2015, Vsevolod Stakhov2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions are met:6* * Redistributions of source code must retain the above copyright7* notice, this list of conditions and the following disclaimer.8* * Redistributions in binary form must reproduce the above copyright9* notice, this list of conditions and the following disclaimer in the10* documentation and/or other materials provided with the distribution.11*12* THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY13* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED14* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE15* DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY16* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES17* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;18* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND19* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT20* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS21* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.22*/2324#include "ucl.h"25#include "ucl_internal.h"26#include <ctype.h>2728static const int niter = 20;29static const int ntests = 10;30static const int nelt = 20;3132static int recursion = 0;3334typedef ucl_object_t* (*ucl_msgpack_test)(void);3536static ucl_object_t* ucl_test_integer (void);37static ucl_object_t* ucl_test_string (void);38static ucl_object_t* ucl_test_boolean (void);39static ucl_object_t* ucl_test_map (void);40static ucl_object_t* ucl_test_array (void);41static ucl_object_t* ucl_test_large_map (void);42static ucl_object_t* ucl_test_large_array (void);43static ucl_object_t* ucl_test_large_string (void);44static ucl_object_t* ucl_test_null (void);4546ucl_msgpack_test tests[] = {47ucl_test_integer,48ucl_test_string,49ucl_test_boolean,50ucl_test_map,51ucl_test_array,52ucl_test_null53};5455#define NTESTS (sizeof(tests) / sizeof(tests[0]))5657typedef struct58{59uint64_t state;60uint64_t inc;61} pcg32_random_t;6263pcg32_random_t rng;6465/*66* From http://www.pcg-random.org/67*/68static uint32_t69pcg32_random (void)70{71uint64_t oldstate = rng.state;7273rng.state = oldstate * 6364136223846793005ULL + (rng.inc | 1);74uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;75uint32_t rot = oldstate >> 59u;76return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));77}7879static const char *80random_key (size_t *lenptr)81{82static char keybuf[512];83int keylen, i;84char c;8586keylen = pcg32_random () % (sizeof (keybuf) - 1) + 1;8788for (i = 0; i < keylen; i ++) {89do {90c = pcg32_random () & 0xFF;91} while (!isgraph (c));9293keybuf[i] = c;94}9596*lenptr = keylen;97return keybuf;98}99100int101main (int argc, char **argv)102{103int fd, i, j;104uint32_t sel;105ucl_object_t *obj, *elt;106struct ucl_parser *parser;107size_t klen, elen, elen2;108const char *key;109unsigned char *emitted, *emitted2;110FILE *out;111const char *fname_out = NULL;112113switch (argc) {114case 2:115fname_out = argv[1];116break;117}118119/* Seed prng */120fd = open ("/dev/urandom", O_RDONLY);121assert (fd != -1);122assert (read (fd, &rng, sizeof (rng)) == sizeof (rng));123close (fd);124125for (i = 0; i < niter; i ++) {126if (fname_out != NULL) {127out = fopen (fname_out, "w");128if (out == NULL) {129exit (-errno);130}131}132else {133out = NULL;134}135136/* Generate phase */137obj = ucl_object_typed_new (UCL_OBJECT);138139for (j = 0; j < ntests; j ++) {140sel = pcg32_random () % NTESTS;141142key = random_key (&klen);143recursion = 0;144elt = tests[sel]();145assert (elt != NULL);146assert (klen != 0);147148ucl_object_insert_key (obj, elt, key, klen, true);149}150151key = random_key (&klen);152elt = ucl_test_large_array ();153ucl_object_insert_key (obj, elt, key, klen, true);154155key = random_key (&klen);156elt = ucl_test_large_map ();157ucl_object_insert_key (obj, elt, key, klen, true);158159key = random_key (&klen);160elt = ucl_test_large_string ();161ucl_object_insert_key (obj, elt, key, klen, true);162163emitted = ucl_object_emit_len (obj, UCL_EMIT_MSGPACK, &elen);164165assert (emitted != NULL);166167if (out) {168fprintf (out, "%*.s\n", (int)elen, emitted);169170fclose (out);171}172ucl_object_unref (obj);173174parser = ucl_parser_new (0);175176if (!ucl_parser_add_chunk_full (parser, emitted, elen, 0,177UCL_DUPLICATE_APPEND, UCL_PARSE_MSGPACK)) {178fprintf (stderr, "error parsing input: %s",179ucl_parser_get_error (parser));180assert (0);181}182183obj = ucl_parser_get_object (parser);184assert (obj != NULL);185186emitted2 = ucl_object_emit_len (obj, UCL_EMIT_MSGPACK, &elen2);187188assert (emitted2 != NULL);189assert (elen2 == elen);190assert (memcmp (emitted, emitted2, elen) == 0);191192ucl_parser_free (parser);193ucl_object_unref (obj);194free (emitted);195free (emitted2);196}197198return 0;199}200201202static ucl_object_t*203ucl_test_integer (void)204{205ucl_object_t *res;206int count, i;207uint64_t cur;208double curf;209210res = ucl_object_typed_new (UCL_ARRAY);211count = pcg32_random () % nelt;212213for (i = 0; i < count; i ++) {214cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random ();215ucl_array_append (res, ucl_object_fromint (cur % 128));216ucl_array_append (res, ucl_object_fromint (-(cur % 128)));217cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random ();218ucl_array_append (res, ucl_object_fromint (cur % UINT16_MAX));219ucl_array_append (res, ucl_object_fromint (-(cur % INT16_MAX)));220cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random ();221ucl_array_append (res, ucl_object_fromint (cur % UINT32_MAX));222ucl_array_append (res, ucl_object_fromint (-(cur % INT32_MAX)));223cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random ();224ucl_array_append (res, ucl_object_fromint (cur));225ucl_array_append (res, ucl_object_fromint (-cur));226/* Double version */227cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random ();228curf = (cur % 128) / 19 * 16;229ucl_array_append (res, ucl_object_fromdouble (curf));230cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random ();231curf = -(cur % 128) / 19 * 16;232ucl_array_append (res, ucl_object_fromdouble (curf));233cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random ();234curf = (cur % 65536) / 19 * 16;235ucl_array_append (res, ucl_object_fromdouble (curf));236ucl_array_append (res, ucl_object_fromdouble (-curf));237cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random ();238curf = (cur % INT32_MAX) / 19 * 16;239ucl_array_append (res, ucl_object_fromdouble (curf));240cur = ((uint64_t)pcg32_random ()) << 32 | pcg32_random ();241memcpy (&curf, &cur, sizeof (curf));242ucl_array_append (res, ucl_object_fromint (cur));243}244245return res;246}247248static ucl_object_t*249ucl_test_string (void)250{251ucl_object_t *res, *elt;252int count, i;253uint32_t cur_len;254char *str;255256res = ucl_object_typed_new (UCL_ARRAY);257count = pcg32_random () % nelt;258259for (i = 0; i < count; i ++) {260while ((cur_len = pcg32_random ()) % 128 == 0);261262str = malloc (cur_len % 128);263ucl_array_append (res, ucl_object_fromstring_common (str, cur_len % 128,264UCL_STRING_RAW));265free (str);266267while ((cur_len = pcg32_random ()) % 512 == 0);268str = malloc (cur_len % 512);269ucl_array_append (res, ucl_object_fromstring_common (str, cur_len % 512,270UCL_STRING_RAW));271free (str);272273while ((cur_len = pcg32_random ()) % 128 == 0);274str = malloc (cur_len % 128);275elt = ucl_object_fromstring_common (str, cur_len % 128,276UCL_STRING_RAW);277elt->flags |= UCL_OBJECT_BINARY;278ucl_array_append (res, elt);279free (str);280281while ((cur_len = pcg32_random ()) % 512 == 0);282str = malloc (cur_len % 512);283elt = ucl_object_fromstring_common (str, cur_len % 512,284UCL_STRING_RAW);285elt->flags |= UCL_OBJECT_BINARY;286ucl_array_append (res, elt);287free (str);288}289290/* One large string */291str = malloc (65537);292elt = ucl_object_fromstring_common (str, 65537,293UCL_STRING_RAW);294elt->flags |= UCL_OBJECT_BINARY;295ucl_array_append (res, elt);296free (str);297298return res;299}300301static ucl_object_t*302ucl_test_boolean (void)303{304ucl_object_t *res;305int count, i;306307res = ucl_object_typed_new (UCL_ARRAY);308count = pcg32_random () % nelt;309310for (i = 0; i < count; i ++) {311ucl_array_append (res, ucl_object_frombool (pcg32_random () % 2));312}313314return res;315}316317static ucl_object_t*318ucl_test_map (void)319{320ucl_object_t *res, *cur;321int count, i;322uint32_t cur_len, sel;323size_t klen;324const char *key;325326res = ucl_object_typed_new (UCL_OBJECT);327count = pcg32_random () % nelt;328329recursion ++;330331for (i = 0; i < count; i ++) {332333if (recursion > 10) {334for (;;) {335sel = pcg32_random () % NTESTS;336if (tests[sel] != ucl_test_map &&337tests[sel] != ucl_test_array) {338break;339}340}341}342else {343sel = pcg32_random () % NTESTS;344}345346key = random_key (&klen);347cur = tests[sel]();348assert (cur != NULL);349assert (klen != 0);350351ucl_object_insert_key (res, cur, key, klen, true);352353/* Multi value key */354cur = tests[sel]();355assert (cur != NULL);356357ucl_object_insert_key (res, cur, key, klen, true);358}359360return res;361}362363static ucl_object_t*364ucl_test_large_map (void)365{366ucl_object_t *res, *cur;367int count, i;368uint32_t cur_len;369size_t klen;370const char *key;371372res = ucl_object_typed_new (UCL_OBJECT);373count = 65537;374375recursion ++;376377for (i = 0; i < count; i ++) {378key = random_key (&klen);379cur = ucl_test_boolean ();380assert (cur != NULL);381assert (klen != 0);382383ucl_object_insert_key (res, cur, key, klen, true);384}385386return res;387}388389static ucl_object_t*390ucl_test_array (void)391{392ucl_object_t *res, *cur;393int count, i;394uint32_t cur_len, sel;395396res = ucl_object_typed_new (UCL_ARRAY);397count = pcg32_random () % nelt;398399recursion ++;400401for (i = 0; i < count; i ++) {402if (recursion > 10) {403for (;;) {404sel = pcg32_random () % NTESTS;405if (tests[sel] != ucl_test_map &&406tests[sel] != ucl_test_array) {407break;408}409}410}411else {412sel = pcg32_random () % NTESTS;413}414415cur = tests[sel]();416assert (cur != NULL);417418ucl_array_append (res, cur);419}420421return res;422}423424static ucl_object_t*425ucl_test_large_array (void)426{427ucl_object_t *res, *cur;428int count, i;429uint32_t cur_len;430431res = ucl_object_typed_new (UCL_ARRAY);432count = 65537;433434recursion ++;435436for (i = 0; i < count; i ++) {437cur = ucl_test_boolean ();438assert (cur != NULL);439440ucl_array_append (res, cur);441}442443return res;444}445446static ucl_object_t*447ucl_test_large_string (void)448{449ucl_object_t *res;450char *str;451uint32_t cur_len;452453while ((cur_len = pcg32_random ()) % 100000 == 0);454str = malloc (cur_len % 100000);455res = ucl_object_fromstring_common (str, cur_len % 100000,456UCL_STRING_RAW);457res->flags |= UCL_OBJECT_BINARY;458free (str);459460return res;461}462463static ucl_object_t*464ucl_test_null (void)465{466return ucl_object_typed_new (UCL_NULL);467}468469470