Home | History | Annotate | Line # | Download | only in test
      1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
      2  *
      3  * Permission is hereby granted, free of charge, to any person obtaining a copy
      4  * of this software and associated documentation files (the "Software"), to
      5  * deal in the Software without restriction, including without limitation the
      6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
      7  * sell copies of the Software, and to permit persons to whom the Software is
      8  * furnished to do so, subject to the following conditions:
      9  *
     10  * The above copyright notice and this permission notice shall be included in
     11  * all copies or substantial portions of the Software.
     12  *
     13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     19  * IN THE SOFTWARE.
     20  */
     21 
     22 /* Tests commented out with XXX are ones that are failing on Linux */
     23 
     24 /*
     25  * Purpose of this test is to check semantics of starting and stopping
     26  * prepare, check and idle watchers.
     27  *
     28  * - A watcher must be able to safely stop or close itself;
     29  * - Once a watcher is stopped or closed its callback should never be called.
     30  * - If a watcher is closed, it is implicitly stopped and its close_cb should
     31  *   be called exactly once.
     32  * - A watcher can safely start and stop other watchers of the same type.
     33  * - Prepare and check watchers are called once per event loop iterations.
     34  * - All active idle watchers are queued when the event loop has no more work
     35  *   to do. This is done repeatedly until all idle watchers are inactive.
     36  * - If a watcher starts another watcher of the same type its callback is not
     37  *   immediately queued. For check and prepare watchers, that means that if
     38  *   a watcher makes another of the same type active, it'll not be called until
     39  *   the next event loop iteration. For idle. watchers this means that the
     40  *   newly activated idle watcher might not be queued immediately.
     41  * - Prepare, check, idle watchers keep the event loop alive even when they're
     42  *   not active.
     43  *
     44  * This is what the test globally does:
     45  *
     46  * - prepare_1 is always active and counts event loop iterations. It also
     47  *   creates and starts prepare_2 every other iteration. Finally it verifies
     48  *   that no idle watchers are active before polling.
     49  * - prepare_2 is started by prepare_1 every other iteration. It immediately
     50  *   stops itself. It verifies that a watcher is not queued immediately
     51  *   if created by another watcher of the same type.
     52  * - There's a check watcher that stops the event loop after a certain number
     53  *   of iterations. It starts a varying number of idle_1 watchers.
     54  * - Idle_1 watchers stop themselves after being called a few times. All idle_1
     55  *   watchers try to start the idle_2 watcher if it is not already started or
     56  *   awaiting its close callback.
     57  * - The idle_2 watcher always exists but immediately closes itself after
     58  *   being started by a check_1 watcher. It verifies that a watcher is
     59  *   implicitly stopped when closed, and that a watcher can close itself
     60  *   safely.
     61  * - There is a repeating timer. It does not keep the event loop alive
     62  *   (ev_unref) but makes sure that the loop keeps polling the system for
     63  *   events.
     64  */
     65 
     66 
     67 #include "uv.h"
     68 #include "task.h"
     69 
     70 #include <math.h>
     71 
     72 
     73 #define IDLE_COUNT      7
     74 #define ITERATIONS      21
     75 #define TIMEOUT         100
     76 
     77 
     78 static uv_prepare_t prepare_1_handle;
     79 static uv_prepare_t prepare_2_handle;
     80 
     81 static uv_check_t check_handle;
     82 
     83 static uv_idle_t idle_1_handles[IDLE_COUNT];
     84 static uv_idle_t idle_2_handle;
     85 
     86 static uv_timer_t timer_handle;
     87 
     88 
     89 static int loop_iteration = 0;
     90 
     91 static int prepare_1_cb_called = 0;
     92 static int prepare_1_close_cb_called = 0;
     93 
     94 static int prepare_2_cb_called = 0;
     95 static int prepare_2_close_cb_called = 0;
     96 
     97 static int check_cb_called = 0;
     98 static int check_close_cb_called = 0;
     99 
    100 static int idle_1_cb_called = 0;
    101 static int idle_1_close_cb_called = 0;
    102 static int idles_1_active = 0;
    103 
    104 static int idle_2_cb_called = 0;
    105 static int idle_2_close_cb_called = 0;
    106 static int idle_2_cb_started = 0;
    107 static int idle_2_is_active = 0;
    108 
    109 
    110 static void timer_cb(uv_timer_t* handle) {
    111   ASSERT_PTR_EQ(handle, &timer_handle);
    112 }
    113 
    114 
    115 static void idle_2_close_cb(uv_handle_t* handle) {
    116   fprintf(stderr, "%s", "IDLE_2_CLOSE_CB\n");
    117   fflush(stderr);
    118 
    119   ASSERT_PTR_EQ(handle, (uv_handle_t*)&idle_2_handle);
    120 
    121   ASSERT(idle_2_is_active);
    122 
    123   idle_2_close_cb_called++;
    124   idle_2_is_active = 0;
    125 }
    126 
    127 
    128 static void idle_2_cb(uv_idle_t* handle) {
    129   fprintf(stderr, "%s", "IDLE_2_CB\n");
    130   fflush(stderr);
    131 
    132   ASSERT_PTR_EQ(handle, &idle_2_handle);
    133 
    134   idle_2_cb_called++;
    135 
    136   uv_close((uv_handle_t*)handle, idle_2_close_cb);
    137 }
    138 
    139 
    140 static void idle_1_cb(uv_idle_t* handle) {
    141   int r;
    142 
    143   fprintf(stderr, "%s", "IDLE_1_CB\n");
    144   fflush(stderr);
    145 
    146   ASSERT_NOT_NULL(handle);
    147   ASSERT_GT(idles_1_active, 0);
    148 
    149   /* Init idle_2 and make it active */
    150   if (!idle_2_is_active && !uv_is_closing((uv_handle_t*)&idle_2_handle)) {
    151     r = uv_idle_init(uv_default_loop(), &idle_2_handle);
    152     ASSERT_OK(r);
    153     r = uv_idle_start(&idle_2_handle, idle_2_cb);
    154     ASSERT_OK(r);
    155     idle_2_is_active = 1;
    156     idle_2_cb_started++;
    157   }
    158 
    159   idle_1_cb_called++;
    160 
    161   if (idle_1_cb_called % 5 == 0) {
    162     r = uv_idle_stop((uv_idle_t*)handle);
    163     ASSERT_OK(r);
    164     idles_1_active--;
    165   }
    166 }
    167 
    168 
    169 static void idle_1_close_cb(uv_handle_t* handle) {
    170   fprintf(stderr, "%s", "IDLE_1_CLOSE_CB\n");
    171   fflush(stderr);
    172 
    173   ASSERT_NOT_NULL(handle);
    174 
    175   idle_1_close_cb_called++;
    176 }
    177 
    178 
    179 static void prepare_1_close_cb(uv_handle_t* handle) {
    180   fprintf(stderr, "%s", "PREPARE_1_CLOSE_CB");
    181   fflush(stderr);
    182   ASSERT_PTR_EQ(handle, (uv_handle_t*)&prepare_1_handle);
    183 
    184   prepare_1_close_cb_called++;
    185 }
    186 
    187 
    188 static void check_close_cb(uv_handle_t* handle) {
    189   fprintf(stderr, "%s", "CHECK_CLOSE_CB\n");
    190   fflush(stderr);
    191   ASSERT_PTR_EQ(handle, (uv_handle_t*)&check_handle);
    192 
    193   check_close_cb_called++;
    194 }
    195 
    196 
    197 static void prepare_2_close_cb(uv_handle_t* handle) {
    198   fprintf(stderr, "%s", "PREPARE_2_CLOSE_CB\n");
    199   fflush(stderr);
    200   ASSERT_PTR_EQ(handle, (uv_handle_t*)&prepare_2_handle);
    201 
    202   prepare_2_close_cb_called++;
    203 }
    204 
    205 
    206 static void check_cb(uv_check_t* handle) {
    207   int i, r;
    208 
    209   fprintf(stderr, "%s", "CHECK_CB\n");
    210   fflush(stderr);
    211   ASSERT_PTR_EQ(handle, &check_handle);
    212 
    213   if (loop_iteration < ITERATIONS) {
    214     /* Make some idle watchers active */
    215     for (i = 0; i < 1 + (loop_iteration % IDLE_COUNT); i++) {
    216       r = uv_idle_start(&idle_1_handles[i], idle_1_cb);
    217       ASSERT_OK(r);
    218       idles_1_active++;
    219     }
    220 
    221   } else {
    222     /* End of the test - close all handles */
    223     uv_close((uv_handle_t*)&prepare_1_handle, prepare_1_close_cb);
    224     uv_close((uv_handle_t*)&check_handle, check_close_cb);
    225     uv_close((uv_handle_t*)&prepare_2_handle, prepare_2_close_cb);
    226 
    227     for (i = 0; i < IDLE_COUNT; i++) {
    228       uv_close((uv_handle_t*)&idle_1_handles[i], idle_1_close_cb);
    229     }
    230 
    231     /* This handle is closed/recreated every time, close it only if it is
    232      * active. */
    233     if (idle_2_is_active) {
    234       uv_close((uv_handle_t*)&idle_2_handle, idle_2_close_cb);
    235     }
    236   }
    237 
    238   check_cb_called++;
    239 }
    240 
    241 
    242 static void prepare_2_cb(uv_prepare_t* handle) {
    243   int r;
    244 
    245   fprintf(stderr, "%s", "PREPARE_2_CB\n");
    246   fflush(stderr);
    247   ASSERT_PTR_EQ(handle, &prepare_2_handle);
    248 
    249   /* Prepare_2 gets started by prepare_1 when (loop_iteration % 2 == 0), and it
    250    * stops itself immediately. A started watcher is not queued until the next
    251    * round, so when this callback is made (loop_iteration % 2 == 0) cannot be
    252    * true. */
    253   ASSERT_NE(0, loop_iteration % 2);
    254 
    255   r = uv_prepare_stop((uv_prepare_t*)handle);
    256   ASSERT_OK(r);
    257 
    258   prepare_2_cb_called++;
    259 }
    260 
    261 
    262 static void prepare_1_cb(uv_prepare_t* handle) {
    263   int r;
    264 
    265   fprintf(stderr, "%s", "PREPARE_1_CB\n");
    266   fflush(stderr);
    267   ASSERT_PTR_EQ(handle, &prepare_1_handle);
    268 
    269   if (loop_iteration % 2 == 0) {
    270     r = uv_prepare_start(&prepare_2_handle, prepare_2_cb);
    271     ASSERT_OK(r);
    272   }
    273 
    274   prepare_1_cb_called++;
    275   loop_iteration++;
    276 
    277   printf("Loop iteration %d of %d.\n", loop_iteration, ITERATIONS);
    278 }
    279 
    280 
    281 TEST_IMPL(loop_handles) {
    282   int i;
    283   int r;
    284 
    285   r = uv_prepare_init(uv_default_loop(), &prepare_1_handle);
    286   ASSERT_OK(r);
    287   r = uv_prepare_start(&prepare_1_handle, prepare_1_cb);
    288   ASSERT_OK(r);
    289 
    290   r = uv_check_init(uv_default_loop(), &check_handle);
    291   ASSERT_OK(r);
    292   r = uv_check_start(&check_handle, check_cb);
    293   ASSERT_OK(r);
    294 
    295   /* initialize only, prepare_2 is started by prepare_1_cb */
    296   r = uv_prepare_init(uv_default_loop(), &prepare_2_handle);
    297   ASSERT_OK(r);
    298 
    299   for (i = 0; i < IDLE_COUNT; i++) {
    300     /* initialize only, idle_1 handles are started by check_cb */
    301     r = uv_idle_init(uv_default_loop(), &idle_1_handles[i]);
    302     ASSERT_OK(r);
    303   }
    304 
    305   /* don't init or start idle_2, both is done by idle_1_cb */
    306 
    307   /* The timer callback is there to keep the event loop polling unref it as it
    308    * is not supposed to keep the loop alive */
    309   r = uv_timer_init(uv_default_loop(), &timer_handle);
    310   ASSERT_OK(r);
    311   r = uv_timer_start(&timer_handle, timer_cb, TIMEOUT, TIMEOUT);
    312   ASSERT_OK(r);
    313   uv_unref((uv_handle_t*)&timer_handle);
    314 
    315   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    316   ASSERT_OK(r);
    317 
    318   ASSERT_EQ(loop_iteration, ITERATIONS);
    319 
    320   ASSERT_EQ(prepare_1_cb_called, ITERATIONS);
    321   ASSERT_EQ(1, prepare_1_close_cb_called);
    322 
    323   ASSERT_EQ(prepare_2_cb_called, ITERATIONS / 2);
    324   ASSERT_EQ(1, prepare_2_close_cb_called);
    325 
    326   ASSERT_EQ(check_cb_called, ITERATIONS);
    327   ASSERT_EQ(1, check_close_cb_called);
    328 
    329   /* idle_1_cb should be called a lot */
    330   ASSERT_EQ(idle_1_close_cb_called, IDLE_COUNT);
    331 
    332   ASSERT_EQ(idle_2_close_cb_called, idle_2_cb_started);
    333   ASSERT_OK(idle_2_is_active);
    334 
    335   MAKE_VALGRIND_HAPPY(uv_default_loop());
    336   return 0;
    337 }
    338