LCOV - code coverage report
Current view: top level - lib/util/tests - strlist.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 203 225 90.2 %
Date: 2024-04-21 15:09:00 Functions: 19 19 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    util_strlist testing
       5             : 
       6             :    Copyright (C) Jelmer Vernooij 2005
       7             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
       8             :    
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             :    
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             :    
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "torture/torture.h"
      25             : #include "torture/local/proto.h"
      26             : #include "param/param.h"
      27             : 
      28             : struct test_list_element {
      29             :         const char *list_as_string;
      30             :         const char *separators;
      31             :         const char *list[5];
      32             : };
      33             : 
      34             : const struct test_list_element test_lists_strings[] = {
      35             :         {
      36             :                 .list_as_string = "",
      37             :                 .list = { NULL }
      38             :         },
      39             :         {
      40             :                 .list_as_string = "foo",
      41             :                 .list = { "foo", NULL }
      42             :         },
      43             :         {
      44             :                 .list_as_string = "foo bar",
      45             :                 .list = { "foo", "bar", NULL }
      46             :         },
      47             :         {
      48             :                 .list_as_string = "foo bar",
      49             :                 .list = { "foo bar", NULL },
      50             :                 .separators = ";"
      51             :         },
      52             :         {
      53             :                 .list_as_string = "\"foo bar\"",
      54             :                 .list = { "\"foo", "bar\"", NULL }
      55             :         },
      56             :         {
      57             :                 .list_as_string = "\"foo bar\",comma\ttab",
      58             :                 .list = { "\"foo", "bar\"", "comma", "tab", NULL }
      59             :         },
      60             :         {
      61             :                 .list_as_string = "\"foo bar\",comma;semicolon",
      62             :                 .list = { "\"foo bar\",comma", "semicolon", NULL },
      63             :                 .separators = ";"
      64             :         }
      65             : };
      66             : 
      67             : const struct test_list_element test_lists_shell_strings[] = {
      68             :         {
      69             :                 .list_as_string = "",
      70             :                 .list = { NULL }
      71             :         },
      72             :         {
      73             :                 .list_as_string = "foo",
      74             :                 .list = { "foo", NULL }
      75             :         },
      76             :         {
      77             :                 .list_as_string = "foo bar",
      78             :                 .list = { "foo", "bar", NULL }
      79             :         },
      80             :         {
      81             :                 .list_as_string = "foo bar",
      82             :                 .list = { "foo bar", NULL },
      83             :                 .separators = ";"
      84             :         },
      85             :         {
      86             :                 .list_as_string = "\"foo bar\"",
      87             :                 .list = { "foo bar", NULL }
      88             :         },
      89             :         {
      90             :                 .list_as_string = "foo bar \"bla \"",
      91             :                 .list = { "foo", "bar", "bla ", NULL }
      92             :         },
      93             :         {
      94             :                 .list_as_string = "foo \"\" bla",
      95             :                 .list = { "foo", "", "bla", NULL },
      96             :         },
      97             :         {
      98             :                 .list_as_string = "bla \"\"\"\" blie",
      99             :                 .list = { "bla", "", "", "blie", NULL },
     100             :         }
     101             : };
     102             : 
     103           8 : static bool test_lists_shell(struct torture_context *tctx, const void *data)
     104             : {
     105           8 :         const struct test_list_element *element = data;
     106             : 
     107           8 :         char **ret1, **ret2, *tmp;
     108           8 :         bool match = true;
     109           8 :         TALLOC_CTX *mem_ctx = tctx;
     110             : 
     111           8 :         ret1 = str_list_make_shell(mem_ctx, element->list_as_string, element->separators);
     112             :         
     113           8 :         torture_assert(tctx, ret1, "str_list_make_shell() must not return NULL");
     114           8 :         tmp = str_list_join_shell(mem_ctx, discard_const_p(const char *, ret1),
     115           8 :                                   element->separators ? *element->separators : ' ');
     116           8 :         ret2 = str_list_make_shell(mem_ctx, tmp, element->separators);
     117             : 
     118           8 :         if ((ret1 == NULL || ret2 == NULL) && ret2 != ret1) {
     119           0 :                 match = false;
     120             :         } else {
     121             :                 int j;
     122          23 :                 for (j = 0; ret1[j] && ret2[j]; j++) {
     123          15 :                         if (strcmp(ret1[j], ret2[j]) != 0) {
     124           0 :                                 match = false;
     125           0 :                                 break;
     126             :                         }
     127             :                 }
     128             : 
     129           8 :                 if (ret1[j] || ret2[j])
     130           0 :                         match = false;
     131             :         }
     132             : 
     133           8 :         torture_assert(tctx, match, talloc_asprintf(tctx, 
     134             :                 "str_list_{make,join}_shell: Error double parsing, first run:\n%s\nSecond run: \n%s", element->list_as_string, tmp));
     135           8 :         torture_assert(tctx, str_list_equal((const char * const *) ret1,
     136             :                                             element->list),
     137             :                        talloc_asprintf(tctx, 
     138             :                                        "str_list_make_shell(%s) failed to create correct list", 
     139             :                                        element->list_as_string));
     140             : 
     141           0 :         return true;
     142             : }
     143             : 
     144           7 : static bool test_list_make(struct torture_context *tctx, const void *data)
     145             : {
     146           7 :         const struct test_list_element *element = data;
     147             : 
     148           7 :         char **result;
     149           7 :         result = str_list_make(tctx, element->list_as_string, element->separators);
     150           7 :         torture_assert(tctx, result, "str_list_make() must not return NULL");
     151           7 :         torture_assert(tctx, str_list_equal((const char * const *) result,
     152             :                                             element->list),
     153             :                        talloc_asprintf(tctx, 
     154             :                                        "str_list_make(%s) failed to create correct list", 
     155             :                                        element->list_as_string));
     156           0 :         return true;
     157             : }
     158             : 
     159           1 : static bool test_list_copy(struct torture_context *tctx)
     160             : {
     161           1 :         const char **result;
     162           1 :         const char *list[] = { "foo", "bar", NULL };
     163           1 :         const char *empty_list[] = { NULL };
     164           1 :         const char **null_list = NULL;
     165           1 :         char **l;
     166             : 
     167           1 :         l = str_list_copy(tctx, list);
     168           1 :         result = discard_const_p(const char *, l);
     169           1 :         torture_assert_int_equal(tctx, str_list_length(result), 2, "list length");
     170           1 :         torture_assert_str_equal(tctx, result[0], "foo", "element 0");
     171           1 :         torture_assert_str_equal(tctx, result[1], "bar", "element 1");
     172           1 :         torture_assert_str_equal(tctx, result[2], NULL, "element 2");
     173             : 
     174           1 :         l = str_list_copy(tctx, empty_list);
     175           1 :         result = discard_const_p(const char *, l);
     176           1 :         torture_assert_int_equal(tctx, str_list_length(result), 0, "list length");
     177           1 :         torture_assert_str_equal(tctx, result[0], NULL, "element 0");
     178             : 
     179           1 :         l = str_list_copy(tctx, null_list);
     180           1 :         result = discard_const_p(const char *, l);
     181           1 :         torture_assert(tctx, result == NULL, "result NULL");
     182             :         
     183           0 :         return true;
     184             : }
     185             : 
     186           1 : static bool test_list_make_empty(struct torture_context *tctx)
     187             : {
     188           1 :         char **result;
     189             : 
     190           1 :         result = str_list_make_empty(tctx);
     191           1 :         torture_assert(tctx, result, "str_list_make_empty() must not return NULL");
     192           1 :         torture_assert(tctx, result[0] == NULL, "first element in str_list_make_empty() result must be NULL");
     193             : 
     194           1 :         result = str_list_make(tctx, NULL, NULL);
     195           1 :         torture_assert(tctx, result, "str_list_make() must not return NULL");
     196           1 :         torture_assert(tctx, result[0] == NULL, "first element in str_list_make(ctx, NULL, NULL) result must be NULL");
     197             :         
     198           1 :         result = str_list_make(tctx, "", NULL);
     199           1 :         torture_assert(tctx, result, "str_list_make() must not return NULL");
     200           1 :         torture_assert(tctx, result[0] == NULL, "first element in str_list_make(ctx, "", NULL) result must be NULL");
     201             :         
     202           0 :         return true;
     203             : }
     204             : 
     205           1 : static bool test_list_make_single(struct torture_context *tctx)
     206             : {
     207           1 :         char **result;
     208             : 
     209           1 :         result = str_list_make_single(tctx, "foo");
     210             : 
     211           1 :         torture_assert(tctx, result, "str_list_make_single() must not return NULL");
     212           1 :         torture_assert_str_equal(tctx, result[0], "foo", "element 0");
     213           1 :         torture_assert(tctx, result[1] == NULL, "second element in result must be NULL");
     214             :         
     215           0 :         return true;
     216             : }
     217             : 
     218           1 : static bool test_list_copy_const(struct torture_context *tctx)
     219             : {
     220           1 :         const char **result;
     221           1 :         const char *list[] = {
     222             :                 "element_0", 
     223             :                 "element_1",
     224             :                 "element_2",
     225             :                 "element_3",
     226             :                 NULL
     227             :         };
     228           1 :         result = str_list_copy_const(tctx, list);
     229           1 :         torture_assert(tctx, result, "str_list_copy() must not return NULL");
     230           1 :         torture_assert(tctx, str_list_equal(result, list), 
     231             :                        "str_list_copy() failed");
     232             : 
     233           0 :         return true;
     234             : }
     235             : 
     236           1 : static bool test_list_length(struct torture_context *tctx)
     237             : {
     238           1 :         const char *list[] = {
     239             :                 "element_0", 
     240             :                 "element_1",
     241             :                 "element_2",
     242             :                 "element_3",
     243             :                 NULL
     244             :         };
     245           1 :         const char *list2[] = {
     246             :                 NULL
     247             :         };
     248           1 :         torture_assert_int_equal(tctx, str_list_length(list), 4, 
     249             :                        "str_list_length() failed");
     250             : 
     251           1 :         torture_assert_int_equal(tctx, str_list_length(list2), 0, 
     252             :                        "str_list_length() failed");
     253             : 
     254           1 :         torture_assert_int_equal(tctx, str_list_length(NULL), 0, 
     255             :                        "str_list_length() failed");
     256             : 
     257           0 :         return true;
     258             : }
     259             : 
     260           1 : static bool test_list_add(struct torture_context *tctx)
     261             : {
     262           1 :         const char **result, **result2;
     263           1 :         const char *list[] = {
     264             :                 "element_0", 
     265             :                 "element_1",
     266             :                 "element_2",
     267             :                 "element_3",
     268             :                 NULL
     269             :         };
     270           1 :         char **l;
     271             : 
     272           1 :         l = str_list_make(tctx, "element_0, element_1, element_2", NULL);
     273           1 :         result = discard_const_p(const char *, l);
     274           1 :         torture_assert(tctx, result, "str_list_make() must not return NULL");
     275           1 :         result2 = str_list_add(result, "element_3");
     276           1 :         torture_assert(tctx, result2, "str_list_add() must not return NULL");
     277           1 :         torture_assert(tctx, str_list_equal(result2, list), 
     278             :                        "str_list_add() failed");
     279             : 
     280           0 :         return true;
     281             : }
     282             : 
     283           1 : static bool test_list_add_const(struct torture_context *tctx)
     284             : {
     285           1 :         const char **result, **result2;
     286           1 :         const char *list[] = {
     287             :                 "element_0", 
     288             :                 "element_1",
     289             :                 "element_2",
     290             :                 "element_3",
     291             :                 NULL
     292             :         };
     293           1 :         char **l;
     294             : 
     295           1 :         l = str_list_make(tctx, "element_0, element_1, element_2", NULL);
     296           1 :         result = discard_const_p(const char *, l);
     297           1 :         torture_assert(tctx, result, "str_list_make() must not return NULL");
     298           1 :         result2 = str_list_add_const(result, "element_3");
     299           1 :         torture_assert(tctx, result2, "str_list_add_const() must not return NULL");
     300           1 :         torture_assert(tctx, str_list_equal(result2, list), 
     301             :                        "str_list_add() failed");
     302             : 
     303           0 :         return true;
     304             : }
     305             : 
     306           1 : static bool test_list_remove(struct torture_context *tctx)
     307             : {
     308           1 :         const char **result;
     309           1 :         const char *list[] = {
     310             :                 "element_0", 
     311             :                 "element_1",
     312             :                 "element_3",
     313             :                 NULL
     314             :         };
     315           1 :         char **l;
     316             : 
     317           1 :         l = str_list_make(tctx, "element_0, element_1, element_2, element_3", NULL);
     318           1 :         result = discard_const_p(const char *, l);
     319           1 :         torture_assert(tctx, result, "str_list_make() must not return NULL");
     320           1 :         str_list_remove(result, "element_2");
     321           1 :         torture_assert(tctx, str_list_equal(result, list), 
     322             :                        "str_list_remove() failed");
     323             : 
     324           0 :         return true;
     325             : }
     326             : 
     327           1 : static bool test_list_check(struct torture_context *tctx)
     328             : {
     329           1 :         const char *list[] = {
     330             :                 "element_0", 
     331             :                 "element_1",
     332             :                 "element_2",
     333             :                 NULL
     334             :         };
     335           1 :         torture_assert(tctx, str_list_check(list, "element_1"), 
     336             :                        "str_list_check() failed");
     337             : 
     338           0 :         return true;
     339             : }
     340             : 
     341           1 : static bool test_list_check_ci(struct torture_context *tctx)
     342             : {
     343           1 :         const char *list[] = {
     344             :                 "element_0", 
     345             :                 "element_1",
     346             :                 "element_2",
     347             :                 NULL
     348             :         };
     349           1 :         torture_assert(tctx, str_list_check_ci(list, "ELEMENT_1"), 
     350             :                        "str_list_check_ci() failed");
     351             : 
     352           0 :         return true;
     353             : }
     354             : 
     355           1 : static bool test_list_unique(struct torture_context *tctx)
     356             : {
     357           1 :         const char **result;
     358           1 :         const char *list[] = {
     359             :                 "element_0", 
     360             :                 "element_1",
     361             :                 "element_2",
     362             :                 NULL
     363             :         };
     364           1 :         const char *list_dup[] = {
     365             :                 "element_0", 
     366             :                 "element_1",
     367             :                 "element_2",
     368             :                 "element_0", 
     369             :                 "element_2",
     370             :                 "element_1",
     371             :                 "element_1",
     372             :                 "element_2",
     373             :                 NULL
     374             :         };
     375           1 :         char **l;
     376             : 
     377           1 :         l = str_list_copy(tctx, list_dup);
     378           1 :         result = discard_const_p(const char *, l);
     379             :         /* We must copy the list, as str_list_unique does a talloc_realloc() on it's parameter */
     380           1 :         result = str_list_unique(result);
     381           1 :         torture_assert(tctx, result, "str_list_unique() must not return NULL");
     382             :         
     383           1 :         torture_assert(tctx, str_list_equal(list, result), 
     384             :                        "str_list_unique() failed");
     385             : 
     386           0 :         return true;
     387             : }
     388             : 
     389           1 : static bool test_list_unique_2(struct torture_context *tctx)
     390             : {
     391           1 :         int i;
     392           1 :         int count, num_dups;
     393           1 :         const char **result;
     394           1 :         char **l1 = str_list_make_empty(tctx);
     395           1 :         char **l2 = str_list_make_empty(tctx);
     396           1 :         const char **list = discard_const_p(const char *, l1);
     397           1 :         const char **list_dup = discard_const_p(const char *, l2);
     398           1 :         char **l;
     399             : 
     400           1 :         count = lpcfg_parm_int(tctx->lp_ctx, NULL, "list_unique", "count", 9);
     401           1 :         num_dups = lpcfg_parm_int(tctx->lp_ctx, NULL, "list_unique", "dups", 7);
     402           1 :         torture_comment(tctx, "test_list_unique_2() with %d elements and %d dups\n", count, num_dups);
     403             : 
     404          11 :         for (i = 0; i < count; i++) {
     405           9 :                 list = str_list_add_const(list, (const char *)talloc_asprintf(tctx, "element_%03d", i));
     406             :         }
     407             : 
     408           8 :         for (i = 0; i < num_dups; i++) {
     409           7 :                 list_dup = str_list_append(list_dup, list);
     410             :         }
     411             : 
     412           1 :         l = str_list_copy(tctx, list_dup);
     413           1 :         result = discard_const_p(const char *, l);
     414             :         /* We must copy the list, as str_list_unique does a talloc_realloc() on it's parameter */
     415           1 :         result = str_list_unique(result);
     416           1 :         torture_assert(tctx, result, "str_list_unique() must not return NULL");
     417             : 
     418           1 :         torture_assert(tctx, str_list_equal(list, result),
     419             :                        "str_list_unique() failed");
     420             : 
     421           0 :         return true;
     422             : }
     423             : 
     424           1 : static bool test_list_append(struct torture_context *tctx)
     425             : {
     426           1 :         const char **result;
     427           1 :         const char *list[] = {
     428             :                 "element_0", 
     429             :                 "element_1",
     430             :                 "element_2",
     431             :                 NULL
     432             :         };
     433           1 :         const char *list2[] = {
     434             :                 "element_3", 
     435             :                 "element_4",
     436             :                 "element_5",
     437             :                 NULL
     438             :         };
     439           1 :         const char *list_combined[] = {
     440             :                 "element_0", 
     441             :                 "element_1",
     442             :                 "element_2",
     443             :                 "element_3", 
     444             :                 "element_4",
     445             :                 "element_5",
     446             :                 NULL
     447             :         };
     448           1 :         char **l;
     449           1 :         l = str_list_copy(tctx, list);
     450           1 :         result = discard_const_p(const char *, l);
     451           1 :         torture_assert(tctx, result, "str_list_copy() must not return NULL");
     452           1 :         result = str_list_append(result, list2);
     453           1 :         torture_assert(tctx, result, "str_list_append() must not return NULL");
     454           1 :         torture_assert(tctx, str_list_equal(list_combined, result), 
     455             :                        "str_list_unique() failed");
     456             : 
     457           0 :         return true;
     458             : }
     459             : 
     460           1 : static bool test_list_append_const(struct torture_context *tctx)
     461             : {
     462           1 :         const char **result;
     463           1 :         const char *list[] = {
     464             :                 "element_0", 
     465             :                 "element_1",
     466             :                 "element_2",
     467             :                 NULL
     468             :         };
     469           1 :         const char *list2[] = {
     470             :                 "element_3", 
     471             :                 "element_4",
     472             :                 "element_5",
     473             :                 NULL
     474             :         };
     475           1 :         const char *list_combined[] = {
     476             :                 "element_0", 
     477             :                 "element_1",
     478             :                 "element_2",
     479             :                 "element_3", 
     480             :                 "element_4",
     481             :                 "element_5",
     482             :                 NULL
     483             :         };
     484           1 :         char **l;
     485           1 :         l = str_list_copy(tctx, list);
     486           1 :         result = discard_const_p(const char *, l);
     487           1 :         torture_assert(tctx, result, "str_list_copy() must not return NULL");
     488           1 :         result = str_list_append_const(result, list2);
     489           1 :         torture_assert(tctx, result, "str_list_append_const() must not return NULL");
     490           1 :         torture_assert(tctx, str_list_equal(list_combined, result), 
     491             :                        "str_list_unique() failed");
     492             : 
     493           0 :         return true;
     494             : }
     495             : 
     496           1 : static bool test_list_add_printf_NULL(struct torture_context *tctx)
     497             : {
     498           1 :         char **list = NULL;
     499           1 :         str_list_add_printf(&list, "x=%d", 1);
     500           1 :         torture_assert(tctx, list==NULL, "str_list_add_printf must keep NULL");
     501           0 :         return true;
     502             : }
     503             : 
     504           1 : static bool test_list_add_printf(struct torture_context *tctx)
     505             : {
     506           1 :         const char *list2[] = { "foo", "bar=baz", NULL };
     507           1 :         char **list = str_list_make_empty(tctx);
     508           1 :         str_list_add_printf(&list, "foo");
     509           1 :         str_list_add_printf(&list, "bar=%s", "baz");
     510           1 :         torture_assert(
     511             :                 tctx,
     512             :                 str_list_equal((const char * const *)list, list2),
     513             :                 "str_list_add_printf failed");
     514           1 :         TALLOC_FREE(list);
     515           0 :         return true;
     516             : }
     517             : 
     518        2354 : struct torture_suite *torture_local_util_strlist(TALLOC_CTX *mem_ctx)
     519             : {
     520        2354 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "strlist");
     521         125 :         size_t i;
     522             : 
     523       21311 :         for (i = 0; i < ARRAY_SIZE(test_lists_shell_strings); i++) {
     524        1000 :                 char *name;
     525       19832 :                 name = talloc_asprintf(suite, "lists_shell(%s)",
     526       18832 :                                                            test_lists_shell_strings[i].list_as_string);
     527       18832 :                 torture_suite_add_simple_tcase_const(suite, name,
     528       18832 :                         test_lists_shell,  &test_lists_shell_strings[i]);
     529             :         }
     530             : 
     531       18832 :         for (i = 0; i < ARRAY_SIZE(test_lists_strings); i++) {
     532         875 :                 char *name;
     533       17353 :                 name = talloc_asprintf(suite, "list_make(%s)",
     534       16478 :                                                            test_lists_strings[i].list_as_string);
     535       16478 :                 torture_suite_add_simple_tcase_const(suite, name,
     536       16478 :                         test_list_make, &test_lists_strings[i]);
     537             :         }
     538             : 
     539        2354 :         torture_suite_add_simple_test(suite, "list_copy", test_list_copy);
     540        2354 :         torture_suite_add_simple_test(suite, "make_empty", test_list_make_empty);
     541        2354 :         torture_suite_add_simple_test(suite, "make_single", test_list_make_single);
     542        2354 :         torture_suite_add_simple_test(suite, "list_copy_const", test_list_copy_const);
     543        2354 :         torture_suite_add_simple_test(suite, "list_length", test_list_length);
     544        2354 :         torture_suite_add_simple_test(suite, "list_add", test_list_add);
     545        2354 :         torture_suite_add_simple_test(suite, "list_add_const", test_list_add_const);
     546        2354 :         torture_suite_add_simple_test(suite, "list_remove", test_list_remove);
     547        2354 :         torture_suite_add_simple_test(suite, "list_check", test_list_check);
     548        2354 :         torture_suite_add_simple_test(suite, "list_check_ci", test_list_check_ci);
     549        2354 :         torture_suite_add_simple_test(suite, "list_unique", test_list_unique);
     550        2354 :         torture_suite_add_simple_test(suite, "list_unique_2", test_list_unique_2);
     551        2354 :         torture_suite_add_simple_test(suite, "list_append", test_list_append);
     552        2354 :         torture_suite_add_simple_test(suite, "list_append_const", test_list_append_const);
     553        2354 :         torture_suite_add_simple_test(
     554             :                 suite, "list_add_printf_NULL", test_list_add_printf_NULL);
     555        2354 :         torture_suite_add_simple_test(
     556             :                 suite, "list_add_printf", test_list_add_printf);
     557        2354 :         return suite;
     558             : }

Generated by: LCOV version 1.14