]>
git.proxmox.com Git - mirror_frr.git/blob - tests/lib/test_nexthop_iter.c
2 * Recursive Nexthop Iterator test.
3 * This tests the ALL_NEXTHOPS macro.
5 * Copyright (C) 2012 by Open Source Routing.
6 * Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
8 * This file is part of Quagga
10 * Quagga is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2, or (at your option) any
15 * Quagga is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; see the file COPYING; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 #include "zebra/rib.h"
29 struct thread_master
*master
;
32 static void str_append(char **buf
, const char *repr
)
35 *buf
= realloc(*buf
, strlen(*buf
) + strlen(repr
) + 1);
37 strncpy((*buf
) + strlen(*buf
), repr
, strlen(repr
) + 1);
45 static void str_appendf(char **buf
, const char *format
, ...)
52 rv
= vasprintf(&pbuf
, format
, ap
);
56 str_append(buf
, pbuf
);
60 /* This structure contains a nexthop chain
61 * and its expected representation */
62 struct nexthop_chain
{
63 /* Head of the chain */
64 struct nexthop_group head
;
65 /* Last nexthop in top chain */
66 struct nexthop
*current_top
;
67 /* Last nexthop in current recursive chain */
68 struct nexthop
*current_recursive
;
69 /* Expected string representation. */
73 static struct nexthop_chain
*nexthop_chain_new(void)
75 struct nexthop_chain
*rv
;
77 rv
= calloc(sizeof(*rv
), 1);
82 static void nexthop_chain_add_top(struct nexthop_chain
*nc
)
86 nh
= calloc(sizeof(*nh
), 1);
89 if (nc
->head
.nexthop
) {
90 nc
->current_top
->next
= nh
;
91 nh
->prev
= nc
->current_top
;
94 nc
->head
.nexthop
= nc
->current_top
= nh
;
96 nc
->current_recursive
= NULL
;
97 str_appendf(&nc
->repr
, "%p\n", nh
);
100 static void add_string_representation(char **repr
, struct nexthop
*nh
)
102 struct nexthop
*parent
;
104 /* add indentations first */
105 parent
= nh
->rparent
;
107 str_appendf(repr
, " ");
108 parent
= parent
->rparent
;
110 str_appendf(repr
, "%p\n", nh
);
113 static void start_recursive_chain(struct nexthop_chain
*nc
, struct nexthop
*nh
)
115 SET_FLAG(nc
->current_top
->flags
, NEXTHOP_FLAG_RECURSIVE
);
116 nc
->current_top
->resolved
= nh
;
117 nh
->rparent
= nc
->current_top
;
118 nc
->current_recursive
= nh
;
120 static void nexthop_chain_add_recursive(struct nexthop_chain
*nc
)
124 nh
= calloc(sizeof(*nh
), 1);
127 assert(nc
->current_top
);
128 if (nc
->current_recursive
) {
129 nc
->current_recursive
->next
= nh
;
130 nh
->prev
= nc
->current_recursive
;
131 nh
->rparent
= nc
->current_recursive
->rparent
;
132 nc
->current_recursive
= nh
;
134 start_recursive_chain(nc
, nh
);
136 add_string_representation(&nc
->repr
, nh
);
139 static void nexthop_chain_add_recursive_level(struct nexthop_chain
*nc
)
143 nh
= calloc(sizeof(*nh
), 1);
146 assert(nc
->current_top
);
147 if (nc
->current_recursive
) {
148 SET_FLAG(nc
->current_recursive
->flags
, NEXTHOP_FLAG_RECURSIVE
);
149 nc
->current_recursive
->resolved
= nh
;
150 nh
->rparent
= nc
->current_recursive
;
151 nc
->current_recursive
= nh
;
153 start_recursive_chain(nc
, nh
);
155 add_string_representation(&nc
->repr
, nh
);
158 static void nexthop_clear_recursive(struct nexthop
*tcur
)
162 if (CHECK_FLAG(tcur
->flags
, NEXTHOP_FLAG_RECURSIVE
))
163 nexthop_clear_recursive(tcur
->resolved
);
165 nexthop_clear_recursive(tcur
->next
);
168 static void nexthop_chain_clear(struct nexthop_chain
*nc
)
170 nexthop_clear_recursive(nc
->head
.nexthop
);
171 nc
->head
.nexthop
= nc
->current_top
= nc
->current_recursive
= NULL
;
176 static void nexthop_chain_free(struct nexthop_chain
*nc
)
180 nexthop_chain_clear(nc
);
184 /* This function builds a string representation of
185 * the nexthop chain using the ALL_NEXTHOPS macro.
186 * It verifies that the ALL_NEXTHOPS macro iterated
187 * correctly over the nexthop chain by comparing the
188 * generated representation with the expected representation.
190 static void nexthop_chain_verify_iter(struct nexthop_chain
*nc
)
195 for (ALL_NEXTHOPS(nc
->head
, nh
))
196 add_string_representation(&repr
, nh
);
199 printf("===\n%s", repr
);
200 assert((!repr
&& !nc
->repr
)
201 || (repr
&& nc
->repr
&& !strcmp(repr
, nc
->repr
)));
205 /* This test run builds a simple nexthop chain
206 * with some recursive nexthops and verifies that
207 * the iterator works correctly in each stage along
210 static void test_run_first(void)
212 struct nexthop_chain
*nc
;
214 nc
= nexthop_chain_new();
215 nexthop_chain_verify_iter(nc
);
217 nexthop_chain_add_top(nc
);
218 nexthop_chain_verify_iter(nc
);
220 nexthop_chain_add_top(nc
);
221 nexthop_chain_verify_iter(nc
);
223 nexthop_chain_add_recursive(nc
);
224 nexthop_chain_verify_iter(nc
);
226 nexthop_chain_add_recursive(nc
);
227 nexthop_chain_verify_iter(nc
);
229 nexthop_chain_add_top(nc
);
230 nexthop_chain_verify_iter(nc
);
232 nexthop_chain_add_top(nc
);
233 nexthop_chain_verify_iter(nc
);
235 nexthop_chain_add_top(nc
);
236 nexthop_chain_verify_iter(nc
);
238 nexthop_chain_add_recursive(nc
);
239 nexthop_chain_verify_iter(nc
);
241 nexthop_chain_add_recursive(nc
);
242 nexthop_chain_verify_iter(nc
);
244 nexthop_chain_add_recursive(nc
);
245 nexthop_chain_verify_iter(nc
);
247 nexthop_chain_add_recursive_level(nc
);
248 nexthop_chain_verify_iter(nc
);
250 nexthop_chain_add_recursive(nc
);
251 nexthop_chain_verify_iter(nc
);
253 nexthop_chain_add_recursive(nc
);
254 nexthop_chain_verify_iter(nc
);
256 nexthop_chain_add_top(nc
);
257 nexthop_chain_verify_iter(nc
);
259 nexthop_chain_free(nc
);
262 /* This test run builds numerous random
263 * nexthop chain configurations and verifies
264 * that the iterator correctly progresses
266 static void test_run_prng(void)
268 struct nexthop_chain
*nc
;
272 nc
= nexthop_chain_new();
275 for (i
= 0; i
< 1000000; i
++) {
276 switch (prng_rand(prng
) % 10) {
278 nexthop_chain_clear(nc
);
285 nexthop_chain_add_top(nc
);
291 nexthop_chain_add_recursive(nc
);
295 nexthop_chain_add_recursive_level(nc
);
298 nexthop_chain_verify_iter(nc
);
300 nexthop_chain_free(nc
);
304 int main(int argc
, char **argv
)
306 if (argc
>= 2 && !strcmp("-v", argv
[1]))
309 printf("Simple test passed.\n");
311 printf("PRNG test passed.\n");