diff options
author | bapt <bapt@FreeBSD.org> | 2014-07-19 23:44:57 +0000 |
---|---|---|
committer | bapt <bapt@FreeBSD.org> | 2014-07-19 23:44:57 +0000 |
commit | 6f718e3669e9ecc1b1ca407a465d6ee20571a2b8 (patch) | |
tree | ba71cc26671c93ed9809f7cadb07734c0bddb4c7 /contrib/libucl/tests/test_schema.c | |
parent | 6095428430d025abcf6983536297f168bf62b45b (diff) | |
download | FreeBSD-src-6f718e3669e9ecc1b1ca407a465d6ee20571a2b8.zip FreeBSD-src-6f718e3669e9ecc1b1ca407a465d6ee20571a2b8.tar.gz |
MFC: r263648, r264789, r266636
This brings:
- schema validation
- xpath-like interface for ucl objects
Adapt pkg(7) to the new libucl API
Diffstat (limited to 'contrib/libucl/tests/test_schema.c')
-rw-r--r-- | contrib/libucl/tests/test_schema.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/contrib/libucl/tests/test_schema.c b/contrib/libucl/tests/test_schema.c new file mode 100644 index 0000000..afce178 --- /dev/null +++ b/contrib/libucl/tests/test_schema.c @@ -0,0 +1,158 @@ +/* Copyright (c) 2014, Vsevolod Stakhov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include "ucl.h" + +static int +read_stdin (char **buf) +{ + int size = BUFSIZ, remain, ret; + char *p; + + *buf = malloc (size); + if (*buf == NULL) { + return -1; + } + + p = *buf; + remain = size; + + while ((ret = read (STDIN_FILENO, p, remain)) > 0) { + remain -= ret; + p += ret; + if (remain == 0) { + *buf = realloc (*buf, size * 2); + if (*buf == NULL) { + return -1; + } + p = *buf + size; + remain = size; + size *= 2; + } + } + + return ret; +} + +static bool +perform_test (const ucl_object_t *schema, const ucl_object_t *obj, + struct ucl_schema_error *err) +{ + const const ucl_object_t *valid, *data, *description; + bool match; + + data = ucl_object_find_key (obj, "data"); + description = ucl_object_find_key (obj, "description"); + valid = ucl_object_find_key (obj, "valid"); + + if (data == NULL || description == NULL || valid == NULL) { + fprintf (stdout, "Bad test case\n"); + return false; + } + + match = ucl_object_validate (schema, data, err); + if (match != ucl_object_toboolean (valid)) { + fprintf (stdout, "Test case '%s' failed (expected %s): '%s'\n", + ucl_object_tostring (description), + ucl_object_toboolean (valid) ? "valid" : "invalid", + err->msg); + return false; + } + + return true; +} + +static int +perform_tests (const ucl_object_t *obj) +{ + struct ucl_schema_error err; + ucl_object_iter_t iter = NULL; + const ucl_object_t *schema, *tests, *description, *test; + + if (obj->type != UCL_OBJECT) { + fprintf (stdout, "Bad test case\n"); + return EXIT_FAILURE; + } + + schema = ucl_object_find_key (obj, "schema"); + tests = ucl_object_find_key (obj, "tests"); + description = ucl_object_find_key (obj, "description"); + + if (schema == NULL || tests == NULL || description == NULL) { + fprintf (stdout, "Bad test case\n"); + return EXIT_FAILURE; + } + + memset (&err, 0, sizeof (err)); + + while ((test = ucl_iterate_object (tests, &iter, true)) != NULL) { + if (!perform_test (schema, test, &err)) { + fprintf (stdout, "Test suite '%s' failed\n", + ucl_object_tostring (description)); + return EXIT_FAILURE; + } + } + + return 0; +} + +int +main (int argc, char **argv) +{ + char *buf = NULL; + struct ucl_parser *parser; + ucl_object_t *obj = NULL; + const ucl_object_t *elt; + ucl_object_iter_t iter = NULL; + int ret = 0; + + if (read_stdin (&buf) == -1) { + exit (EXIT_FAILURE); + } + + parser = ucl_parser_new (0); + + ucl_parser_add_string (parser, buf, 0); + + if (ucl_parser_get_error (parser) != NULL) { + fprintf (stdout, "Error occurred: %s\n", ucl_parser_get_error (parser)); + ret = 1; + return EXIT_FAILURE; + } + obj = ucl_parser_get_object (parser); + ucl_parser_free (parser); + + while ((elt = ucl_iterate_object (obj, &iter, true)) != NULL) { + ret = perform_tests (elt); + if (ret != 0) { + break; + } + } + + ucl_object_unref (obj); + + return ret; +} |