LCOV - code coverage report
Current view: top level - tests/cmocka - test_be_ptask.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 492 495 99.4 %
Date: 2015-10-19 Functions: 37 37 100.0 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Pavel Březina <pbrezina@redhat.com>
       4             : 
       5             :     Copyright (C) 2014 Red Hat
       6             : 
       7             :     This program is free software; you can redistribute it and/or modify
       8             :     it under the terms of the GNU General Public License as published by
       9             :     the Free Software Foundation; either version 3 of the License, or
      10             :     (at your option) any later version.
      11             : 
      12             :     This program is distributed in the hope that it will be useful,
      13             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :     GNU General Public License for more details.
      16             : 
      17             :     You should have received a copy of the GNU General Public License
      18             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include <talloc.h>
      22             : #include <tevent.h>
      23             : #include <errno.h>
      24             : #include <popt.h>
      25             : #include <time.h>
      26             : 
      27             : #include "providers/dp_backend.h"
      28             : #include "providers/dp_ptask_private.h"
      29             : #include "providers/dp_ptask.h"
      30             : #include "tests/cmocka/common_mock.h"
      31             : #include "tests/cmocka/common_mock_be.h"
      32             : #include "tests/common.h"
      33             : 
      34             : #define DELAY  2
      35             : #define PERIOD 1
      36             : 
      37             : #define new_test(test) \
      38             :     cmocka_unit_test_setup_teardown(test_ ## test, test_setup, test_teardown)
      39             : 
      40             : struct test_ctx {
      41             :     struct sss_test_ctx *tctx;
      42             :     struct be_ctx *be_ctx;
      43             : 
      44             :     time_t when;
      45             :     bool done;
      46             : 
      47             :     bool add_online_cb_called;
      48             :     bool add_offline_cb_called;
      49             : };
      50             : 
      51             : #define mark_online(test_ctx) do { \
      52             :     test_ctx->be_ctx->offstat.went_offline = 0; \
      53             :     test_ctx->be_ctx->offstat.offline = false; \
      54             : } while (0)
      55             : 
      56             : #define mark_offline(test_ctx) do { \
      57             :     test_ctx->be_ctx->offstat.went_offline = get_current_time(); \
      58             :     test_ctx->be_ctx->offstat.offline = true; \
      59             : } while (0)
      60             : 
      61             : /* Since both test_ctx->done and ptask->req is marked as finished already
      62             :  * in the sync _send function before a new execution is scheduled we need to
      63             :  * rely on the fact that ptask->req is set to zero when a new timer is
      64             :  * created. This way we guarantee that the condition is true only when
      65             :  * the ptask is executed and a new one is scheduled. */
      66             : #define is_sync_ptask_finished(test_ctx, ptask) \
      67             :     (test_ctx->done && ptask->req == NULL)
      68             : 
      69          41 : static time_t get_current_time(void)
      70             : {
      71             :     struct timeval tv;
      72             :     int ret;
      73             : 
      74          41 :     ret = gettimeofday(&tv, NULL);
      75          41 :     assert_int_equal(0, ret);
      76          41 :     return tv.tv_sec;
      77             : }
      78             : 
      79             : /* Mock few backend functions so we don't have to bring the whole
      80             :  * data provider into this test. */
      81             : 
      82          19 : bool be_is_offline(struct be_ctx *ctx)
      83             : {
      84          19 :     return ctx->offstat.offline;
      85             : }
      86             : 
      87           1 : int be_add_online_cb(TALLOC_CTX *mem_ctx,
      88             :                      struct be_ctx *ctx,
      89             :                      be_callback_t cb,
      90             :                      void *pvt,
      91             :                      struct be_cb **online_cb)
      92             : {
      93           1 :     struct test_ctx *test_ctx = NULL;
      94             : 
      95           1 :     test_ctx = sss_mock_ptr_type(struct test_ctx *);
      96           1 :     test_ctx->add_online_cb_called = true;
      97             : 
      98           1 :     return ERR_OK;
      99             : }
     100             : 
     101           1 : int be_add_offline_cb(TALLOC_CTX *mem_ctx,
     102             :                       struct be_ctx *ctx,
     103             :                       be_callback_t cb,
     104             :                       void *pvt,
     105             :                       struct be_cb **offline_cb)
     106             : {
     107           1 :     struct test_ctx *test_ctx = NULL;
     108             : 
     109           1 :     test_ctx = sss_mock_ptr_type(struct test_ctx *);
     110           1 :     test_ctx->add_offline_cb_called = true;
     111             : 
     112           1 :     return ERR_OK;
     113             : }
     114             : 
     115             : struct test_be_ptask_state {
     116             :     struct test_ctx *test_ctx;
     117             : };
     118             : 
     119          10 : struct tevent_req * test_be_ptask_send(TALLOC_CTX *mem_ctx,
     120             :                                        struct tevent_context *ev,
     121             :                                        struct be_ctx *be_ctx,
     122             :                                        struct be_ptask *be_ptask,
     123             :                                        void *pvt)
     124             : {
     125          10 :     struct test_be_ptask_state *state = NULL;
     126          10 :     struct test_ctx *test_ctx = NULL;
     127          10 :     struct tevent_req *req = NULL;
     128             : 
     129          10 :     assert_non_null(ev);
     130          10 :     assert_non_null(be_ctx);
     131          10 :     assert_non_null(be_ptask);
     132          10 :     assert_non_null(pvt);
     133             : 
     134          10 :     test_ctx = talloc_get_type(pvt, struct test_ctx);
     135          10 :     assert_non_null(test_ctx);
     136             : 
     137          10 :     test_ctx->when = get_current_time();
     138             : 
     139          10 :     req = tevent_req_create(mem_ctx, &state, struct test_be_ptask_state);
     140          10 :     assert_non_null(req);
     141             : 
     142          10 :     state->test_ctx = test_ctx;
     143             : 
     144          10 :     tevent_req_done(req);
     145          10 :     tevent_req_post(req, ev);
     146          10 :     return req;
     147             : }
     148             : 
     149           1 : struct tevent_req * test_be_ptask_null_send(TALLOC_CTX *mem_ctx,
     150             :                                             struct tevent_context *ev,
     151             :                                             struct be_ctx *be_ctx,
     152             :                                             struct be_ptask *be_ptask,
     153             :                                             void *pvt)
     154             : {
     155           1 :     struct test_ctx *test_ctx = NULL;
     156           1 :     assert_non_null(ev);
     157           1 :     assert_non_null(be_ctx);
     158           1 :     assert_non_null(be_ptask);
     159           1 :     assert_non_null(pvt);
     160             : 
     161           1 :     test_ctx = talloc_get_type(pvt, struct test_ctx);
     162           1 :     assert_non_null(test_ctx);
     163             : 
     164           1 :     test_ctx->when = get_current_time();
     165           1 :     test_ctx->done = true;
     166             : 
     167           1 :     return NULL;
     168             : }
     169             : 
     170           1 : struct tevent_req * test_be_ptask_timeout_send(TALLOC_CTX *mem_ctx,
     171             :                                                struct tevent_context *ev,
     172             :                                                struct be_ctx *be_ctx,
     173             :                                                struct be_ptask *be_ptask,
     174             :                                                void *pvt)
     175             : {
     176           1 :     struct test_be_ptask_state *state = NULL;
     177           1 :     struct test_ctx *test_ctx = NULL;
     178           1 :     struct tevent_req *req = NULL;
     179             : 
     180           1 :     assert_non_null(ev);
     181           1 :     assert_non_null(be_ctx);
     182           1 :     assert_non_null(be_ptask);
     183           1 :     assert_non_null(pvt);
     184             : 
     185           1 :     test_ctx = talloc_get_type(pvt, struct test_ctx);
     186           1 :     assert_non_null(test_ctx);
     187             : 
     188           1 :     test_ctx->when = get_current_time();
     189             : 
     190           1 :     req = tevent_req_create(mem_ctx, &state, struct test_be_ptask_state);
     191           1 :     assert_non_null(req);
     192             : 
     193           1 :     state->test_ctx = test_ctx;
     194             : 
     195             :     /* we won't finish the request */
     196             : 
     197           1 :     return req;
     198             : }
     199             : 
     200           9 : errno_t test_be_ptask_recv(struct tevent_req *req)
     201             : {
     202           9 :     struct test_be_ptask_state *state = NULL;
     203             : 
     204           9 :     state = tevent_req_data(req, struct test_be_ptask_state);
     205           9 :     assert_non_null(state);
     206             : 
     207           9 :     state->test_ctx->done = true;
     208             : 
     209           9 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     210             : 
     211           9 :     return ERR_OK;
     212             : }
     213             : 
     214           1 : errno_t test_be_ptask_error_recv(struct tevent_req *req)
     215             : {
     216           1 :     struct test_be_ptask_state *state = NULL;
     217             : 
     218           1 :     state = tevent_req_data(req, struct test_be_ptask_state);
     219           1 :     assert_non_null(state);
     220             : 
     221           1 :     state->test_ctx->done = true;
     222             : 
     223           1 :     return ERR_INTERNAL;
     224             : }
     225             : 
     226           2 : errno_t test_be_ptask_sync(TALLOC_CTX *mem_ctx,
     227             :                            struct tevent_context *ev,
     228             :                            struct be_ctx *be_ctx,
     229             :                            struct be_ptask *be_ptask,
     230             :                            void *pvt)
     231             : {
     232           2 :     struct test_ctx *test_ctx = NULL;
     233             : 
     234           2 :     assert_non_null(ev);
     235           2 :     assert_non_null(be_ctx);
     236           2 :     assert_non_null(be_ptask);
     237           2 :     assert_non_null(pvt);
     238             : 
     239           2 :     test_ctx = talloc_get_type(pvt, struct test_ctx);
     240           2 :     assert_non_null(test_ctx);
     241             : 
     242           2 :     test_ctx->when = get_current_time();
     243           2 :     test_ctx->done = true;
     244             : 
     245           2 :     return ERR_OK;
     246             : }
     247             : 
     248           3 : errno_t test_be_ptask_sync_error(TALLOC_CTX *mem_ctx,
     249             :                                  struct tevent_context *ev,
     250             :                                  struct be_ctx *be_ctx,
     251             :                                  struct be_ptask *be_ptask,
     252             :                                  void *pvt)
     253             : {
     254           3 :     struct test_ctx *test_ctx = NULL;
     255             : 
     256           3 :     assert_non_null(ev);
     257           3 :     assert_non_null(be_ctx);
     258           3 :     assert_non_null(be_ptask);
     259           3 :     assert_non_null(pvt);
     260             : 
     261           3 :     test_ctx = talloc_get_type(pvt, struct test_ctx);
     262           3 :     assert_non_null(test_ctx);
     263             : 
     264           3 :     test_ctx->when = get_current_time();
     265           3 :     test_ctx->done = true;
     266             : 
     267           3 :     return ERR_INTERNAL;
     268             : }
     269             : 
     270          23 : static int test_setup(void **state)
     271             : {
     272          23 :     struct test_ctx *test_ctx = NULL;
     273             : 
     274          23 :     assert_true(leak_check_setup());
     275             : 
     276          23 :     test_ctx = talloc_zero(global_talloc_context, struct test_ctx);
     277          23 :     assert_non_null(test_ctx);
     278             : 
     279          23 :     test_ctx->tctx = create_ev_test_ctx(test_ctx);
     280          23 :     assert_non_null(test_ctx->tctx);
     281             : 
     282          23 :     test_ctx->be_ctx = mock_be_ctx(test_ctx, test_ctx->tctx);
     283          23 :     assert_non_null(test_ctx->be_ctx);
     284             : 
     285          23 :     test_ctx->be_ctx->ev = tevent_context_init(test_ctx->be_ctx);
     286          23 :     assert_non_null(test_ctx->be_ctx->ev);
     287             : 
     288          23 :     *state = test_ctx;
     289          23 :     return 0;
     290             : }
     291             : 
     292          23 : static int test_teardown(void **state)
     293             : {
     294          23 :     talloc_zfree(*state);
     295          23 :     assert_true(leak_check_teardown());
     296          23 :     return 0;
     297             : }
     298             : 
     299           1 : void test_be_ptask_create_einval_be(void **state)
     300             : {
     301           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     302           1 :     struct be_ptask *ptask = NULL;
     303             :     errno_t ret;
     304             : 
     305           1 :     ret = be_ptask_create(test_ctx, NULL, PERIOD, 0, 0, 0, 0,
     306             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     307             :                           test_be_ptask_recv, NULL, "Test ptask", &ptask);
     308           1 :     assert_int_equal(ret, EINVAL);
     309           1 :     assert_null(ptask);
     310           1 : }
     311             : 
     312           1 : void test_be_ptask_create_einval_period(void **state)
     313             : {
     314           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     315           1 :     struct be_ptask *ptask = NULL;
     316             :     errno_t ret;
     317             : 
     318           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, 0, 0, 0, 0, 0,
     319             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     320             :                           test_be_ptask_recv, NULL, "Test ptask", &ptask);
     321           1 :     assert_int_equal(ret, EINVAL);
     322           1 :     assert_null(ptask);
     323           1 : }
     324             : 
     325           1 : void test_be_ptask_create_einval_send(void **state)
     326             : {
     327           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     328           1 :     struct be_ptask *ptask = NULL;
     329             :     errno_t ret;
     330             : 
     331           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     332             :                           BE_PTASK_OFFLINE_SKIP, 0, NULL,
     333             :                           test_be_ptask_recv, NULL, "Test ptask", &ptask);
     334           1 :     assert_int_equal(ret, EINVAL);
     335           1 :     assert_null(ptask);
     336           1 : }
     337             : 
     338           1 : void test_be_ptask_create_einval_recv(void **state)
     339             : {
     340           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     341           1 :     struct be_ptask *ptask = NULL;
     342             :     errno_t ret;
     343             : 
     344           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     345             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     346             :                           NULL, NULL, "Test ptask", &ptask);
     347           1 :     assert_int_equal(ret, EINVAL);
     348           1 :     assert_null(ptask);
     349           1 : }
     350             : 
     351           1 : void test_be_ptask_create_einval_name(void **state)
     352             : {
     353           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     354           1 :     struct be_ptask *ptask = NULL;
     355             :     errno_t ret;
     356             : 
     357           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     358             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     359             :                           test_be_ptask_recv, NULL, NULL, &ptask);
     360           1 :     assert_int_equal(ret, EINVAL);
     361           1 :     assert_null(ptask);
     362           1 : }
     363             : 
     364           1 : void test_be_ptask_create_no_delay(void **state)
     365             : {
     366           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     367           1 :     struct be_ptask *ptask = NULL;
     368             :     time_t now;
     369             :     errno_t ret;
     370             : 
     371           1 :     now = get_current_time();
     372           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     373             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     374             :                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
     375           1 :     assert_int_equal(ret, ERR_OK);
     376           1 :     assert_non_null(ptask);
     377           1 :     assert_non_null(ptask->timer);
     378             : 
     379           4 :     while (!test_ctx->done) {
     380           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     381             :     }
     382             : 
     383           1 :     assert_true(now <= ptask->last_execution);
     384           1 :     assert_true(now <= test_ctx->when);
     385           1 :     assert_true(ptask->last_execution <= test_ctx->when);
     386             : 
     387           1 :     be_ptask_destroy(&ptask);
     388           1 :     assert_null(ptask);
     389           1 : }
     390             : 
     391           1 : void test_be_ptask_create_first_delay(void **state)
     392             : {
     393           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     394           1 :     struct be_ptask *ptask = NULL;
     395             :     time_t now;
     396             :     errno_t ret;
     397             : 
     398           1 :     now = get_current_time();
     399           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, DELAY, 0, 0, 0,
     400             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     401             :                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
     402           1 :     assert_int_equal(ret, ERR_OK);
     403           1 :     assert_non_null(ptask);
     404           1 :     assert_non_null(ptask->timer);
     405             : 
     406           4 :     while (!test_ctx->done) {
     407           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     408             :     }
     409             : 
     410           1 :     assert_true(now + DELAY <= ptask->last_execution);
     411           1 :     assert_true(now + DELAY <= test_ctx->when);
     412           1 :     assert_true(ptask->last_execution <= test_ctx->when);
     413             : 
     414           1 :     be_ptask_destroy(&ptask);
     415           1 :     assert_null(ptask);
     416           1 : }
     417             : 
     418           1 : void test_be_ptask_disable(void **state)
     419             : {
     420           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     421           1 :     struct be_ptask *ptask = NULL;
     422             :     errno_t ret;
     423             : 
     424           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     425             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     426             :                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
     427           1 :     assert_int_equal(ret, ERR_OK);
     428           1 :     assert_non_null(ptask);
     429           1 :     assert_non_null(ptask->timer);
     430             : 
     431           1 :     be_ptask_disable(ptask);
     432             : 
     433           1 :     assert_null(ptask->timer);
     434           1 :     assert_false(ptask->enabled);
     435             : 
     436           1 :     be_ptask_destroy(&ptask);
     437           1 :     assert_null(ptask);
     438           1 : }
     439             : 
     440           1 : void test_be_ptask_enable(void **state)
     441             : {
     442           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     443           1 :     struct be_ptask *ptask = NULL;
     444             :     time_t now;
     445             :     errno_t ret;
     446             : 
     447           1 :     now = get_current_time();
     448           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     449             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     450             :                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
     451           1 :     assert_int_equal(ret, ERR_OK);
     452           1 :     assert_non_null(ptask);
     453           1 :     assert_non_null(ptask->timer);
     454             : 
     455           1 :     be_ptask_disable(ptask);
     456             : 
     457           1 :     now = get_current_time();
     458           1 :     be_ptask_enable(ptask);
     459           1 :     assert_non_null(ptask->timer);
     460             : 
     461           4 :     while (!test_ctx->done) {
     462           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     463             :     }
     464             : 
     465           1 :     assert_true(now <= ptask->last_execution);
     466           1 :     assert_true(now <= test_ctx->when);
     467           1 :     assert_true(ptask->last_execution <= test_ctx->when);
     468             : 
     469           1 :     be_ptask_destroy(&ptask);
     470           1 :     assert_null(ptask);
     471           1 : }
     472             : 
     473           1 : void test_be_ptask_enable_delay(void **state)
     474             : {
     475           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     476           1 :     struct be_ptask *ptask = NULL;
     477             :     time_t now;
     478             :     errno_t ret;
     479             : 
     480           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, DELAY, 0, 0,
     481             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     482             :                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
     483           1 :     assert_int_equal(ret, ERR_OK);
     484           1 :     assert_non_null(ptask);
     485           1 :     assert_non_null(ptask->timer);
     486             : 
     487           4 :     while (!test_ctx->done) {
     488           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     489             :     }
     490             : 
     491           1 :     be_ptask_disable(ptask);
     492           1 :     test_ctx->done = false;
     493           1 :     now = get_current_time();
     494           1 :     be_ptask_enable(ptask);
     495             : 
     496           4 :     while (!test_ctx->done) {
     497           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     498             :     }
     499             : 
     500           1 :     assert_true(now + DELAY <= ptask->last_execution);
     501           1 :     assert_true(now + DELAY <= test_ctx->when);
     502           1 :     assert_true(ptask->last_execution <= test_ctx->when);
     503             : 
     504           1 :     be_ptask_destroy(&ptask);
     505           1 :     assert_null(ptask);
     506           1 : }
     507             : 
     508           1 : void test_be_ptask_offline_skip(void **state)
     509             : {
     510           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     511           1 :     struct be_ptask *ptask = NULL;
     512             :     time_t next_execution;
     513             :     time_t now;
     514             :     errno_t ret;
     515             : 
     516           1 :     mark_offline(test_ctx);
     517             : 
     518           1 :     now = get_current_time();
     519           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     520             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     521             :                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
     522           1 :     assert_int_equal(ret, ERR_OK);
     523           1 :     assert_non_null(ptask);
     524           1 :     assert_non_null(ptask->timer);
     525             : 
     526           1 :     next_execution = ptask->next_execution;
     527           1 :     assert_true(now <= next_execution);
     528             : 
     529           3 :     while (ptask->next_execution == next_execution && !test_ctx->done) {
     530           1 :         tevent_loop_once(test_ctx->be_ctx->ev);
     531             :     }
     532             : 
     533           1 :     assert_true(next_execution + PERIOD <= ptask->next_execution);
     534           1 :     assert_true(ptask->enabled);
     535           1 :     assert_non_null(ptask->timer);
     536             : 
     537           1 :     be_ptask_destroy(&ptask);
     538           1 :     assert_null(ptask);
     539           1 : }
     540             : 
     541           1 : void test_be_ptask_offline_disable(void **state)
     542             : {
     543           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     544           1 :     struct be_ptask *ptask = NULL;
     545             :     errno_t ret;
     546             : 
     547           1 :     mark_offline(test_ctx);
     548             : 
     549           1 :     will_return(be_add_online_cb, test_ctx);
     550           1 :     will_return(be_add_offline_cb, test_ctx);
     551             : 
     552           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     553             :                           BE_PTASK_OFFLINE_DISABLE, 0, test_be_ptask_send,
     554             :                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
     555           1 :     assert_int_equal(ret, ERR_OK);
     556           1 :     assert_non_null(ptask);
     557           1 :     assert_non_null(ptask->timer);
     558             : 
     559           1 :     assert_true(test_ctx->add_online_cb_called);
     560           1 :     assert_true(test_ctx->add_offline_cb_called);
     561             : 
     562           3 :     while (ptask->enabled && !test_ctx->done) {
     563           1 :         tevent_loop_once(test_ctx->be_ctx->ev);
     564             :     }
     565             : 
     566           1 :     assert_false(ptask->enabled);
     567           1 :     assert_false(test_ctx->done);
     568           1 :     assert_null(ptask->timer);
     569             : 
     570           1 :     be_ptask_destroy(&ptask);
     571           1 :     assert_null(ptask);
     572           1 : }
     573             : 
     574           1 : void test_be_ptask_offline_execute(void **state)
     575             : {
     576           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     577           1 :     struct be_ptask *ptask = NULL;
     578             :     errno_t ret;
     579             : 
     580           1 :     mark_offline(test_ctx);
     581             : 
     582           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     583             :                           BE_PTASK_OFFLINE_EXECUTE, 0, test_be_ptask_send,
     584             :                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
     585           1 :     assert_int_equal(ret, ERR_OK);
     586           1 :     assert_non_null(ptask);
     587           1 :     assert_non_null(ptask->timer);
     588             : 
     589           4 :     while (!test_ctx->done) {
     590           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     591             :     }
     592             : 
     593           1 :     assert_true(ptask->enabled);
     594           1 :     assert_non_null(ptask->timer);
     595             : 
     596           1 :     be_ptask_destroy(&ptask);
     597           1 :     assert_null(ptask);
     598           1 : }
     599             : 
     600           1 : void test_be_ptask_reschedule_ok(void **state)
     601             : {
     602           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     603           1 :     struct be_ptask *ptask = NULL;
     604             :     time_t next_execution;
     605             :     time_t now;
     606             :     errno_t ret;
     607             : 
     608           1 :     now = get_current_time();
     609           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     610             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     611             :                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
     612           1 :     assert_int_equal(ret, ERR_OK);
     613           1 :     assert_non_null(ptask);
     614           1 :     assert_non_null(ptask->timer);
     615             : 
     616           1 :     next_execution = ptask->next_execution;
     617             : 
     618           4 :     while (!test_ctx->done) {
     619           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     620             :     }
     621             : 
     622           1 :     assert_true(now <= ptask->last_execution);
     623           1 :     assert_true(now <= test_ctx->when);
     624           1 :     assert_true(ptask->last_execution <= test_ctx->when);
     625             : 
     626           1 :     assert_true(next_execution + PERIOD <= ptask->next_execution);
     627           1 :     assert_non_null(ptask->timer);
     628             : 
     629           1 :     be_ptask_destroy(&ptask);
     630           1 :     assert_null(ptask);
     631           1 : }
     632             : 
     633           1 : void test_be_ptask_reschedule_null(void **state)
     634             : {
     635           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     636           1 :     struct be_ptask *ptask = NULL;
     637           1 :     time_t now = 0;
     638             :     errno_t ret;
     639             : 
     640           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     641             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_null_send,
     642             :                           test_be_ptask_recv, test_ctx, "Test ptask",
     643             :                           &ptask);
     644           1 :     assert_int_equal(ret, ERR_OK);
     645           1 :     assert_non_null(ptask);
     646           1 :     assert_non_null(ptask->timer);
     647             : 
     648           3 :     while (!test_ctx->done) {
     649           1 :         now = get_current_time();
     650           1 :         tevent_loop_once(test_ctx->be_ctx->ev);
     651             :     }
     652             : 
     653           1 :     assert_true(now + PERIOD <= ptask->next_execution);
     654           1 :     assert_non_null(ptask->timer);
     655             : 
     656           1 :     be_ptask_destroy(&ptask);
     657           1 :     assert_null(ptask);
     658           1 : }
     659             : 
     660           1 : void test_be_ptask_reschedule_error(void **state)
     661             : {
     662           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     663           1 :     struct be_ptask *ptask = NULL;
     664           1 :     time_t now = 0;
     665             :     errno_t ret;
     666             : 
     667           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     668             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     669             :                           test_be_ptask_error_recv, test_ctx, "Test ptask",
     670             :                           &ptask);
     671           1 :     assert_int_equal(ret, ERR_OK);
     672           1 :     assert_non_null(ptask);
     673           1 :     assert_non_null(ptask->timer);
     674             : 
     675           4 :     while (!test_ctx->done) {
     676           2 :         now = get_current_time();
     677           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     678             :     }
     679             : 
     680           1 :     assert_true(now + PERIOD <= ptask->next_execution);
     681           1 :     assert_non_null(ptask->timer);
     682             : 
     683           1 :     be_ptask_destroy(&ptask);
     684           1 :     assert_null(ptask);
     685           1 : }
     686             : 
     687           1 : void test_be_ptask_reschedule_timeout(void **state)
     688             : {
     689           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     690           1 :     struct be_ptask *ptask = NULL;
     691           1 :     time_t now = 0;
     692             :     errno_t ret;
     693             : 
     694           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 1,
     695             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_timeout_send,
     696             :                           test_be_ptask_error_recv, test_ctx, "Test ptask",
     697             :                           &ptask);
     698           1 :     assert_int_equal(ret, ERR_OK);
     699           1 :     assert_non_null(ptask);
     700           1 :     assert_non_null(ptask->timer);
     701             : 
     702             :     /* first iterate until the task is executed */
     703           3 :     while (!test_ctx->done && ptask->req == NULL) {
     704           1 :         tevent_loop_once(test_ctx->be_ctx->ev);
     705             :     }
     706             : 
     707             :     /* then iterate until the request is destroyed */
     708           3 :     while (!test_ctx->done && ptask->req != NULL) {
     709           1 :         now = get_current_time();
     710           1 :         tevent_loop_once(test_ctx->be_ctx->ev);
     711             :     }
     712             : 
     713           1 :     assert_false(test_ctx->done);
     714           1 :     assert_true(now + PERIOD <= ptask->next_execution);
     715           1 :     assert_non_null(ptask->timer);
     716             : 
     717           1 :     be_ptask_destroy(&ptask);
     718           1 :     assert_null(ptask);
     719           1 : }
     720             : 
     721           1 : void test_be_ptask_reschedule_backoff(void **state)
     722             : {
     723           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     724           1 :     struct be_ptask *ptask = NULL;
     725             :     time_t next_execution;
     726             :     time_t now_first;
     727           1 :     time_t now_backoff = 0;
     728             :     errno_t ret;
     729             : 
     730           1 :     now_first = get_current_time();
     731           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     732             :                           BE_PTASK_OFFLINE_SKIP, PERIOD*2, test_be_ptask_send,
     733             :                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
     734           1 :     assert_int_equal(ret, ERR_OK);
     735           1 :     assert_non_null(ptask);
     736           1 :     assert_non_null(ptask->timer);
     737             : 
     738             :     /* first run */
     739           1 :     next_execution = ptask->next_execution;
     740             : 
     741           4 :     while (!test_ctx->done) {
     742             :         /* We need to acquire timestamp for the second test here, since this
     743             :          * is the closest value to the timestamp when the next event is
     744             :          * scheduled. */
     745           2 :         now_backoff = get_current_time();
     746           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     747             :     }
     748             : 
     749           1 :     assert_true(now_first <= ptask->last_execution);
     750           1 :     assert_true(now_first <= test_ctx->when);
     751           1 :     assert_true(ptask->last_execution <= test_ctx->when);
     752             : 
     753           1 :     assert_true(next_execution + PERIOD <= ptask->next_execution);
     754           1 :     assert_int_equal(PERIOD*2, ptask->period);
     755           1 :     assert_non_null(ptask->timer);
     756             : 
     757           1 :     test_ctx->done = false;
     758             : 
     759             :     /* second run */
     760           1 :     next_execution = ptask->next_execution;
     761             : 
     762           4 :     while (!test_ctx->done) {
     763           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     764             :     }
     765             : 
     766           1 :     assert_true(now_backoff + PERIOD <= ptask->last_execution);
     767           1 :     assert_true(now_backoff + PERIOD <= test_ctx->when);
     768           1 :     assert_true(ptask->last_execution <= test_ctx->when);
     769             : 
     770           1 :     assert_true(next_execution + PERIOD*2 <= ptask->next_execution);
     771           1 :     assert_int_equal(PERIOD*2, ptask->period);
     772           1 :     assert_non_null(ptask->timer);
     773             : 
     774           1 :     be_ptask_destroy(&ptask);
     775           1 :     assert_null(ptask);
     776           1 : }
     777             : 
     778           1 : void test_be_ptask_get_period(void **state)
     779             : {
     780           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     781           1 :     struct be_ptask *ptask = NULL;
     782             :     time_t out_period;
     783             :     errno_t ret;
     784             : 
     785           1 :     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     786             :                           BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
     787             :                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
     788           1 :     assert_int_equal(ret, ERR_OK);
     789           1 :     assert_non_null(ptask);
     790             : 
     791           1 :     out_period = be_ptask_get_period(ptask);
     792           1 :     assert_true(PERIOD == out_period);
     793             : 
     794           1 :     be_ptask_destroy(&ptask);
     795           1 :     assert_null(ptask);
     796           1 : }
     797             : 
     798           1 : void test_be_ptask_create_sync(void **state)
     799             : {
     800           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     801           1 :     struct be_ptask *ptask = NULL;
     802             :     time_t now;
     803             :     errno_t ret;
     804             : 
     805           1 :     now = get_current_time();
     806           1 :     ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     807             :                                BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_sync,
     808             :                                test_ctx, "Test ptask", &ptask);
     809           1 :     assert_int_equal(ret, ERR_OK);
     810           1 :     assert_non_null(ptask);
     811           1 :     assert_non_null(ptask->timer);
     812             : 
     813           3 :     while (!test_ctx->done) {
     814           1 :         tevent_loop_once(test_ctx->be_ctx->ev);
     815             :     }
     816             : 
     817           1 :     assert_true(now <= ptask->last_execution);
     818           1 :     assert_true(now <= test_ctx->when);
     819           1 :     assert_true(ptask->last_execution <= test_ctx->when);
     820             : 
     821           1 :     be_ptask_destroy(&ptask);
     822           1 :     assert_null(ptask);
     823           1 : }
     824             : 
     825           1 : void test_be_ptask_sync_reschedule_ok(void **state)
     826             : {
     827           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     828           1 :     struct be_ptask *ptask = NULL;
     829             :     time_t next_execution;
     830             :     time_t now;
     831             :     errno_t ret;
     832             : 
     833           1 :     now = get_current_time();
     834           1 :     ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     835             :                                BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_sync,
     836             :                                test_ctx, "Test ptask", &ptask);
     837           1 :     assert_int_equal(ret, ERR_OK);
     838           1 :     assert_non_null(ptask);
     839           1 :     assert_non_null(ptask->timer);
     840             : 
     841           1 :     next_execution = ptask->next_execution;
     842             : 
     843           4 :     while (!is_sync_ptask_finished(test_ctx, ptask)) {
     844           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     845             :     }
     846             : 
     847           1 :     assert_true(now <= ptask->last_execution);
     848           1 :     assert_true(now <= test_ctx->when);
     849           1 :     assert_true(ptask->last_execution <= test_ctx->when);
     850             : 
     851           1 :     assert_true(next_execution + PERIOD <= ptask->next_execution);
     852           1 :     assert_non_null(ptask->timer);
     853             : 
     854           1 :     be_ptask_destroy(&ptask);
     855           1 :     assert_null(ptask);
     856           1 : }
     857             : 
     858           1 : void test_be_ptask_sync_reschedule_error(void **state)
     859             : {
     860           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     861           1 :     struct be_ptask *ptask = NULL;
     862           1 :     time_t now = 0;
     863             :     errno_t ret;
     864             : 
     865           1 :     ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     866             :                                BE_PTASK_OFFLINE_SKIP, 0,
     867             :                                test_be_ptask_sync_error,
     868             :                                test_ctx, "Test ptask", &ptask);
     869           1 :     assert_int_equal(ret, ERR_OK);
     870           1 :     assert_non_null(ptask);
     871           1 :     assert_non_null(ptask->timer);
     872             : 
     873           4 :     while (!is_sync_ptask_finished(test_ctx, ptask)) {
     874           2 :         now = get_current_time();
     875           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     876             :     }
     877             : 
     878           1 :     assert_true(now + PERIOD <= ptask->next_execution);
     879           1 :     assert_non_null(ptask->timer);
     880             : 
     881           1 :     be_ptask_destroy(&ptask);
     882           1 :     assert_null(ptask);
     883           1 : }
     884             : 
     885           1 : void test_be_ptask_sync_reschedule_backoff(void **state)
     886             : {
     887           1 :     struct test_ctx *test_ctx = (struct test_ctx *)(*state);
     888           1 :     struct be_ptask *ptask = NULL;
     889             :     time_t next_execution;
     890             :     time_t now_first;
     891           1 :     time_t now_backoff = 0;
     892             :     errno_t ret;
     893             : 
     894           1 :     now_first = get_current_time();
     895           1 :     ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
     896             :                                BE_PTASK_OFFLINE_SKIP, PERIOD*2,
     897             :                                test_be_ptask_sync_error,
     898             :                                test_ctx, "Test ptask", &ptask);
     899           1 :     assert_int_equal(ret, ERR_OK);
     900           1 :     assert_non_null(ptask);
     901           1 :     assert_non_null(ptask->timer);
     902             : 
     903             :     /* first run */
     904           1 :     next_execution = ptask->next_execution;
     905             : 
     906           4 :     while (!is_sync_ptask_finished(test_ctx, ptask)) {
     907             :         /* We need to acquire timestamp for the second test here, since this
     908             :          * is the closest value to the timestamp when the next event is
     909             :          * scheduled. */
     910           2 :         now_backoff = get_current_time();
     911           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     912             :     }
     913             : 
     914           1 :     assert_true(now_first <= ptask->last_execution);
     915           1 :     assert_true(now_first <= test_ctx->when);
     916           1 :     assert_true(ptask->last_execution <= test_ctx->when);
     917             : 
     918           1 :     assert_true(next_execution + PERIOD <= ptask->next_execution);
     919           1 :     assert_int_equal(PERIOD*2, ptask->period);
     920           1 :     assert_non_null(ptask->timer);
     921             : 
     922           1 :     test_ctx->done = false;
     923             : 
     924             :     /* second run */
     925           1 :     next_execution = ptask->next_execution;
     926             : 
     927           4 :     while (!is_sync_ptask_finished(test_ctx, ptask)) {
     928           2 :         tevent_loop_once(test_ctx->be_ctx->ev);
     929             :     }
     930             : 
     931           1 :     assert_true(now_backoff + PERIOD <= ptask->last_execution);
     932           1 :     assert_true(now_backoff + PERIOD <= test_ctx->when);
     933           1 :     assert_true(ptask->last_execution <= test_ctx->when);
     934             : 
     935           1 :     assert_true(next_execution + PERIOD*2 <= ptask->next_execution);
     936           1 :     assert_int_equal(PERIOD*2, ptask->period);
     937           1 :     assert_non_null(ptask->timer);
     938             : 
     939           1 :     be_ptask_destroy(&ptask);
     940           1 :     assert_null(ptask);
     941           1 : }
     942             : 
     943           1 : int main(int argc, const char *argv[])
     944             : {
     945             :     poptContext pc;
     946             :     int opt;
     947           6 :     struct poptOption long_options[] = {
     948             :         POPT_AUTOHELP
     949           5 :         SSSD_DEBUG_OPTS
     950             :         POPT_TABLEEND
     951             :     };
     952             : 
     953           1 :     const struct CMUnitTest tests[] = {
     954             :         new_test(be_ptask_create_einval_be),
     955             :         new_test(be_ptask_create_einval_period),
     956             :         new_test(be_ptask_create_einval_send),
     957             :         new_test(be_ptask_create_einval_recv),
     958             :         new_test(be_ptask_create_einval_name),
     959             :         new_test(be_ptask_create_no_delay),
     960             :         new_test(be_ptask_create_first_delay),
     961             :         new_test(be_ptask_disable),
     962             :         new_test(be_ptask_enable),
     963             :         new_test(be_ptask_enable_delay),
     964             :         new_test(be_ptask_offline_skip),
     965             :         new_test(be_ptask_offline_disable),
     966             :         new_test(be_ptask_offline_execute),
     967             :         new_test(be_ptask_reschedule_ok),
     968             :         new_test(be_ptask_reschedule_null),
     969             :         new_test(be_ptask_reschedule_error),
     970             :         new_test(be_ptask_reschedule_timeout),
     971             :         new_test(be_ptask_reschedule_backoff),
     972             :         new_test(be_ptask_get_period),
     973             :         new_test(be_ptask_create_sync),
     974             :         new_test(be_ptask_sync_reschedule_ok),
     975             :         new_test(be_ptask_sync_reschedule_error),
     976             :         new_test(be_ptask_sync_reschedule_backoff)
     977             :     };
     978             : 
     979             :     /* Set debug level to invalid value so we can deside if -d 0 was used. */
     980           1 :     debug_level = SSSDBG_INVALID;
     981             : 
     982           1 :     pc = poptGetContext(argv[0], argc, argv, long_options, 0);
     983           1 :     while((opt = poptGetNextOpt(pc)) != -1) {
     984             :         switch(opt) {
     985             :         default:
     986           0 :             fprintf(stderr, "\nInvalid option %s: %s\n\n",
     987             :                     poptBadOption(pc, 0), poptStrerror(opt));
     988           0 :             poptPrintUsage(pc, stderr, 0);
     989           0 :             return 1;
     990             :         }
     991             :     }
     992           1 :     poptFreeContext(pc);
     993             : 
     994           1 :     DEBUG_CLI_INIT(debug_level);
     995             : 
     996           1 :     return cmocka_run_group_tests(tests, NULL, NULL);
     997             : }

Generated by: LCOV version 1.10