The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/tests/zfs-tests/cmd/nvlist_to_lua.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * CDDL HEADER START
    3  *
    4  * This file and its contents are supplied under the terms of the
    5  * Common Development and Distribution License ("CDDL"), version 1.0.
    6  * You may only use this file in accordance with the terms of version
    7  * 1.0 of the CDDL.
    8  *
    9  * A full copy of the text of the CDDL should have accompanied this
   10  * source.  A copy of the CDDL is also available via the Internet at
   11  * http://www.illumos.org/license/CDDL.
   12  *
   13  * CDDL HEADER END
   14  */
   15 
   16 /*
   17  * Copyright (c) 2016 by Delphix. All rights reserved.
   18  */
   19 
   20 #include <stdio.h>
   21 #include <stdlib.h>
   22 #include <string.h>
   23 #include <libzfs_core.h>
   24 #include <sys/nvpair.h>
   25 
   26 static nvlist_t *nvl;
   27 static const char *pool;
   28 static boolean_t unexpected_failures;
   29 
   30 static boolean_t
   31 nvlist_equal(nvlist_t *nvla, nvlist_t *nvlb)
   32 {
   33         if (fnvlist_num_pairs(nvla) != fnvlist_num_pairs(nvlb))
   34                 return (B_FALSE);
   35         /*
   36          * The nvlists have the same number of pairs and keys are unique, so
   37          * if every key in A is also in B and assigned to the same value, the
   38          * lists are identical.
   39          */
   40         for (nvpair_t *pair = nvlist_next_nvpair(nvla, NULL);
   41             pair != NULL; pair = nvlist_next_nvpair(nvla, pair)) {
   42                 char *key = nvpair_name(pair);
   43 
   44                 if (!nvlist_exists(nvlb, key))
   45                         return (B_FALSE);
   46 
   47                 if (nvpair_type(pair) !=
   48                     nvpair_type(fnvlist_lookup_nvpair(nvlb, key)))
   49                         return (B_FALSE);
   50 
   51                 switch (nvpair_type(pair)) {
   52                 case DATA_TYPE_BOOLEAN_VALUE:
   53                         if (fnvpair_value_boolean_value(pair) !=
   54                             fnvlist_lookup_boolean_value(nvlb, key)) {
   55                                 return (B_FALSE);
   56                         }
   57                         break;
   58                 case DATA_TYPE_STRING:
   59                         if (strcmp(fnvpair_value_string(pair),
   60                             fnvlist_lookup_string(nvlb, key))) {
   61                                 return (B_FALSE);
   62                         }
   63                         break;
   64                 case DATA_TYPE_INT64:
   65                         if (fnvpair_value_int64(pair) !=
   66                             fnvlist_lookup_int64(nvlb, key)) {
   67                                 return (B_FALSE);
   68                         }
   69                         break;
   70                 case DATA_TYPE_NVLIST:
   71                         if (!nvlist_equal(fnvpair_value_nvlist(pair),
   72                             fnvlist_lookup_nvlist(nvlb, key))) {
   73                                 return (B_FALSE);
   74                         }
   75                         break;
   76                 default:
   77                         (void) printf("Unexpected type for nvlist_equal\n");
   78                         return (B_FALSE);
   79                 }
   80         }
   81         return (B_TRUE);
   82 }
   83 
   84 static void
   85 test(const char *testname, boolean_t expect_success, boolean_t expect_match)
   86 {
   87         const char *progstr = "input = ...; return {output=input}";
   88 
   89         nvlist_t *outnvl;
   90 
   91         (void) printf("\nrunning test '%s'; input:\n", testname);
   92         dump_nvlist(nvl, 4);
   93 
   94         int err = lzc_channel_program(pool, progstr,
   95             10 * 1000 * 1000, 10 * 1024 * 1024, nvl, &outnvl);
   96 
   97         (void) printf("lzc_channel_program returned %u\n", err);
   98         dump_nvlist(outnvl, 5);
   99 
  100         if (err == 0 && expect_match) {
  101                 /*
  102                  * Verify that outnvl is the same as input nvl, if we expect
  103                  * them to be. The input and output will never match if the
  104                  * input contains an array (since arrays are converted to lua
  105                  * tables), so this is only asserted for some test cases.
  106                  */
  107                 nvlist_t *real_outnvl = fnvlist_lookup_nvlist(outnvl, "return");
  108                 real_outnvl = fnvlist_lookup_nvlist(real_outnvl, "output");
  109                 if (!nvlist_equal(nvl, real_outnvl)) {
  110                         unexpected_failures = B_TRUE;
  111                         (void) printf("unexpected input/output mismatch for "
  112                             "case: %s\n", testname);
  113                 }
  114         }
  115         if (err != 0 && expect_success) {
  116                 unexpected_failures = B_TRUE;
  117                 (void) printf("unexpected FAIL of case: %s\n", testname);
  118         }
  119 
  120         fnvlist_free(nvl);
  121         nvl = fnvlist_alloc();
  122 }
  123 
  124 static void
  125 run_tests(void)
  126 {
  127         const char *key = "key";
  128 
  129         /* Note: maximum nvlist key length is 32KB */
  130         int len = 1024 * 31;
  131         char *bigstring = malloc(len);
  132         if (bigstring == NULL) {
  133                 perror("malloc");
  134                 exit(EXIT_FAILURE);
  135         }
  136 
  137         for (int i = 0; i < len; i++)
  138                 bigstring[i] = 'a' + i % 26;
  139         bigstring[len - 1] = '\0';
  140 
  141         nvl = fnvlist_alloc();
  142 
  143         fnvlist_add_boolean(nvl, key);
  144         test("boolean", B_TRUE, B_FALSE);
  145 
  146         fnvlist_add_boolean_value(nvl, key, B_TRUE);
  147         test("boolean_value", B_FALSE, B_FALSE);
  148 
  149         fnvlist_add_byte(nvl, key, 1);
  150         test("byte", B_FALSE, B_FALSE);
  151 
  152         fnvlist_add_int8(nvl, key, 1);
  153         test("int8", B_FALSE, B_FALSE);
  154 
  155         fnvlist_add_uint8(nvl, key, 1);
  156         test("uint8", B_FALSE, B_FALSE);
  157 
  158         fnvlist_add_int16(nvl, key, 1);
  159         test("int16", B_FALSE, B_FALSE);
  160 
  161         fnvlist_add_uint16(nvl, key, 1);
  162         test("uint16", B_FALSE, B_FALSE);
  163 
  164         fnvlist_add_int32(nvl, key, 1);
  165         test("int32", B_FALSE, B_FALSE);
  166 
  167         fnvlist_add_uint32(nvl, key, 1);
  168         test("uint32", B_FALSE, B_FALSE);
  169 
  170         fnvlist_add_int64(nvl, key, 1);
  171         test("int64", B_TRUE, B_TRUE);
  172 
  173         fnvlist_add_uint64(nvl, key, 1);
  174         test("uint64", B_FALSE, B_FALSE);
  175 
  176         fnvlist_add_string(nvl, key, "1");
  177         test("string", B_TRUE, B_TRUE);
  178 
  179 
  180         {
  181                 nvlist_t *val = fnvlist_alloc();
  182                 fnvlist_add_string(val, "subkey", "subvalue");
  183                 fnvlist_add_nvlist(nvl, key, val);
  184                 fnvlist_free(val);
  185                 test("nvlist", B_TRUE, B_TRUE);
  186         }
  187         {
  188                 boolean_t val[2] = { B_FALSE, B_TRUE };
  189                 fnvlist_add_boolean_array(nvl, key, val, 2);
  190                 test("boolean_array", B_FALSE, B_FALSE);
  191         }
  192         {
  193                 uchar_t val[2] = { 0, 1 };
  194                 fnvlist_add_byte_array(nvl, key, val, 2);
  195                 test("byte_array", B_FALSE, B_FALSE);
  196         }
  197         {
  198                 int8_t val[2] = { 0, 1 };
  199                 fnvlist_add_int8_array(nvl, key, val, 2);
  200                 test("int8_array", B_FALSE, B_FALSE);
  201         }
  202         {
  203                 uint8_t val[2] = { 0, 1 };
  204                 fnvlist_add_uint8_array(nvl, key, val, 2);
  205                 test("uint8_array", B_FALSE, B_FALSE);
  206         }
  207         {
  208                 int16_t val[2] = { 0, 1 };
  209                 fnvlist_add_int16_array(nvl, key, val, 2);
  210                 test("int16_array", B_FALSE, B_FALSE);
  211         }
  212         {
  213                 uint16_t val[2] = { 0, 1 };
  214                 fnvlist_add_uint16_array(nvl, key, val, 2);
  215                 test("uint16_array", B_FALSE, B_FALSE);
  216         }
  217         {
  218                 int32_t val[2] = { 0, 1 };
  219                 fnvlist_add_int32_array(nvl, key, val, 2);
  220                 test("int32_array", B_FALSE, B_FALSE);
  221         }
  222         {
  223                 uint32_t val[2] = { 0, 1 };
  224                 fnvlist_add_uint32_array(nvl, key, val, 2);
  225                 test("uint32_array", B_FALSE, B_FALSE);
  226         }
  227         {
  228                 int64_t val[2] = { 0, 1 };
  229                 fnvlist_add_int64_array(nvl, key, val, 2);
  230                 test("int64_array", B_TRUE, B_FALSE);
  231         }
  232         {
  233                 uint64_t val[2] = { 0, 1 };
  234                 fnvlist_add_uint64_array(nvl, key, val, 2);
  235                 test("uint64_array", B_FALSE, B_FALSE);
  236         }
  237         {
  238                 const char *val[2] = { "", "1" };
  239                 fnvlist_add_string_array(nvl, key, val, 2);
  240                 test("string_array", B_TRUE, B_FALSE);
  241         }
  242         {
  243                 nvlist_t *val[2];
  244                 val[0] = fnvlist_alloc();
  245                 fnvlist_add_string(val[0], "subkey", "subvalue");
  246                 val[1] = fnvlist_alloc();
  247                 fnvlist_add_string(val[1], "subkey2", "subvalue2");
  248                 fnvlist_add_nvlist_array(nvl, key, (const nvlist_t **)val, 2);
  249                 fnvlist_free(val[0]);
  250                 fnvlist_free(val[1]);
  251                 test("nvlist_array", B_FALSE, B_FALSE);
  252         }
  253         {
  254                 fnvlist_add_string(nvl, bigstring, "1");
  255                 test("large_key", B_TRUE, B_TRUE);
  256         }
  257         {
  258                 fnvlist_add_string(nvl, key, bigstring);
  259                 test("large_value", B_TRUE, B_TRUE);
  260         }
  261         {
  262                 for (int i = 0; i < 1024; i++) {
  263                         char buf[32];
  264                         (void) snprintf(buf, sizeof (buf), "key-%u", i);
  265                         fnvlist_add_int64(nvl, buf, i);
  266                 }
  267                 test("many_keys", B_TRUE, B_TRUE);
  268         }
  269 #ifndef __sparc__
  270         {
  271                 for (int i = 0; i < 10; i++) {
  272                         nvlist_t *newval = fnvlist_alloc();
  273                         fnvlist_add_nvlist(newval, "key", nvl);
  274                         fnvlist_free(nvl);
  275                         nvl = newval;
  276                 }
  277                 test("deeply_nested_pos", B_TRUE, B_TRUE);
  278         }
  279         {
  280                 for (int i = 0; i < 90; i++) {
  281                         nvlist_t *newval = fnvlist_alloc();
  282                         fnvlist_add_nvlist(newval, "key", nvl);
  283                         fnvlist_free(nvl);
  284                         nvl = newval;
  285                 }
  286                 test("deeply_nested_neg", B_FALSE, B_FALSE);
  287         }
  288 #endif
  289         free(bigstring);
  290         fnvlist_free(nvl);
  291 }
  292 
  293 int
  294 main(int argc, const char *argv[])
  295 {
  296         (void) libzfs_core_init();
  297 
  298         if (argc != 2) {
  299                 (void) printf("usage: %s <pool>\n",
  300                     argv[0]);
  301                 exit(2);
  302         }
  303         pool = argv[1];
  304 
  305         run_tests();
  306 
  307         libzfs_core_fini();
  308         return (unexpected_failures);
  309 }

Cache object: 84faf0f1a06cea3139f2604e97fad8a7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.