LCOV - code coverage report
Current view: top level - tests/cmocka - test_data_provider_be.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 86 91 94.5 %
Date: 2015-10-19 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /*
       2             :     Copyright (C) 2015 Red Hat
       3             : 
       4             :     This program is free software; you can redistribute it and/or modify
       5             :     it under the terms of the GNU General Public License as published by
       6             :     the Free Software Foundation; either version 3 of the License, or
       7             :     (at your option) any later version.
       8             : 
       9             :     This program is distributed in the hope that it will be useful,
      10             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :     GNU General Public License for more details.
      13             : 
      14             :     You should have received a copy of the GNU General Public License
      15             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      16             : */
      17             : 
      18             : #include <talloc.h>
      19             : #include <tevent.h>
      20             : #include <errno.h>
      21             : #include <popt.h>
      22             : #include <time.h>
      23             : 
      24             : #include "providers/dp_backend.h"
      25             : #include "tests/cmocka/common_mock.h"
      26             : #include "tests/cmocka/common_mock_be.h"
      27             : #include "tests/common.h"
      28             : 
      29             : #define TESTS_PATH "tests_dp_be"
      30             : #define TEST_CONF_DB "test_dp_be_conf.ldb"
      31             : #define TEST_DOM_NAME "dp_be_test"
      32             : #define TEST_ID_PROVIDER "ldap"
      33             : 
      34             : #define OFFLINE_TIMEOUT 2
      35             : #define AS_STR(param) (#param)
      36             : 
      37             : static TALLOC_CTX *global_mock_context = NULL;
      38             : static bool global_timer_added;
      39             : 
      40             : struct tevent_timer *__real__tevent_add_timer(struct tevent_context *ev,
      41             :                                               TALLOC_CTX *mem_ctx,
      42             :                                               struct timeval next_event,
      43             :                                               tevent_timer_handler_t handler,
      44             :                                               void *private_data,
      45             :                                               const char *handler_name,
      46             :                                               const char *location);
      47             : 
      48           2 : struct tevent_timer *__wrap__tevent_add_timer(struct tevent_context *ev,
      49             :                                               TALLOC_CTX *mem_ctx,
      50             :                                               struct timeval next_event,
      51             :                                               tevent_timer_handler_t handler,
      52             :                                               void *private_data,
      53             :                                               const char *handler_name,
      54             :                                               const char *location)
      55             : {
      56           2 :     global_timer_added = true;
      57             : 
      58           2 :     return __real__tevent_add_timer(ev, mem_ctx, next_event,
      59             :                                     handler, private_data, handler_name,
      60             :                                     location);
      61             : }
      62             : 
      63             : 
      64             : struct test_ctx {
      65             :     struct sss_test_ctx *tctx;
      66             :     struct be_ctx *be_ctx;
      67             : };
      68             : 
      69           3 : static int test_setup(void **state)
      70             : {
      71           3 :     struct test_ctx *test_ctx = NULL;
      72           3 :     struct sss_test_conf_param params[] = {
      73             :         { "offline_timeout", AS_STR(OFFLINE_TIMEOUT) },
      74             :         { NULL, NULL },             /* Sentinel */
      75             :     };
      76             : 
      77           3 :     assert_true(leak_check_setup());
      78           3 :     global_mock_context = talloc_new(global_talloc_context);
      79           3 :     assert_non_null(global_mock_context);
      80             : 
      81           3 :     test_ctx = talloc_zero(global_talloc_context, struct test_ctx);
      82           3 :     assert_non_null(test_ctx);
      83             : 
      84           3 :     test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH,
      85             :                                          TEST_CONF_DB, TEST_DOM_NAME,
      86             :                                          TEST_ID_PROVIDER, params);
      87           3 :     assert_non_null(test_ctx->tctx);
      88             : 
      89           3 :     test_ctx->be_ctx = mock_be_ctx(test_ctx, test_ctx->tctx);
      90           3 :     assert_non_null(test_ctx->be_ctx);
      91             : 
      92           6 :     test_ctx->be_ctx->domain->subdomains = named_domain(test_ctx,
      93             :                                                         "subdomains",
      94           3 :                                                         test_ctx->be_ctx->domain);
      95           3 :     assert_non_null(test_ctx->be_ctx->domain->subdomains);
      96             : 
      97           3 :     *state = test_ctx;
      98             : 
      99           3 :     return 0;
     100             : }
     101             : 
     102           3 : static int test_teardown(void **state)
     103             : {
     104           3 :     talloc_zfree(*state);
     105           3 :     assert_true(leak_check_teardown());
     106           3 :     return 0;
     107             : }
     108             : 
     109           8 : static void assert_domain_state(struct sss_domain_info *dom,
     110             :                                 enum sss_domain_state expected_state)
     111             : {
     112             :     enum sss_domain_state dom_state;
     113             : 
     114           8 :     dom_state = sss_domain_get_state(dom);
     115           8 :     assert_int_equal(dom_state, expected_state);
     116           8 : }
     117             : 
     118           1 : static void test_mark_subdom_offline_check(struct tevent_context *ev,
     119             :                                            struct tevent_timer *te,
     120             :                                            struct timeval current_time,
     121             :                                            void *pvt)
     122             : {
     123           1 :     struct test_ctx *test_ctx = talloc_get_type(pvt, struct test_ctx);
     124             : 
     125           1 :     assert_domain_state(test_ctx->be_ctx->domain->subdomains,
     126             :                         DOM_ACTIVE);
     127             : 
     128           1 :     test_ctx->tctx->done = true;
     129           1 :     test_ctx->tctx->error = EOK;
     130           1 : }
     131             : 
     132           1 : static void test_mark_dom_offline(void **state)
     133             : {
     134           1 :     struct test_ctx *test_ctx = talloc_get_type(*state, struct test_ctx);
     135             : 
     136           1 :     assert_domain_state(test_ctx->be_ctx->domain, DOM_ACTIVE);
     137           1 :     assert_false(be_is_offline(test_ctx->be_ctx));
     138             : 
     139           1 :     be_mark_dom_offline(test_ctx->be_ctx->domain, test_ctx->be_ctx);
     140             : 
     141           1 :     assert_true(be_is_offline(test_ctx->be_ctx));
     142           1 :     assert_domain_state(test_ctx->be_ctx->domain, DOM_ACTIVE);
     143           1 : }
     144             : 
     145           1 : static void test_mark_subdom_offline(void **state)
     146             : {
     147             :     struct timeval tv;
     148           1 :     struct tevent_timer *check_ev = NULL;
     149           1 :     struct test_ctx *test_ctx = talloc_get_type(*state, struct test_ctx);
     150             :     errno_t ret;
     151             : 
     152           1 :     assert_domain_state(test_ctx->be_ctx->domain->subdomains,
     153             :                         DOM_ACTIVE);
     154           1 :     assert_false(be_is_offline(test_ctx->be_ctx));
     155             : 
     156           1 :     global_timer_added = false;
     157           1 :     be_mark_dom_offline(test_ctx->be_ctx->domain->subdomains, test_ctx->be_ctx);
     158           1 :     assert_domain_state(test_ctx->be_ctx->domain->subdomains,
     159             :                         DOM_INACTIVE);
     160             : 
     161             :     /* A timer must be added that resets the state back */
     162           1 :     assert_true(global_timer_added);
     163             : 
     164             :     /* Global offline state must not change */
     165           1 :     assert_false(be_is_offline(test_ctx->be_ctx));
     166             : 
     167             :     /* Make sure we don't add a second timer */
     168           1 :     global_timer_added = false;
     169           1 :     be_mark_dom_offline(test_ctx->be_ctx->domain->subdomains, test_ctx->be_ctx);
     170           1 :     assert_domain_state(test_ctx->be_ctx->domain->subdomains,
     171             :                         DOM_INACTIVE);
     172           1 :     assert_false(global_timer_added);
     173             : 
     174             :     /* Wait for the internal timer to reset our subdomain back */
     175           1 :     tv = tevent_timeval_current_ofs(OFFLINE_TIMEOUT + 1, 0);
     176             : 
     177           1 :     check_ev = tevent_add_timer(test_ctx->tctx->ev, test_ctx, tv,
     178             :                                 test_mark_subdom_offline_check,
     179             :                                 test_ctx);
     180           1 :     if (check_ev == NULL) {
     181           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot create timer\n");
     182           0 :         return;
     183             :     }
     184             : 
     185           1 :     ret = test_ev_loop(test_ctx->tctx);
     186           1 :     assert_int_equal(ret, EOK);
     187             : }
     188             : 
     189           1 : static void test_mark_subdom_offline_disabled(void **state)
     190             : {
     191           1 :     struct test_ctx *test_ctx = talloc_get_type(*state, struct test_ctx);
     192             : 
     193           1 :     sss_domain_set_state(test_ctx->be_ctx->domain->subdomains, DOM_DISABLED);
     194           1 :     assert_domain_state(test_ctx->be_ctx->domain->subdomains,
     195             :                         DOM_DISABLED);
     196             : 
     197           1 :     be_mark_dom_offline(test_ctx->be_ctx->domain->subdomains, test_ctx->be_ctx);
     198           1 :     assert_domain_state(test_ctx->be_ctx->domain->subdomains,
     199             :                         DOM_DISABLED);
     200           1 : }
     201             : 
     202           1 : int main(int argc, const char *argv[])
     203             : {
     204             :     poptContext pc;
     205             :     int opt;
     206             :     int rv;
     207           1 :     int no_cleanup = 0;
     208           7 :     struct poptOption long_options[] = {
     209             :         POPT_AUTOHELP
     210           5 :         SSSD_DEBUG_OPTS
     211             :         {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0,
     212           1 :          _("Do not delete the test database after a test run"), NULL },
     213             :         POPT_TABLEEND
     214             :     };
     215             : 
     216           1 :     const struct CMUnitTest tests[] = {
     217             :         cmocka_unit_test_setup_teardown(test_mark_dom_offline,
     218             :                                         test_setup,
     219             :                                         test_teardown),
     220             :         cmocka_unit_test_setup_teardown(test_mark_subdom_offline,
     221             :                                         test_setup,
     222             :                                         test_teardown),
     223             :         cmocka_unit_test_setup_teardown(test_mark_subdom_offline_disabled,
     224             :                                         test_setup,
     225             :                                         test_teardown),
     226             :     };
     227             : 
     228             :     /* Set debug level to invalid value so we can deside if -d 0 was used. */
     229           1 :     debug_level = SSSDBG_INVALID;
     230             : 
     231           1 :     pc = poptGetContext(argv[0], argc, argv, long_options, 0);
     232           1 :     while((opt = poptGetNextOpt(pc)) != -1) {
     233             :         switch(opt) {
     234             :         default:
     235           0 :             fprintf(stderr, "\nInvalid option %s: %s\n\n",
     236             :                     poptBadOption(pc, 0), poptStrerror(opt));
     237           0 :             poptPrintUsage(pc, stderr, 0);
     238           0 :             return 1;
     239             :         }
     240             :     }
     241           1 :     poptFreeContext(pc);
     242             : 
     243           1 :     DEBUG_CLI_INIT(debug_level);
     244             : 
     245             :     /* Even though normally the tests should clean up after themselves
     246             :      * they might not after a failed run. Remove the old db to be sure */
     247           1 :     tests_set_cwd();
     248           1 :     test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
     249           1 :     test_dom_suite_setup(TESTS_PATH);
     250             : 
     251           1 :     rv = cmocka_run_group_tests(tests, NULL, NULL);
     252           1 :     if (rv == 0 && !no_cleanup) {
     253           1 :         test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
     254             :     }
     255           1 :     return rv;
     256             : 
     257             :     return cmocka_run_group_tests(tests, NULL, NULL);
     258             : }

Generated by: LCOV version 1.10