Notification iterator: transform precondition checks to BT_ASSERT_PRE()
[babeltrace.git] / tests / lib / test_bt_notification_heap.c
1 /*
2 * test_bt_notification_heap.c
3 *
4 * bt_notification_heap tests
5 *
6 * Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; under version 2 of the License.
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include "tap/tap.h"
23 #include <stdlib.h>
24 #include <babeltrace/compiler-internal.h>
25 #include <babeltrace/ref.h>
26 #include <babeltrace/graph/notification-heap.h>
27 #include <babeltrace/graph/notification.h>
28 #include <babeltrace/graph/notification-internal.h>
29
30 #define NR_TESTS 7
31
32 struct dummy_notification {
33 struct bt_notification parent;
34 uint64_t value;
35 };
36
37 static
38 void dummy_notification_destroy(struct bt_object *obj)
39 {
40 g_free(obj);
41 }
42
43 /* Reproduced from internal notification.c code. */
44 void bt_notification_init(struct bt_notification *notification,
45 enum bt_notification_type type,
46 bt_object_release_func release)
47 {
48 assert(type > 0 && type < BT_NOTIFICATION_TYPE_NR);
49 notification->type = type;
50 bt_object_init(&notification->base, release);
51 }
52
53 static
54 struct bt_notification *dummy_notification_create(uint64_t value)
55 {
56 struct dummy_notification *notification;
57
58 notification = g_new0(struct dummy_notification, 1);
59 if (!notification) {
60 goto error;
61 }
62 bt_notification_init(&notification->parent,
63 BT_NOTIFICATION_TYPE_NR - 1 /* dummy value */,
64 dummy_notification_destroy);
65 notification->value = value;
66 return &notification->parent;
67 error:
68 return NULL;
69 }
70
71 static
72 bt_bool compare_notifications(struct bt_notification *a, struct bt_notification *b,
73 void *unused)
74 {
75 uint64_t val_a = ((struct dummy_notification *) a)->value;
76 uint64_t val_b = ((struct dummy_notification *) b)->value;
77
78 if (val_a == val_b) {
79 return a < b;
80 } else {
81 return val_a < val_b;
82 }
83 }
84
85 int main(int argc, char **argv)
86 {
87 int i;
88 uint64_t last_read_value = 0;
89 struct bt_notification_heap *heap = NULL;
90
91 /* Initialize tap harness before any tests */
92 plan_tests(NR_TESTS);
93 heap = bt_notification_heap_create(compare_notifications, NULL);
94 ok(heap, "Created a notification heap");
95
96 /* Insert 10 000 notifications with random values. */
97 for (i = 0; i < 10000; i++) {
98 int ret;
99 struct bt_notification *notification =
100 dummy_notification_create(rand());
101
102 if (!notification) {
103 diag("Dummy notification creation failed");
104 goto end;
105 }
106
107 ret = bt_notification_heap_insert(heap, notification);
108 if (ret) {
109 diag("Failed to insert notification %i in heap", i);
110 goto end;
111 }
112 bt_put(notification);
113 }
114 pass("Inserted 10 000 random notifications in notification heap");
115
116 /* Pop 5000 notifications, making sure the values read are ascending */
117 for (i = 0; i < 5000; i++) {
118 struct bt_notification *pop_notification;
119 struct bt_notification *peek_notification;
120 struct dummy_notification *dummy;
121
122 peek_notification = bt_notification_heap_peek(heap);
123 if (!peek_notification) {
124 fail("Failed to peek a notification");
125 goto end;
126 }
127
128 pop_notification = bt_notification_heap_pop(heap);
129 if (!pop_notification) {
130 fail("Failed to pop a notification");
131 goto end;
132 }
133
134 if (peek_notification != pop_notification) {
135 fail("bt_notification_heap_peek and bt_notification_heap_pop do not return the same notification");
136 bt_put(peek_notification);
137 bt_put(pop_notification);
138 goto end;
139 }
140
141 dummy = container_of(pop_notification,
142 struct dummy_notification, parent);
143 if (dummy->value < last_read_value) {
144 fail("Notification heap did not provide notifications in ascending order");
145 }
146 last_read_value = dummy->value;
147 bt_put(peek_notification);
148 bt_put(pop_notification);
149 }
150
151 pass("bt_notification_heap_peek and bt_notification_heap_pop return the same notification");
152 pass("Notification heap provided 5 000 notifications in ascending order");
153
154 /* Insert 10 000 notifications with random values. */
155 for (i = 0; i < 10000; i++) {
156 int ret;
157 struct bt_notification *notification =
158 dummy_notification_create(rand());
159
160 if (!notification) {
161 diag("Dummy notification creation failed");
162 goto end;
163 }
164
165 ret = bt_notification_heap_insert(heap, notification);
166 if (ret) {
167 diag("Failed to insert notification %i in heap", i);
168 goto end;
169 }
170 bt_put(notification);
171 }
172 pass("Inserted 10 000 random notifications in notification heap after popping");
173
174 last_read_value = 0;
175 /* Pop remaining 15 000 notifications, making sure the values read are ascending */
176 for (i = 0; i < 15000; i++) {
177 struct bt_notification *pop_notification;
178 struct dummy_notification *dummy;
179
180 pop_notification = bt_notification_heap_pop(heap);
181 if (!pop_notification) {
182 fail("Failed to pop a notification");
183 goto end;
184 }
185 dummy = container_of(pop_notification,
186 struct dummy_notification, parent);
187 if (dummy->value < last_read_value) {
188 fail("Notification heap did not provide notifications in ascending order");
189 }
190 last_read_value = dummy->value;
191 bt_put(pop_notification);
192 }
193 pass("Popped remaining 15 000 notifications from heap in ascending order");
194
195 ok(!bt_notification_heap_peek(heap), "No notifications left in heap");
196 end:
197 bt_put(heap);
198 return exit_status();
199 }
This page took 0.032931 seconds and 4 git commands to generate.