LCOV - code coverage report
Current view: top level - lib/util/tests - binsearch.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 62 65 95.4 %
Date: 2024-04-21 15:09:00 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Tests for binsearch.h macros.
       5             : 
       6             :    Copyright Catalyst IT 2016.
       7             : 
       8             :    Written by Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "lib/util/binsearch.h"
      26             : #include "lib/util/tsort.h"
      27             : #include "torture/torture.h"
      28             : #include "torture/local/proto.h"
      29             : 
      30          33 : static int int_cmp(int a, int b)
      31             : {
      32          33 :         return NUMERIC_CMP(a, b);
      33             : }
      34             : 
      35         132 : static int int_cmp_p(int a, int *b)
      36             : {
      37         132 :         int _b = *b;
      38         132 :         return NUMERIC_CMP(a, _b);
      39             : }
      40             : 
      41           1 : static bool test_binsearch_v(struct torture_context *tctx)
      42             : {
      43           1 :         int array[] = { -11, -7, 0, 1, 723, 1000000};
      44           1 :         int misses[] = { -121, 17, -10, 10, -1, -723, 1000002};
      45           1 :         int i;
      46           1 :         int *result = NULL;
      47             : 
      48           8 :         for (i = 0; i < ARRAY_SIZE(misses); i++) {
      49          26 :                 BINARY_ARRAY_SEARCH_V(array, ARRAY_SIZE(array),
      50             :                                       misses[i], int_cmp, result);
      51           7 :                 torture_comment(tctx, "looking for misses[%d] == %d\n", i, misses[i]);
      52           7 :                 torture_assert(tctx, result == NULL, "failed to miss");
      53             :         }
      54             : 
      55           7 :         for (i = 0; i < ARRAY_SIZE(array); i++) {
      56          14 :                 BINARY_ARRAY_SEARCH_V(array, ARRAY_SIZE(array),
      57             :                                       array[i], int_cmp, result);
      58           6 :                 torture_comment(tctx, "looking for array[%d] == %d, %p; got %p\n",
      59             :                                 i, array[i], &array[i], result);
      60           6 :                 torture_assert(tctx, result == &array[i],
      61             :                                "failed to find element");
      62             :         }
      63           0 :         return true;
      64             : }
      65             : 
      66           1 : static bool test_binsearch_gte(struct torture_context *tctx)
      67             : {
      68           1 :         int array[] = { -11, -7, -7, -7, -1, 0, 0, 1, 723, 723, 723,
      69             :                         724, 724, 10000};
      70           1 :         size_t a_len = ARRAY_SIZE(array);
      71           1 :         int targets[] = { -121, -8, -7, -6, 17, -10, 10, -1, 723,
      72             :                           724, 725, 10002, 10000, 0, -11, 1, 11};
      73           1 :         int i, j, target;
      74           1 :         int *result = NULL, *next = NULL;
      75             : 
      76          18 :         for (i = 0; i < ARRAY_SIZE(targets); i++) {
      77          17 :                 target = targets[i];
      78          17 :                 torture_comment(tctx, "looking for targets[%d] %d\n",
      79             :                                 i, target);
      80             : 
      81         100 :                 BINARY_ARRAY_SEARCH_GTE(array, a_len, target,
      82             :                                         int_cmp_p, result, next);
      83             : 
      84          17 :                 if (result == NULL) {
      85             :                         /* we think there is no exact match */
      86         135 :                         for (j = 0; j < a_len; j++) {
      87         126 :                                 if (target == array[j]) {
      88           0 :                                         torture_comment(tctx,
      89             :                                                         "failed to find %d\n",
      90             :                                                         targets[i]);
      91         126 :                                         torture_fail(tctx,
      92             :                                                      "result is wrongly NULL");
      93             :                                 }
      94             :                         }
      95           9 :                         if (next != NULL) {
      96           8 :                                 torture_assert(tctx, (next >= array &&
      97             :                                                       next < array + a_len),
      98             :                                                "next is out of bounds");
      99             : 
     100           8 :                                 torture_assert(tctx, *next > target,
     101             :                                                "next <= target");
     102           8 :                                 if (target <= array[0]) {
     103           1 :                                         torture_assert(tctx, next == array,
     104             :                                                        "search before start failed");
     105             :                                 }
     106           8 :                                 if (next != array) {
     107           7 :                                         torture_assert(tctx, next[-1] < target,
     108             :                                                        "next[-1] >= target");
     109             :                                 }
     110             :                         }
     111             :                         else {
     112           1 :                                 torture_assert(tctx, array[a_len - 1] < target,
     113             :                                                "next was not found\n");
     114             :                         }
     115             :                 } else {
     116             :                         /* we think we found an exact match */
     117           8 :                         torture_assert(tctx, *result == target,
     118             :                                        "result has wrong value");
     119             : 
     120           8 :                         torture_assert(tctx, (result >= array &&
     121             :                                               result < array + a_len),
     122             :                                        "result is out of bounds!");
     123             : 
     124           8 :                         torture_assert(tctx, next == NULL,
     125             :                                        "next should be NULL on exact match\n");
     126           8 :                         if (result != array) {
     127           7 :                                 torture_assert(tctx, result[-1] != target,
     128             :                                                "didn't find first target\n");
     129             :                         }
     130             :                 }
     131          17 :                 if (target >= array[a_len - 1]) {
     132          17 :                         torture_assert(tctx, next == NULL,
     133             :                                        "next is not NULL at array end\n");
     134             :                 }
     135             :         }
     136             : 
     137             :         /* try again, with result and next the same pointer */
     138          18 :         for (i = 0; i < ARRAY_SIZE(targets); i++) {
     139          17 :                 target = targets[i];
     140          17 :                 torture_comment(tctx, "looking for targets[%d] %d\n",
     141             :                                 i, target);
     142             : 
     143         100 :                 BINARY_ARRAY_SEARCH_GTE(array, a_len, target,
     144             :                                         int_cmp_p, result, result);
     145             : 
     146          17 :                 if (result == NULL) {
     147             :                         /* we think the target is greater than all elements */
     148           1 :                         torture_assert(tctx, array[a_len - 1] < target,
     149             :                                        "element >= target not found\n");
     150             :                 } else {
     151             :                         /* we think an element is >= target */
     152          16 :                         torture_assert(tctx, *result >= target,
     153             :                                        "result has wrong value");
     154             : 
     155          16 :                         torture_assert(tctx, (result >= array &&
     156             :                                               result < array + a_len),
     157             :                                        "result is out of bounds!");
     158             : 
     159          16 :                         if (result != array) {
     160          17 :                                 torture_assert(tctx, result[-1] < target,
     161             :                                                "didn't find first target\n");
     162             :                         }
     163             :                 }
     164             :         }
     165             : 
     166           0 :         return true;
     167             : }
     168             : 
     169        2354 : struct torture_suite *torture_local_util_binsearch(TALLOC_CTX *mem_ctx)
     170             : {
     171        2354 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "binsearch");
     172        2354 :         torture_suite_add_simple_test(suite, "binsearch_v", test_binsearch_v);
     173        2354 :         torture_suite_add_simple_test(suite, "binsearch_gte", test_binsearch_gte);
     174        2354 :         return suite;
     175             : }

Generated by: LCOV version 1.14