LCOV - code coverage report
Current view: top level - lib/tevent - test_req.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 124 131 94.7 %
Date: 2024-04-21 15:09:00 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Unix SMB/CIFS implementation.
       3             :  *
       4             :  * testing of some tevent_req aspects
       5             :  *
       6             :  * Copyright (C) Volker Lendecke 2018
       7             :  *
       8             :  *   ** NOTE! The following LGPL license applies to the tevent
       9             :  *   ** library. This does NOT imply that all of Samba is released
      10             :  *   ** under the LGPL
      11             :  *
      12             :  * This library is free software; you can redistribute it and/or
      13             :  * modify it under the terms of the GNU Lesser General Public
      14             :  * License as published by the Free Software Foundation; either
      15             :  * version 3 of the License, or (at your option) any later version.
      16             :  *
      17             :  * This library is distributed in the hope that it will be useful,
      18             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      19             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      20             :  * Lesser General Public License for more details.
      21             :  *
      22             :  * You should have received a copy of the GNU Lesser General Public
      23             :  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      24             :  */
      25             : 
      26             : #include "includes.h"
      27             : #include "tevent.h"
      28             : #include "torture/torture.h"
      29             : #include "torture/local/proto.h"
      30             : #include "lib/util/tevent_unix.h"
      31             : #include "lib/util/tevent_req_profile.h"
      32             : #include "lib/util/time_basic.h"
      33             : 
      34             : struct tevent_req_create_state {
      35             :         uint8_t val;
      36             : };
      37             : 
      38           1 : static bool test_tevent_req_create(struct torture_context *tctx,
      39             :                                    const void *test_data)
      40             : {
      41           1 :         struct tevent_req *req;
      42           1 :         struct tevent_req_create_state *state;
      43             : 
      44           1 :         req = tevent_req_create(tctx, &state,
      45             :                                 struct tevent_req_create_state);
      46           1 :         torture_assert_not_null(tctx, req, "tevent_req_create failed\n");
      47           1 :         torture_assert_int_equal(tctx, state->val, 0, "state not initialized\n");
      48             : 
      49           1 :         TALLOC_FREE(req);
      50             : 
      51           1 :         return true;
      52             : }
      53             : 
      54             : struct profile1_state {
      55             :         uint8_t dummy;
      56             : };
      57             : 
      58           1 : static bool test_tevent_req_profile1(struct torture_context *tctx,
      59             :                                      const void *test_data)
      60             : {
      61           1 :         struct tevent_req *req;
      62           1 :         struct profile1_state *state;
      63           1 :         const struct tevent_req_profile *p1;
      64           1 :         struct tevent_req_profile *p2;
      65           1 :         struct timeval start, stop;
      66           1 :         bool ok;
      67           1 :         int cmp;
      68             : 
      69           1 :         req = tevent_req_create(tctx, &state, struct profile1_state);
      70           1 :         torture_assert_not_null(tctx, req, "tevent_req_create failed\n");
      71             : 
      72           1 :         p1 = tevent_req_get_profile(req);
      73           1 :         torture_assert(tctx, p1 == NULL, "profile not initialized to NULL\n");
      74             : 
      75           1 :         ok = tevent_req_set_profile(req);
      76           1 :         torture_assert(tctx, ok, "set_profile failed\n");
      77             : 
      78           1 :         tevent_req_done(req);
      79             : 
      80           1 :         p2 = tevent_req_move_profile(req, tctx);
      81           1 :         torture_assert_not_null(tctx, p2, "get_profile failed\n");
      82             : 
      83             :         /* Demonstrate sure "p2" outlives req */
      84           1 :         TALLOC_FREE(req);
      85             : 
      86           1 :         tevent_req_profile_get_start(p2, NULL, &start);
      87           1 :         tevent_req_profile_get_stop(p2, NULL, &stop);
      88             : 
      89           1 :         cmp = tevent_timeval_compare(&start, &stop);
      90           1 :         torture_assert(tctx, cmp <= 0, "stop before start\n");
      91             : 
      92           1 :         TALLOC_FREE(p2);
      93             : 
      94           1 :         return true;
      95             : }
      96             : 
      97             : struct profile2_state {
      98             :         uint8_t dummy;
      99             : };
     100             : 
     101             : static void profile2_done(struct tevent_req *subreq);
     102             : 
     103           1 : static struct tevent_req *profile2_send(TALLOC_CTX *mem_ctx,
     104             :                                         struct tevent_context *ev)
     105             : {
     106           1 :         struct tevent_req *req, *subreq;
     107           1 :         struct profile2_state *state;
     108           1 :         bool ok;
     109             : 
     110           1 :         req = tevent_req_create(mem_ctx, &state, struct profile2_state);
     111           1 :         if (req == NULL) {
     112           0 :                 return NULL;
     113             :         }
     114             : 
     115           1 :         ok = tevent_req_set_profile(req);
     116           1 :         if (!ok) {
     117           0 :                 return tevent_req_post(req, ev);
     118             :         }
     119             : 
     120           1 :         subreq = tevent_wakeup_send(
     121             :                 state,
     122             :                 ev,
     123             :                 tevent_timeval_current_ofs(0, 1));
     124           1 :         if (tevent_req_nomem(subreq, req)) {
     125           0 :                 return tevent_req_post(req, ev);
     126             :         }
     127           1 :         tevent_req_set_callback(subreq, profile2_done, req);
     128             : 
     129           1 :         return req;
     130             : }
     131             : 
     132           1 : static void profile2_done(struct tevent_req *subreq)
     133             : {
     134           1 :         struct tevent_req *req = tevent_req_callback_data(
     135             :                 subreq, struct tevent_req);
     136           1 :         bool ok;
     137             : 
     138           1 :         ok = tevent_wakeup_recv(subreq);
     139           1 :         if (!ok) {
     140           0 :                 tevent_req_oom(req);
     141           0 :                 return;
     142             :         }
     143           1 :         tevent_req_done(req);
     144             : }
     145             : 
     146           1 : static int profile2_recv(struct tevent_req *req,
     147             :                           TALLOC_CTX *mem_ctx,
     148             :                           struct tevent_req_profile **profile)
     149             : {
     150           1 :         int err;
     151             : 
     152           1 :         if (tevent_req_is_unix_error(req, &err)) {
     153           0 :                 return err;
     154             :         }
     155             : 
     156           1 :         *profile = tevent_req_move_profile(req, mem_ctx);
     157             : 
     158           1 :         return 0;
     159             : }
     160             : 
     161           1 : static bool test_tevent_req_profile2(struct torture_context *tctx,
     162             :                                      const void *test_data)
     163             : {
     164           1 :         struct tevent_context *ev;
     165           1 :         struct tevent_req *req;
     166           1 :         struct tevent_req_profile *p1 = NULL;
     167           1 :         struct tevent_req_profile *p2 = NULL;
     168           1 :         const char *str1, *str2;
     169           1 :         struct timeval tv1, tv2;
     170           1 :         pid_t pid1, pid2;
     171           1 :         enum tevent_req_state state1, state2;
     172           1 :         uint64_t err1, err2;
     173           1 :         char *printstring;
     174           1 :         ssize_t pack_len;
     175           1 :         int err;
     176           1 :         bool ok;
     177             : 
     178           1 :         ev = samba_tevent_context_init(tctx);
     179           1 :         torture_assert_not_null(tctx, ev, "samba_tevent_context_init failed\n");
     180             : 
     181           1 :         req = profile2_send(tctx, ev);
     182           1 :         torture_assert_not_null(tctx, req, "profile2_send failed\n");
     183             : 
     184           1 :         ok = tevent_req_poll_unix(req, ev, &err);
     185           1 :         torture_assert(tctx, ok, "tevent_req_poll_unix failed\n");
     186             : 
     187           1 :         err = profile2_recv(req, tctx, &p1);
     188           1 :         torture_assert_int_equal(tctx, err, 0, "profile2_recv failed\n");
     189             : 
     190           1 :         TALLOC_FREE(req);
     191           1 :         TALLOC_FREE(ev);
     192             : 
     193           1 :         printstring = tevent_req_profile_string(tctx, p1, 0, UINT_MAX);
     194           1 :         torture_assert_not_null(
     195             :                 tctx,
     196             :                 printstring,
     197             :                 "tevent_req_profile_string failed\n");
     198           1 :         printf("%s\n", printstring);
     199             : 
     200           1 :         pack_len = tevent_req_profile_pack(p1, NULL, 0);
     201           1 :         torture_assert(tctx, pack_len>0, "profile_pack failed\n");
     202             : 
     203           1 :         {
     204           1 :                 uint8_t buf[pack_len];
     205           1 :                 ssize_t unpack_len;
     206             : 
     207           1 :                 tevent_req_profile_pack(p1, buf, sizeof(buf));
     208           1 :                 dump_data(10, buf, sizeof(buf));
     209             : 
     210           1 :                 unpack_len = tevent_req_profile_unpack(
     211             :                         buf,
     212             :                         pack_len,
     213             :                         tctx,
     214             :                         &p2);
     215           1 :                 torture_assert_int_equal(tctx,
     216             :                                          pack_len,
     217             :                                          unpack_len,
     218             :                                          "profile_unpack failed\n");
     219             :         }
     220             : 
     221           1 :         printstring = tevent_req_profile_string(tctx, p2, 0, UINT_MAX);
     222           1 :         torture_assert_not_null(
     223             :                 tctx,
     224             :                 printstring,
     225             :                 "tevent_req_profile_string failed\n");
     226           1 :         printf("%s\n", printstring);
     227             : 
     228           1 :         tevent_req_profile_get_name(p1, &str1);
     229           1 :         tevent_req_profile_get_name(p2, &str2);
     230           1 :         torture_assert_str_equal(tctx, str1, str2, "names differ\n");
     231             : 
     232           1 :         tevent_req_profile_get_start(p1, &str1, &tv1);
     233           1 :         tevent_req_profile_get_start(p2, &str2, &tv2);
     234           1 :         torture_assert_str_equal(tctx, str1, str2, "start strings differ\n");
     235           1 :         torture_assert(tctx,
     236             :                        tevent_timeval_compare(&tv1, &tv2) == 0,
     237             :                        "start times differ\n");
     238             : 
     239           1 :         tevent_req_profile_get_stop(p1, &str1, &tv1);
     240           1 :         tevent_req_profile_get_stop(p2, &str2, &tv2);
     241           1 :         torture_assert_str_equal(tctx, str1, str2, "stop strings differ\n");
     242           1 :         torture_assert(tctx,
     243             :                        tevent_timeval_compare(&tv1, &tv2) == 0,
     244             :                        "stop times differ\n");
     245             : 
     246           1 :         tevent_req_profile_get_status(p1, &pid1, &state1, &err1);
     247           1 :         tevent_req_profile_get_status(p2, &pid2, &state2, &err2);
     248           1 :         torture_assert_int_equal(tctx, pid1, pid2, "pids differ\n");
     249           1 :         torture_assert_int_equal(tctx, state1, state2, "states differ\n");
     250           1 :         torture_assert_int_equal(tctx, err1, err2, "user errors differ\n");
     251             : 
     252           1 :         str1 = tevent_req_profile_string(p1, p1, 0, UINT_MAX);
     253           1 :         torture_assert_not_null(tctx, str1, "profile_string failed\n");
     254           1 :         str2 = tevent_req_profile_string(p2, p2, 0, UINT_MAX);
     255           1 :         torture_assert_not_null(tctx, str2, "profile_string failed\n");
     256             : 
     257           1 :         torture_assert_str_equal(tctx, str1, str2, "result strings differ\n");
     258             : 
     259           1 :         TALLOC_FREE(p1);
     260           1 :         TALLOC_FREE(p2);
     261             : 
     262           0 :         return true;
     263             : }
     264             : 
     265        2354 : struct torture_suite *torture_local_tevent_req(TALLOC_CTX *mem_ctx)
     266             : {
     267         125 :         struct torture_suite *suite;
     268             : 
     269        2354 :         suite = torture_suite_create(mem_ctx, "tevent_req");
     270             : 
     271        2354 :         torture_suite_add_simple_tcase_const(
     272             :                 suite,
     273             :                 "create",
     274             :                 test_tevent_req_create,
     275             :                 NULL);
     276        2354 :         torture_suite_add_simple_tcase_const(
     277             :                 suite,
     278             :                 "profile1",
     279             :                 test_tevent_req_profile1,
     280             :                 NULL);
     281        2354 :         torture_suite_add_simple_tcase_const(
     282             :                 suite,
     283             :                 "profile2",
     284             :                 test_tevent_req_profile2,
     285             :                 NULL);
     286             : 
     287        2354 :         return suite;
     288             : }

Generated by: LCOV version 1.14