LCOV - code coverage report
Current view: top level - tests - refcount-tests.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 79 81 97.5 %
Date: 2012-11-29 Functions: 4 4 100.0 %
Branches: 12 14 85.7 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :    SSSD
       3                 :            : 
       4                 :            :    Reference counting tests.
       5                 :            : 
       6                 :            :    Authors:
       7                 :            :         Martin Nagy <mnagy@redhat.com>
       8                 :            : 
       9                 :            :    Copyright (C) Red Hat, Inc 2009
      10                 :            : 
      11                 :            :    This program is free software; you can redistribute it and/or modify
      12                 :            :    it under the terms of the GNU General Public License as published by
      13                 :            :    the Free Software Foundation; either version 3 of the License, or
      14                 :            :    (at your option) any later version.
      15                 :            : 
      16                 :            :    This program is distributed in the hope that it will be useful,
      17                 :            :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :    GNU General Public License for more details.
      20                 :            : 
      21                 :            :    You should have received a copy of the GNU General Public License
      22                 :            :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23                 :            : */
      24                 :            : 
      25                 :            : #include <stdlib.h>
      26                 :            : #include <check.h>
      27                 :            : #include <talloc.h>
      28                 :            : #include <tevent.h>
      29                 :            : #include <popt.h>
      30                 :            : 
      31                 :            : #include "tests/common.h"
      32                 :            : #include "util/util.h"
      33                 :            : 
      34                 :            : /* Interface under test */
      35                 :            : #include "util/refcount.h"
      36                 :            : 
      37                 :            : /* Fail the test if object 'obj' does not have 'num' references. */
      38                 :            : #define REF_ASSERT(obj, num) \
      39                 :            :     fail_unless(((obj)->DO_NOT_TOUCH_THIS_MEMBER_refcount == (num)), \
      40                 :            :                 "Reference count of " #obj " should be %d but is %d", \
      41                 :            :                 (num), (obj)->DO_NOT_TOUCH_THIS_MEMBER_refcount)
      42                 :            : 
      43                 :            : #define FILLER_SIZE 32
      44                 :            : 
      45                 :            : struct foo {
      46                 :            :     REFCOUNT_COMMON;
      47                 :            :     char a[FILLER_SIZE];
      48                 :            :     char b[FILLER_SIZE];
      49                 :            : };
      50                 :            : 
      51                 :            : struct bar {
      52                 :            :     char a[FILLER_SIZE];
      53                 :            :     REFCOUNT_COMMON;
      54                 :            :     char b[FILLER_SIZE];
      55                 :            : };
      56                 :            : 
      57                 :            : struct baz {
      58                 :            :     char a[FILLER_SIZE];
      59                 :            :     char b[FILLER_SIZE];
      60                 :            :     REFCOUNT_COMMON;
      61                 :            : };
      62                 :            : 
      63                 :            : #define SET_FILLER(target) do { \
      64                 :            :     memset((target)->a, 'a', FILLER_SIZE); \
      65                 :            :     memset((target)->b, 'b', FILLER_SIZE); \
      66                 :            : } while (0)
      67                 :            : 
      68                 :            : #define CHECK_FILLER(target) do { \
      69                 :            :     int _counter; \
      70                 :            :     for (_counter = 0; _counter < FILLER_SIZE; _counter++) { \
      71                 :            :         fail_unless((target)->a[_counter] == 'a', "Corrupted memory in "  \
      72                 :            :                     #target "->a[%d] of size %d", _counter, FILLER_SIZE); \
      73                 :            :         fail_unless((target)->b[_counter] == 'b', "Corrupted memory in "  \
      74                 :            :                     #target "->b[%d] of size %d", _counter, FILLER_SIZE); \
      75                 :            :     } \
      76                 :            : } while (0)
      77                 :            : 
      78                 :            : struct container {
      79                 :            :     struct foo *foo;
      80                 :            :     struct bar *bar;
      81                 :            :     struct baz *baz;
      82                 :            : };
      83                 :            : 
      84                 :            : static struct container *global;
      85                 :            : 
      86                 :          1 : START_TEST(test_refcount_basic)
      87                 :            : {
      88                 :            :     struct container *containers;
      89                 :            :     int i;
      90                 :            : 
      91                 :            :     /* First allocate our global storage place. */
      92                 :          1 :     global = talloc(NULL, struct container);
      93                 :          1 :     fail_if(global == NULL);
      94                 :            : 
      95                 :            :     /* Allocate foo. */
      96                 :          1 :     global->foo = rc_alloc(global, struct foo);
      97                 :          1 :     fail_if(global->foo == NULL);
      98                 :          1 :     SET_FILLER(global->foo);
      99                 :          1 :     REF_ASSERT(global->foo, 1);
     100                 :            : 
     101                 :            :     /* Allocate bar. */
     102                 :          1 :     global->bar = rc_alloc(global, struct bar);
     103                 :          1 :     fail_if(global->bar == NULL);
     104                 :          1 :     SET_FILLER(global->bar);
     105                 :          1 :     REF_ASSERT(global->bar, 1);
     106                 :            : 
     107                 :            :     /* Allocate baz. */
     108                 :          1 :     global->baz = rc_alloc(global, struct baz);
     109                 :          1 :     fail_if(global->baz == NULL);
     110                 :          1 :     SET_FILLER(global->baz);
     111                 :          1 :     REF_ASSERT(global->baz, 1);
     112                 :            : 
     113                 :            :     /* Try multiple attaches. */
     114                 :          1 :     containers = talloc_array(NULL, struct container, 100);
     115                 :          1 :     fail_if(containers == NULL);
     116         [ +  + ]:        101 :     for (i = 0; i < 100; i++) {
     117                 :        100 :         containers[i].foo = rc_reference(containers, struct foo, global->foo);
     118                 :        100 :         containers[i].bar = rc_reference(containers, struct bar, global->bar);
     119                 :        100 :         containers[i].baz = rc_reference(containers, struct baz, global->baz);
     120                 :        100 :         REF_ASSERT(containers[i].foo, i + 2);
     121                 :        100 :         REF_ASSERT(global->foo, i + 2);
     122                 :        100 :         REF_ASSERT(containers[i].bar, i + 2);
     123                 :        100 :         REF_ASSERT(global->bar, i + 2);
     124                 :        100 :         REF_ASSERT(containers[i].baz, i + 2);
     125                 :        100 :         REF_ASSERT(global->baz, i + 2);
     126                 :            :     }
     127                 :          1 :     talloc_free(containers);
     128                 :            : 
     129         [ +  + ]:         33 :     CHECK_FILLER(global->foo);
     130         [ +  + ]:         33 :     CHECK_FILLER(global->bar);
     131         [ +  + ]:         33 :     CHECK_FILLER(global->baz);
     132                 :            : 
     133                 :          1 :     REF_ASSERT(global->foo, 1);
     134                 :          1 :     REF_ASSERT(global->bar, 1);
     135                 :          1 :     REF_ASSERT(global->baz, 1);
     136                 :            : 
     137                 :          1 :     talloc_free(global);
     138                 :            : }
     139                 :          1 : END_TEST
     140                 :            : 
     141                 :          1 : START_TEST(test_refcount_swap)
     142                 :            : {
     143                 :            :     void *tmp_ctx;
     144                 :            :     struct container *container1;
     145                 :            :     struct container *container2;
     146                 :            : 
     147                 :          1 :     tmp_ctx = talloc_new(NULL);
     148                 :            : 
     149                 :          1 :     check_leaks_push(tmp_ctx);
     150                 :            : 
     151                 :          1 :     container1 = talloc(tmp_ctx, struct container);
     152                 :          1 :     container2 = talloc(tmp_ctx, struct container);
     153                 :            : 
     154                 :            :     /* Allocate. */
     155                 :          1 :     container1->foo = rc_alloc(container1, struct foo);
     156                 :          1 :     fail_if(container1->foo == NULL);
     157                 :          1 :     SET_FILLER(container1->foo);
     158                 :            : 
     159                 :            :     /* Reference. */
     160                 :          1 :     container2->foo = rc_reference(container2, struct foo, container1->foo);
     161                 :          1 :     fail_if(container2->foo == NULL);
     162                 :            : 
     163                 :            :     /* Make sure everything is as it should be. */
     164                 :          1 :     fail_unless(container1->foo == container2->foo);
     165                 :          1 :     REF_ASSERT(container1->foo, 2);
     166                 :            : 
     167                 :            :     /* Free in reverse order. */
     168                 :          1 :     talloc_free(container1);
     169                 :          1 :     REF_ASSERT(container2->foo, 1);
     170         [ +  + ]:         33 :     CHECK_FILLER(container2->foo);
     171                 :          1 :     talloc_free(container2);
     172                 :            : 
     173                 :          1 :     check_leaks_pop(tmp_ctx);
     174                 :          1 :     talloc_free(tmp_ctx);
     175                 :            : }
     176                 :          1 : END_TEST
     177                 :            : 
     178                 :          3 : Suite *create_suite(void)
     179                 :            : {
     180                 :          3 :     Suite *s = suite_create("refcount");
     181                 :            : 
     182                 :          3 :     TCase *tc = tcase_create("REFCOUNT Tests");
     183                 :            : 
     184                 :            :     /* Do some testing */
     185                 :          3 :     tcase_add_checked_fixture(tc, leak_check_setup, leak_check_teardown);
     186                 :          3 :     tcase_add_test(tc, test_refcount_basic);
     187                 :          3 :     tcase_add_test(tc, test_refcount_swap);
     188                 :            : 
     189                 :            :     /* Add all test cases to the test suite */
     190                 :          3 :     suite_add_tcase(s, tc);
     191                 :            : 
     192                 :          3 :     return s;
     193                 :            : }
     194                 :            : 
     195                 :          3 : int main(int argc, const char *argv[])
     196                 :            : {
     197                 :            :     int opt;
     198                 :            :     poptContext pc;
     199                 :            :     int failure_count;
     200                 :            :     Suite *suite;
     201                 :            :     SRunner *sr;
     202                 :          3 :     int debug = 0;
     203                 :            : 
     204                 :          3 :     struct poptOption long_options[] = {
     205                 :            :         POPT_AUTOHELP
     206                 :            :         { "debug-level", 'd', POPT_ARG_INT, &debug, 0, "Set debug level", NULL },
     207                 :            :         POPT_TABLEEND
     208                 :            :     };
     209                 :            : 
     210                 :            :     /* Set debug level to invalid value so we can deside if -d 0 was used. */
     211                 :          3 :     debug_level = SSSDBG_INVALID;
     212                 :            : 
     213                 :          3 :     pc = poptGetContext(argv[0], argc, argv, long_options, 0);
     214         [ -  + ]:          3 :     while((opt = poptGetNextOpt(pc)) != -1) {
     215                 :            :         switch(opt) {
     216                 :            :         default:
     217                 :          0 :             fprintf(stderr, "\nInvalid option %s: %s\n\n",
     218                 :            :                     poptBadOption(pc, 0), poptStrerror(opt));
     219                 :          0 :             poptPrintUsage(pc, stderr, 0);
     220                 :            :             return 1;
     221                 :            :         }
     222                 :            :     }
     223                 :          3 :     poptFreeContext(pc);
     224                 :            : 
     225         [ +  - ]:          3 :     DEBUG_INIT(debug);
     226                 :            : 
     227                 :          3 :     tests_set_cwd();
     228                 :            : 
     229                 :          3 :     suite = create_suite();
     230                 :          3 :     sr = srunner_create(suite);
     231                 :          3 :     srunner_set_fork_status(sr, CK_FORK);
     232                 :            :     /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
     233                 :          3 :     srunner_run_all(sr, CK_ENV);
     234                 :          1 :     failure_count = srunner_ntests_failed(sr);
     235                 :          1 :     srunner_free(sr);
     236                 :          1 :     return (failure_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
     237                 :            : }
     238                 :            : 

Generated by: LCOV version 1.9