Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : #include "src/core/iomgr/alarm.h"
35 :
36 : #include <string.h>
37 :
38 : #include "src/core/iomgr/alarm_internal.h"
39 : #include <grpc/support/log.h>
40 : #include "test/core/util/test_config.h"
41 :
42 : #define MAX_CB 30
43 :
44 : static int cb_called[MAX_CB][2];
45 :
46 25 : static void cb(grpc_exec_ctx *exec_ctx, void *arg, int success) {
47 25 : cb_called[(gpr_intptr)arg][success]++;
48 25 : }
49 :
50 1 : static void add_test(void) {
51 1 : gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME);
52 : int i;
53 : grpc_alarm alarms[20];
54 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
55 :
56 1 : grpc_alarm_list_init(start);
57 1 : memset(cb_called, 0, sizeof(cb_called));
58 :
59 : /* 10 ms alarms. will expire in the current epoch */
60 11 : for (i = 0; i < 10; i++) {
61 10 : grpc_alarm_init(&exec_ctx, &alarms[i],
62 : gpr_time_add(start, gpr_time_from_millis(10, GPR_TIMESPAN)),
63 10 : cb, (void *)(gpr_intptr)i, start);
64 : }
65 :
66 : /* 1010 ms alarms. will expire in the next epoch */
67 11 : for (i = 10; i < 20; i++) {
68 10 : grpc_alarm_init(
69 : &exec_ctx, &alarms[i],
70 : gpr_time_add(start, gpr_time_from_millis(1010, GPR_TIMESPAN)), cb,
71 10 : (void *)(gpr_intptr)i, start);
72 : }
73 :
74 : /* collect alarms. Only the first batch should be ready. */
75 1 : GPR_ASSERT(10 == grpc_alarm_check(&exec_ctx,
76 : gpr_time_add(start, gpr_time_from_millis(
77 : 500, GPR_TIMESPAN)),
78 : NULL));
79 1 : grpc_exec_ctx_finish(&exec_ctx);
80 21 : for (i = 0; i < 20; i++) {
81 20 : GPR_ASSERT(cb_called[i][1] == (i < 10));
82 20 : GPR_ASSERT(cb_called[i][0] == 0);
83 : }
84 :
85 1 : GPR_ASSERT(0 == grpc_alarm_check(&exec_ctx,
86 : gpr_time_add(start, gpr_time_from_millis(
87 : 600, GPR_TIMESPAN)),
88 : NULL));
89 1 : grpc_exec_ctx_finish(&exec_ctx);
90 31 : for (i = 0; i < 30; i++) {
91 30 : GPR_ASSERT(cb_called[i][1] == (i < 10));
92 30 : GPR_ASSERT(cb_called[i][0] == 0);
93 : }
94 :
95 : /* collect the rest of the alarms */
96 1 : GPR_ASSERT(10 == grpc_alarm_check(
97 : &exec_ctx, gpr_time_add(start, gpr_time_from_millis(
98 : 1500, GPR_TIMESPAN)),
99 : NULL));
100 1 : grpc_exec_ctx_finish(&exec_ctx);
101 31 : for (i = 0; i < 30; i++) {
102 30 : GPR_ASSERT(cb_called[i][1] == (i < 20));
103 30 : GPR_ASSERT(cb_called[i][0] == 0);
104 : }
105 :
106 1 : GPR_ASSERT(0 == grpc_alarm_check(&exec_ctx,
107 : gpr_time_add(start, gpr_time_from_millis(
108 : 1600, GPR_TIMESPAN)),
109 : NULL));
110 31 : for (i = 0; i < 30; i++) {
111 30 : GPR_ASSERT(cb_called[i][1] == (i < 20));
112 30 : GPR_ASSERT(cb_called[i][0] == 0);
113 : }
114 :
115 1 : grpc_alarm_list_shutdown(&exec_ctx);
116 1 : grpc_exec_ctx_finish(&exec_ctx);
117 1 : }
118 :
119 6 : static gpr_timespec tfm(int m) {
120 6 : gpr_timespec t = gpr_time_from_millis(m, GPR_TIMESPAN);
121 6 : t.clock_type = GPR_CLOCK_REALTIME;
122 6 : return t;
123 : }
124 :
125 : /* Cleaning up a list with pending alarms. */
126 1 : void destruction_test(void) {
127 : grpc_alarm alarms[5];
128 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
129 :
130 1 : grpc_alarm_list_init(gpr_time_0(GPR_CLOCK_REALTIME));
131 1 : memset(cb_called, 0, sizeof(cb_called));
132 :
133 1 : grpc_alarm_init(&exec_ctx, &alarms[0], tfm(100), cb, (void *)(gpr_intptr)0,
134 : gpr_time_0(GPR_CLOCK_REALTIME));
135 1 : grpc_alarm_init(&exec_ctx, &alarms[1], tfm(3), cb, (void *)(gpr_intptr)1,
136 : gpr_time_0(GPR_CLOCK_REALTIME));
137 1 : grpc_alarm_init(&exec_ctx, &alarms[2], tfm(100), cb, (void *)(gpr_intptr)2,
138 : gpr_time_0(GPR_CLOCK_REALTIME));
139 1 : grpc_alarm_init(&exec_ctx, &alarms[3], tfm(3), cb, (void *)(gpr_intptr)3,
140 : gpr_time_0(GPR_CLOCK_REALTIME));
141 1 : grpc_alarm_init(&exec_ctx, &alarms[4], tfm(1), cb, (void *)(gpr_intptr)4,
142 : gpr_time_0(GPR_CLOCK_REALTIME));
143 1 : GPR_ASSERT(1 == grpc_alarm_check(&exec_ctx, tfm(2), NULL));
144 1 : grpc_exec_ctx_finish(&exec_ctx);
145 1 : GPR_ASSERT(1 == cb_called[4][1]);
146 1 : grpc_alarm_cancel(&exec_ctx, &alarms[0]);
147 1 : grpc_alarm_cancel(&exec_ctx, &alarms[3]);
148 1 : grpc_exec_ctx_finish(&exec_ctx);
149 1 : GPR_ASSERT(1 == cb_called[0][0]);
150 1 : GPR_ASSERT(1 == cb_called[3][0]);
151 :
152 1 : grpc_alarm_list_shutdown(&exec_ctx);
153 1 : grpc_exec_ctx_finish(&exec_ctx);
154 1 : GPR_ASSERT(1 == cb_called[1][0]);
155 1 : GPR_ASSERT(1 == cb_called[2][0]);
156 1 : }
157 :
158 1 : int main(int argc, char **argv) {
159 1 : grpc_test_init(argc, argv);
160 1 : add_test();
161 1 : destruction_test();
162 1 : return 0;
163 : }
|