summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am13
-rw-r--r--tests/aspath_test.c269
-rw-r--r--tests/bgp_capability_test.c145
-rw-r--r--tests/bgp_mp_attr_test.c139
-rw-r--r--tests/ecommunity_test.c27
-rw-r--r--tests/heavy-thread.c26
-rw-r--r--tests/heavy-wq.c54
-rw-r--r--tests/heavy.c26
-rw-r--r--tests/main.c34
-rw-r--r--tests/test-checksum.c101
-rw-r--r--tests/test-list_util.c2112
-rw-r--r--tests/test-privs.c28
-rw-r--r--tests/test-sig.c10
-rw-r--r--tests/test-stream.c10
-rw-r--r--tests/test-symtab.c344
-rw-r--r--tests/test-vector.c1377
16 files changed, 4298 insertions, 417 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4ab507bb..d6e24db7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -5,8 +5,9 @@ AM_CFLAGS = $(PICFLAGS)
AM_LDFLAGS = $(PILDFLAGS)
noinst_PROGRAMS = testsig testbuffer testmemory heavy heavywq heavythread \
- aspathtest testprivs teststream testbgpcap ecommtest \
- testbgpmpattr testchecksum
+ aspathtest testprivs teststream testbgpcap ecommtest \
+ testbgpmpattr testchecksum testvector testsymtab \
+ testlistutil
testsig_SOURCES = test-sig.c
testbuffer_SOURCES = test-buffer.c
@@ -21,6 +22,9 @@ testbgpcap_SOURCES = bgp_capability_test.c
ecommtest_SOURCES = ecommunity_test.c
testbgpmpattr_SOURCES = bgp_mp_attr_test.c
testchecksum_SOURCES = test-checksum.c
+testvector_SOURCES = test-vector.c
+testsymtab_SOURCES = test-symtab.c
+testlistutil_SOURCES = test-list_util.c
testsig_LDADD = ../lib/libzebra.la @LIBCAP@
testbuffer_LDADD = ../lib/libzebra.la @LIBCAP@
@@ -34,4 +38,7 @@ aspathtest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a
testbgpcap_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a
ecommtest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a
testbgpmpattr_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a
-testchecksum_LDADD = ../lib/libzebra.la @LIBCAP@
+testchecksum_LDADD = ../lib/libzebra.la @LIBCAP@
+testvector_LDADD = ../lib/libzebra.la @LIBCAP@
+testsymtab_LDADD = ../lib/libzebra.la @LIBCAP@
+testlistutil_LDADD = ../lib/libzebra.la @LIBCAP@
diff --git a/tests/aspath_test.c b/tests/aspath_test.c
index 4a2ce9aa..11008b25 100644
--- a/tests/aspath_test.c
+++ b/tests/aspath_test.c
@@ -22,7 +22,7 @@ struct thread_master *master = NULL;
static int failed = 0;
/* specification for a test - what the results should be */
-struct test_spec
+struct test_spec
{
const char *shouldbe; /* the string the path should parse to */
const char *shouldbe_delete_confed; /* ditto, but once confeds are deleted */
@@ -45,9 +45,9 @@ static struct test_segment {
const u_char asdata[1024];
int len;
struct test_spec sp;
-} test_segments [] =
+} test_segments [] =
{
- { /* 0 */
+ { /* 0 */
"seq1",
"seq(8466,3,52737,4096)",
{ 0x2,0x4, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00 },
@@ -69,7 +69,7 @@ static struct test_segment {
{ /* 2 */
"seq3",
"seq(8466,3,52737,4096,8722,4)",
- { 0x2,0x6, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00,
+ { 0x2,0x6, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00,
0x22,0x12, 0x00,0x04},
14,
{ "8466 3 52737 4096 8722 4",
@@ -91,7 +91,7 @@ static struct test_segment {
"seq(8467, 59649) set(4196,48658) set(17322,30745)",
{ 0x2,0x2, 0x21,0x13, 0xe9,0x01,
0x1,0x2, 0x10,0x64, 0xbe,0x12,
- 0x1,0x2, 0x43,0xaa, 0x78,0x19 },
+ 0x1,0x2, 0x43,0xaa, 0x78,0x19 },
18,
{ "8467 59649 {4196,48658} {17322,30745}",
"8467 59649 {4196,48658} {17322,30745}",
@@ -151,7 +151,7 @@ static struct test_segment {
{ /* 10 */
"seq4",
"seq(8466,2,52737,4096,8722,4)",
- { 0x2,0x6, 0x21,0x12, 0x00,0x02, 0xce,0x01, 0x10,0x00,
+ { 0x2,0x6, 0x21,0x12, 0x00,0x02, 0xce,0x01, 0x10,0x00,
0x22,0x12, 0x00,0x04},
14,
{ "8466 2 52737 4096 8722 4",
@@ -161,7 +161,7 @@ static struct test_segment {
{ /* 11 */
"tripleseq1",
"seq(8466,2,52737) seq(4096,8722,4) seq(8722)",
- { 0x2,0x3, 0x21,0x12, 0x00,0x02, 0xce,0x01,
+ { 0x2,0x3, 0x21,0x12, 0x00,0x02, 0xce,0x01,
0x2,0x3, 0x10,0x00, 0x22,0x12, 0x00,0x04,
0x2,0x1, 0x22,0x12},
20,
@@ -169,7 +169,7 @@ static struct test_segment {
"8466 2 52737 4096 8722 4 8722",
7, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
},
- { /* 12 */
+ { /* 12 */
"someprivate",
"seq(8466,64512,52737,65535)",
{ 0x2,0x4, 0x21,0x12, 0xfc,0x00, 0xce,0x01, 0xff,0xff },
@@ -178,7 +178,7 @@ static struct test_segment {
"8466 64512 52737 65535",
4, 0, NOT_ALL_PRIVATE, 65535, 4, 8466 },
},
- { /* 13 */
+ { /* 13 */
"allprivate",
"seq(65534,64512,64513,65535)",
{ 0x2,0x4, 0xff,0xfe, 0xfc,0x00, 0xfc,0x01, 0xff,0xff },
@@ -187,7 +187,7 @@ static struct test_segment {
"65534 64512 64513 65535",
4, 0, ALL_PRIVATE, 65534, 4, 65534 },
},
- { /* 14 */
+ { /* 14 */
"long",
"seq(8466,3,52737,4096,34285,<repeated 49 more times>)",
{ 0x2,0xfa, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
@@ -266,7 +266,7 @@ static struct test_segment {
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285",
-
+
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
@@ -294,7 +294,7 @@ static struct test_segment {
"8466 3 52737 4096 34285 8466 3 52737 4096 34285",
250, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
},
- { /* 15 */
+ { /* 15 */
"seq1extra",
"seq(8466,3,52737,4096,3456)",
{ 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
@@ -310,7 +310,7 @@ static struct test_segment {
0,
{ "", "", 0, 0, 0, 0, 0, 0 },
},
- { /* 17 */
+ { /* 17 */
"redundantset",
"seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153)",
{ 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80,
@@ -338,7 +338,7 @@ static struct test_segment {
{ /* 19 */
"reconcile_new_asp",
"set(2457,61697,4369), seq(1842,41591,51793)",
- {
+ {
0x1,0x3, 0x09,0x99, 0xf1,0x01, 0x11,0x11,
0x2,0x3, 0x07,0x32, 0xa2,0x77, 0xca,0x51 },
16,
@@ -391,7 +391,7 @@ static struct test_segment {
"23456 23456 23456 6435 59408",
5, 0, NOT_ALL_PRIVATE, 59408, 1, 23456 },
},
- { /* 24 */
+ { /* 24 */
"redundantset2",
"seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153,7099)",
{ 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80,
@@ -403,7 +403,7 @@ static struct test_segment {
"8466 3 52737 4096 3456 {7099,8153}",
6, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
},
- { /* 25 */
+ { /* 25 */
"zero-size overflow",
"#ASNs = 0, data = seq(8466 3 52737 4096 3456)",
{ 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
@@ -411,17 +411,17 @@ static struct test_segment {
{ NULL, NULL,
0, 0, 0, 0, 0, 0 },
},
- { /* 26 */
+ { /* 26 */
"zero-size overflow + valid segment",
"seq(#AS=0:8466 3 52737),seq(4096 3456)",
- { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01,
+ { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01,
0x2,0x2, 0x10,0x00, 0x0d,0x80 },
14
,
{ NULL, NULL,
0, 0, 0, 0, 0, 0 },
},
- { /* 27 */
+ { /* 27 */
"invalid segment type",
"type=8(4096 3456)",
{ 0x8,0x2, 0x10,0x00, 0x0d,0x80 },
@@ -453,7 +453,7 @@ static struct aspath_tests {
AS2_DATA, 0,
0,
{ BGP_ATTR_FLAG_TRANS,
- BGP_ATTR_AS_PATH,
+ BGP_ATTR_AS_PATH,
10,
},
3,
@@ -466,7 +466,7 @@ static struct aspath_tests {
AS2_DATA, -1,
0,
{ BGP_ATTR_FLAG_TRANS,
- BGP_ATTR_AS_PATH,
+ BGP_ATTR_AS_PATH,
8,
},
3,
@@ -479,7 +479,7 @@ static struct aspath_tests {
AS2_DATA, -1,
0,
{ BGP_ATTR_FLAG_TRANS,
- BGP_ATTR_AS_PATH,
+ BGP_ATTR_AS_PATH,
12,
},
3,
@@ -492,7 +492,7 @@ static struct aspath_tests {
AS2_DATA, -1,
0,
{ BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
- BGP_ATTR_AS_PATH,
+ BGP_ATTR_AS_PATH,
10,
},
3,
@@ -505,7 +505,7 @@ static struct aspath_tests {
AS2_DATA, -1,
0,
{ BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
- BGP_ATTR_AS4_PATH,
+ BGP_ATTR_AS4_PATH,
10,
},
3,
@@ -518,7 +518,7 @@ static struct aspath_tests {
AS4_DATA, -1,
PEER_CAP_AS4_RCV,
{ BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
- BGP_ATTR_AS4_PATH,
+ BGP_ATTR_AS4_PATH,
10,
},
3,
@@ -531,7 +531,7 @@ static struct aspath_tests {
AS4_DATA, 0,
PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
{ BGP_ATTR_FLAG_TRANS,
- BGP_ATTR_AS_PATH,
+ BGP_ATTR_AS_PATH,
18,
},
3,
@@ -544,7 +544,7 @@ static struct aspath_tests {
AS4_DATA, -1,
PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
{ BGP_ATTR_FLAG_TRANS,
- BGP_ATTR_AS_PATH,
+ BGP_ATTR_AS_PATH,
16,
},
3,
@@ -557,7 +557,7 @@ static struct aspath_tests {
AS4_DATA, -1,
PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
{ BGP_ATTR_FLAG_TRANS,
- BGP_ATTR_AS_PATH,
+ BGP_ATTR_AS_PATH,
20,
},
3,
@@ -570,7 +570,7 @@ static struct aspath_tests {
AS4_DATA, -1,
PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
{ BGP_ATTR_FLAG_TRANS,
- BGP_ATTR_AS_PATH,
+ BGP_ATTR_AS_PATH,
22,
},
3,
@@ -583,7 +583,7 @@ static struct aspath_tests {
AS4_DATA, -1,
PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
{ BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
- BGP_ATTR_AS_PATH,
+ BGP_ATTR_AS_PATH,
18,
},
3,
@@ -596,7 +596,7 @@ static struct aspath_tests {
AS4_DATA, -1,
PEER_CAP_AS4_ADV,
{ BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
- BGP_ATTR_AS4_PATH,
+ BGP_ATTR_AS4_PATH,
14,
},
3,
@@ -609,7 +609,7 @@ static struct tests {
const struct test_segment *test1;
const struct test_segment *test2;
struct test_spec sp;
-} prepend_tests[] =
+} prepend_tests[] =
{
/* 0 */
{ &test_segments[0], &test_segments[1],
@@ -691,7 +691,7 @@ static struct tests {
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 2 52737 4096 8722 4 8722",
-
+
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
@@ -757,7 +757,7 @@ struct tests reconcile_tests[] =
},
{ NULL, NULL, { NULL, 0, 0, 0, 0, 0, 0, } },
};
-
+
struct tests aggregate_tests[] =
{
{ &test_segments[0], &test_segments[2],
@@ -790,7 +790,7 @@ struct tests aggregate_tests[] =
{ NULL, NULL, { NULL, 0, 0} },
};
-struct compare_tests
+struct compare_tests
{
int test_index1;
int test_index2;
@@ -830,17 +830,17 @@ make_aspath (const u_char *data, size_t len, int use32bit)
{
struct stream *s = NULL;
struct aspath *as;
-
+
if (len)
{
s = stream_new (len);
stream_put (s, data, len);
}
- as = aspath_parse (s, len, use32bit);
-
+ as = aspath_parse (s, len, use32bit, 0);
+
if (s)
stream_free (s);
-
+
return as;
}
@@ -857,7 +857,7 @@ printbytes (const u_char *bytes, int len)
i++;
}
printf ("\n");
-}
+}
/* validate the given aspath */
static int
@@ -868,33 +868,33 @@ validate (struct aspath *as, const struct test_spec *sp)
const u_char *out;
static struct stream *s;
struct aspath *asinout, *asconfeddel, *asstr, *as4;
-
+
if (as == NULL && sp->shouldbe == NULL)
{
printf ("Correctly failed to parse\n");
return fails;
}
-
+
out = aspath_snmp_pathseg (as, &bytes);
asinout = make_aspath (out, bytes, 0);
-
+
/* Excercise AS4 parsing a bit, with a dogfood test */
if (!s)
s = stream_new (4096);
bytes4 = aspath_put (s, as, 1);
as4 = make_aspath (STREAM_DATA(s), bytes4, 1);
-
+
asstr = aspath_str2aspath (sp->shouldbe);
-
+
asconfeddel = aspath_delete_confed_seq (aspath_dup (asinout));
-
+
printf ("got: %s\n", aspath_print(as));
-
+
/* the parsed path should match the specified 'shouldbe' string.
* We should pass the "eat our own dog food" test, be able to output
* this path and then input it again. Ie the path resulting from:
*
- * aspath_parse(aspath_put(as))
+ * aspath_parse(aspath_put(as))
*
* should:
*
@@ -909,7 +909,7 @@ validate (struct aspath *as, const struct test_spec *sp)
*
* aspath_parse(aspath_put(as,USE32BIT))
*
- * Confederation related tests:
+ * Confederation related tests:
* - aspath_delete_confed_seq(aspath) should match shouldbe_confed
* - aspath_delete_confed_seq should be idempotent.
*/
@@ -930,9 +930,9 @@ validate (struct aspath *as, const struct test_spec *sp)
fails++;
printf ("shouldbe:\n%s\n", sp->shouldbe);
printf ("as4:\n%s\n", aspath_print (as4));
- printf ("hash keys: in: %d out->in: %d\n",
+ printf ("hash keys: in: %d out->in: %d\n",
aspath_key_make (as), aspath_key_make (asinout));
- printf ("hops: %d, counted %d %d\n", sp->hops,
+ printf ("hops: %d, counted %d %d\n", sp->hops,
aspath_count_hops (as),
aspath_count_hops (asinout) );
printf ("confeds: %d, counted %d %d\n", sp->confeds,
@@ -942,13 +942,13 @@ validate (struct aspath *as, const struct test_spec *sp)
printbytes (out, bytes);
}
/* basic confed related tests */
- if ((aspath_print (asconfeddel) == NULL
+ if ((aspath_print (asconfeddel) == NULL
&& sp->shouldbe_delete_confed != NULL)
- || (aspath_print (asconfeddel) != NULL
+ || (aspath_print (asconfeddel) != NULL
&& sp->shouldbe_delete_confed == NULL)
|| strcmp(aspath_print (asconfeddel), sp->shouldbe_delete_confed)
/* delete_confed_seq should be idempotent */
- || (aspath_key_make (asconfeddel)
+ || (aspath_key_make (asconfeddel)
!= aspath_key_make (aspath_delete_confed_seq (asconfeddel))))
{
failed++;
@@ -965,7 +965,7 @@ validate (struct aspath *as, const struct test_spec *sp)
fails++;
printf ("asstr: %s\n", aspath_print (asstr));
}
-
+
/* loop, private and first as checks */
if ((sp->does_loop && aspath_loop_check (as, sp->does_loop) == 0)
|| (sp->doesnt_loop && aspath_loop_check (as, sp->doesnt_loop) != 0)
@@ -983,13 +983,13 @@ validate (struct aspath *as, const struct test_spec *sp)
printf ("private check: %d %d\n", sp->private_as,
aspath_private_as_check (as));
}
- aspath_unintern (asinout);
- aspath_unintern (as4);
-
+ aspath_unintern (&asinout);
+ aspath_unintern (&as4);
+
aspath_free (asconfeddel);
aspath_free (asstr);
stream_reset (s);
-
+
return fails;
}
@@ -1004,9 +1004,9 @@ empty_get_test ()
printf ("%s\n", OK);
else
printf ("%s!\n", FAILED);
-
+
printf ("\n");
-
+
aspath_free (as);
}
@@ -1015,22 +1015,22 @@ static void
parse_test (struct test_segment *t)
{
struct aspath *asp;
-
+
printf ("%s: %s\n", t->name, t->desc);
asp = make_aspath (t->asdata, t->len, 0);
-
+
printf ("aspath: %s\nvalidating...:\n", aspath_print (asp));
if (!validate (asp, &t->sp))
printf (OK "\n");
else
printf (FAILED "\n");
-
+
printf ("\n");
-
+
if (asp)
- aspath_unintern (asp);
+ aspath_unintern (&asp);
}
/* prepend testing */
@@ -1038,27 +1038,27 @@ static void
prepend_test (struct tests *t)
{
struct aspath *asp1, *asp2, *ascratch;
-
+
printf ("prepend %s: %s\n", t->test1->name, t->test1->desc);
printf ("to %s: %s\n", t->test2->name, t->test2->desc);
-
+
asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
-
+
ascratch = aspath_dup (asp2);
- aspath_unintern (asp2);
-
+ aspath_unintern (&asp2);
+
asp2 = aspath_prepend (asp1, ascratch);
-
+
printf ("aspath: %s\n", aspath_print (asp2));
-
+
if (!validate (asp2, &t->sp))
printf ("%s\n", OK);
else
printf ("%s!\n", FAILED);
-
+
printf ("\n");
- aspath_unintern (asp1);
+ aspath_unintern (&asp1);
aspath_free (asp2);
}
@@ -1067,27 +1067,27 @@ static void
empty_prepend_test (struct test_segment *t)
{
struct aspath *asp1, *asp2, *ascratch;
-
+
printf ("empty prepend %s: %s\n", t->name, t->desc);
-
+
asp1 = make_aspath (t->asdata, t->len, 0);
asp2 = aspath_empty ();
-
+
ascratch = aspath_dup (asp2);
- aspath_unintern (asp2);
-
+ aspath_unintern (&asp2);
+
asp2 = aspath_prepend (asp1, ascratch);
-
+
printf ("aspath: %s\n", aspath_print (asp2));
-
+
if (!validate (asp2, &t->sp))
printf (OK "\n");
else
printf (FAILED "!\n");
-
+
printf ("\n");
if (asp1)
- aspath_unintern (asp1);
+ aspath_unintern (&asp1);
aspath_free (asp2);
}
@@ -1096,23 +1096,23 @@ static void
as4_reconcile_test (struct tests *t)
{
struct aspath *asp1, *asp2, *ascratch;
-
+
printf ("reconciling %s:\n %s\n", t->test1->name, t->test1->desc);
printf ("with %s:\n %s\n", t->test2->name, t->test2->desc);
-
+
asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
-
+
ascratch = aspath_reconcile_as4 (asp1, asp2);
-
+
if (!validate (ascratch, &t->sp))
printf (OK "\n");
else
printf (FAILED "!\n");
-
+
printf ("\n");
- aspath_unintern (asp1);
- aspath_unintern (asp2);
+ aspath_unintern (&asp1);
+ aspath_unintern (&asp2);
aspath_free (ascratch);
}
@@ -1122,23 +1122,23 @@ static void
aggregate_test (struct tests *t)
{
struct aspath *asp1, *asp2, *ascratch;
-
+
printf ("aggregate %s: %s\n", t->test1->name, t->test1->desc);
printf ("with %s: %s\n", t->test2->name, t->test2->desc);
-
+
asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
-
+
ascratch = aspath_aggregate (asp1, asp2);
-
+
if (!validate (ascratch, &t->sp))
printf (OK "\n");
else
printf (FAILED "!\n");
-
+
printf ("\n");
- aspath_unintern (asp1);
- aspath_unintern (asp2);
+ aspath_unintern (&asp1);
+ aspath_unintern (&asp2);
aspath_free (ascratch);
/* aspath_unintern (ascratch);*/
}
@@ -1156,23 +1156,23 @@ cmp_test ()
struct test_segment *t1 = &test_segments[left_compare[i].test_index1];
struct test_segment *t2 = &test_segments[left_compare[i].test_index2];
struct aspath *asp1, *asp2;
-
+
printf ("left cmp %s: %s\n", t1->name, t1->desc);
printf ("and %s: %s\n", t2->name, t2->desc);
-
+
asp1 = make_aspath (t1->asdata, t1->len, 0);
asp2 = make_aspath (t2->asdata, t2->len, 0);
-
+
if (aspath_cmp_left (asp1, asp2) != left_compare[i].shouldbe_cmp
|| aspath_cmp_left (asp2, asp1) != left_compare[i].shouldbe_cmp
- || aspath_cmp_left_confed (asp1, asp2)
+ || aspath_cmp_left_confed (asp1, asp2)
!= left_compare[i].shouldbe_confed
- || aspath_cmp_left_confed (asp2, asp1)
+ || aspath_cmp_left_confed (asp2, asp1)
!= left_compare[i].shouldbe_confed)
{
failed++;
printf (FAILED "\n");
- printf ("result should be: cmp: %d, confed: %d\n",
+ printf ("result should be: cmp: %d, confed: %d\n",
left_compare[i].shouldbe_cmp,
left_compare[i].shouldbe_confed);
printf ("got: cmp %d, cmp_confed: %d\n",
@@ -1183,47 +1183,50 @@ cmp_test ()
}
else
printf (OK "\n");
-
+
printf ("\n");
- aspath_unintern (asp1);
- aspath_unintern (asp2);
+ aspath_unintern (&asp1);
+ aspath_unintern (&asp2);
}
}
static int
handle_attr_test (struct aspath_tests *t)
{
- struct bgp bgp = { 0 };
+ struct bgp bgp = { 0 };
struct peer peer = { 0 };
- struct attr attr = { 0 };
+ struct attr attr = { 0 };
int ret;
int initfail = failed;
struct aspath *asp;
size_t datalen;
-
+ char host[] = { "none" } ;
+
asp = make_aspath (t->segment->asdata, t->segment->len, 0);
-
+
peer.ibuf = stream_new (BGP_MAX_PACKET_SIZE);
peer.obuf = stream_fifo_new ();
peer.bgp = &bgp;
- peer.host = (char *)"none";
+ peer.host = host ;
+#if 0
peer.fd = -1;
+#endif
peer.cap = t->cap;
-
+
stream_write (peer.ibuf, t->attrheader, t->len);
datalen = aspath_put (peer.ibuf, asp, t->as4 == AS4_DATA);
-
+
ret = bgp_attr_parse (&peer, &attr, t->len + datalen, NULL, NULL);
-
+
if (ret != t->result)
{
printf ("bgp_attr_parse returned %d, expected %d\n", ret, t->result);
- printf ("datalen %d\n", datalen);
+ printf ("datalen %d\n", (int)datalen);
failed++;
}
if (ret != 0)
goto out;
-
+
if (attr.aspath == NULL)
{
printf ("aspath is NULL!\n");
@@ -1240,9 +1243,9 @@ handle_attr_test (struct aspath_tests *t)
out:
if (attr.aspath)
- aspath_unintern (attr.aspath);
+ aspath_unintern (&attr.aspath);
if (asp)
- aspath_unintern (asp);
+ aspath_unintern (&asp);
return failed - initfail;
}
@@ -1250,7 +1253,7 @@ static void
attr_test (struct aspath_tests *t)
{
printf ("%s\n", t->desc);
- printf ("%s\n\n", handle_attr_test (t) ? FAILED : OK);
+ printf ("%s\n\n", handle_attr_test (t) ? FAILED : OK);
}
int
@@ -1260,54 +1263,54 @@ main (void)
bgp_master_init ();
master = bm->master;
bgp_attr_init ();
-
+
while (test_segments[i].name)
{
printf ("test %u\n", i);
parse_test (&test_segments[i]);
empty_prepend_test (&test_segments[i++]);
}
-
+
i = 0;
while (prepend_tests[i].test1)
{
printf ("prepend test %u\n", i);
prepend_test (&prepend_tests[i++]);
}
-
+
i = 0;
while (aggregate_tests[i].test1)
{
printf ("aggregate test %u\n", i);
aggregate_test (&aggregate_tests[i++]);
}
-
+
i = 0;
-
+
while (reconcile_tests[i].test1)
{
printf ("reconcile test %u\n", i);
as4_reconcile_test (&reconcile_tests[i++]);
}
-
+
i = 0;
-
+
cmp_test();
-
+
i = 0;
-
+
empty_get_test();
-
+
i = 0;
-
+
while (aspath_tests[i].desc)
{
printf ("aspath_attr test %d\n", i);
attr_test (&aspath_tests[i++]);
}
-
+
printf ("failures: %d\n", failed);
printf ("aspath count: %ld\n", aspath_count());
-
+
return (failed + aspath_count());
}
diff --git a/tests/bgp_capability_test.c b/tests/bgp_capability_test.c
index 0dbf4fb9..cae9a12d 100644
--- a/tests/bgp_capability_test.c
+++ b/tests/bgp_capability_test.c
@@ -1,4 +1,5 @@
#include <zebra.h>
+#include "miyagi.h"
#include "vty.h"
#include "stream.h"
@@ -36,7 +37,7 @@ static struct test_segment {
#define SHOULD_ERR -1
int parses; /* whether it should parse or not */
int peek_for; /* what peek_for_as4_capability should say */
-
+
/* AFI/SAFI validation */
int validate_afi;
afi_t afi;
@@ -44,10 +45,10 @@ static struct test_segment {
#define VALID_AFI 1
#define INVALID_AFI 0
int afi_valid;
-} test_segments [] =
+} test_segments [] =
{
/* 0 */
- { "caphdr",
+ { "caphdr",
"capability header, and no more",
{ CAPABILITY_CODE_REFRESH, 0x0 },
2, SHOULD_PARSE,
@@ -114,7 +115,7 @@ static struct test_segment mp_segments[] =
{ CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
6, SHOULD_PARSE, 0,
1, AFI_IP, BGP_SAFI_VPNV4, VALID_AFI,
- },
+ },
/* 9 */
{ "MP7",
"MP IP4/VPNv6",
@@ -150,9 +151,9 @@ static struct test_segment misc_segments[] =
/* 13 */
{ "ORF",
"ORF, simple, single entry, single tuple",
- { /* hdr */ CAPABILITY_CODE_ORF, 0x7,
- /* mpc */ 0x0, 0x1, 0x0, 0x1,
- /* num */ 0x1,
+ { /* hdr */ CAPABILITY_CODE_ORF, 0x7,
+ /* mpc */ 0x0, 0x1, 0x0, 0x1,
+ /* num */ 0x1,
/* tuples */ 0x40, 0x3
},
9, SHOULD_PARSE,
@@ -161,18 +162,18 @@ static struct test_segment misc_segments[] =
{ "ORF-many",
"ORF, multi entry/tuple",
{ /* hdr */ CAPABILITY_CODE_ORF, 0x21,
- /* mpc */ 0x0, 0x1, 0x0, 0x1,
- /* num */ 0x3,
+ /* mpc */ 0x0, 0x1, 0x0, 0x1,
+ /* num */ 0x3,
/* tuples */ 0x40, ORF_MODE_BOTH,
0x80, ORF_MODE_RECEIVE,
0x80, ORF_MODE_SEND,
- /* mpc */ 0x0, 0x2, 0x0, 0x1,
- /* num */ 0x3,
+ /* mpc */ 0x0, 0x2, 0x0, 0x1,
+ /* num */ 0x3,
/* tuples */ 0x40, ORF_MODE_BOTH,
0x80, ORF_MODE_RECEIVE,
0x80, ORF_MODE_SEND,
/* mpc */ 0x0, 0x2, 0x0, 0x2,
- /* num */ 0x3,
+ /* num */ 0x3,
/* tuples */ 0x40, ORF_MODE_RECEIVE,
0x80, ORF_MODE_SEND,
0x80, ORF_MODE_BOTH,
@@ -183,18 +184,18 @@ static struct test_segment misc_segments[] =
{ "ORFlo",
"ORF, multi entry/tuple, hdr length too short",
{ /* hdr */ CAPABILITY_CODE_ORF, 0x15,
- /* mpc */ 0x0, 0x1, 0x0, 0x1,
- /* num */ 0x3,
+ /* mpc */ 0x0, 0x1, 0x0, 0x1,
+ /* num */ 0x3,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
- /* mpc */ 0x0, 0x1, 0x0, 0x1,
- /* num */ 0x3,
+ /* mpc */ 0x0, 0x1, 0x0, 0x1,
+ /* num */ 0x3,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
/* mpc */ 0x0, 0x2, 0x0, 0x2,
- /* num */ 0x3,
+ /* num */ 0x3,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
@@ -205,18 +206,18 @@ static struct test_segment misc_segments[] =
{ "ORFlu",
"ORF, multi entry/tuple, length too long",
{ /* hdr */ 0x3, 0x22,
- /* mpc */ 0x0, 0x1, 0x0, 0x1,
- /* num */ 0x3,
+ /* mpc */ 0x0, 0x1, 0x0, 0x1,
+ /* num */ 0x3,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
- /* mpc */ 0x0, 0x2, 0x0, 0x1,
- /* num */ 0x3,
+ /* mpc */ 0x0, 0x2, 0x0, 0x1,
+ /* num */ 0x3,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
/* mpc */ 0x0, 0x2, 0x0, 0x2,
- /* num */ 0x3,
+ /* num */ 0x3,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
@@ -227,18 +228,18 @@ static struct test_segment misc_segments[] =
{ "ORFnu",
"ORF, multi entry/tuple, entry number too long",
{ /* hdr */ 0x3, 0x21,
- /* mpc */ 0x0, 0x1, 0x0, 0x1,
- /* num */ 0x3,
+ /* mpc */ 0x0, 0x1, 0x0, 0x1,
+ /* num */ 0x3,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
- /* mpc */ 0x0, 0x2, 0x0, 0x1,
- /* num */ 0x4,
+ /* mpc */ 0x0, 0x2, 0x0, 0x1,
+ /* num */ 0x4,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
/* mpc */ 0x0, 0x2, 0x0, 0x2,
- /* num */ 0x3,
+ /* num */ 0x3,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
@@ -249,13 +250,13 @@ static struct test_segment misc_segments[] =
{ "ORFno",
"ORF, multi entry/tuple, entry number too short",
{ /* hdr */ 0x3, 0x21,
- /* mpc */ 0x0, 0x1, 0x0, 0x1,
- /* num */ 0x3,
+ /* mpc */ 0x0, 0x1, 0x0, 0x1,
+ /* num */ 0x3,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
- /* mpc */ 0x0, 0x2, 0x0, 0x1,
- /* num */ 0x1,
+ /* mpc */ 0x0, 0x2, 0x0, 0x1,
+ /* num */ 0x1,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
@@ -271,18 +272,18 @@ static struct test_segment misc_segments[] =
{ "ORFpad",
"ORF, multi entry/tuple, padded to align",
{ /* hdr */ 0x3, 0x22,
- /* mpc */ 0x0, 0x1, 0x0, 0x1,
- /* num */ 0x3,
+ /* mpc */ 0x0, 0x1, 0x0, 0x1,
+ /* num */ 0x3,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
- /* mpc */ 0x0, 0x2, 0x0, 0x1,
- /* num */ 0x3,
+ /* mpc */ 0x0, 0x2, 0x0, 0x1,
+ /* num */ 0x3,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
/* mpc */ 0x0, 0x2, 0x0, 0x2,
- /* num */ 0x3,
+ /* num */ 0x3,
/* tuples */ 0x40, 0x3,
0x80, 0x1,
0x80, 0x2,
@@ -401,7 +402,7 @@ static struct test_segment misc_segments[] =
};
/* DYNAMIC message */
-struct test_segment dynamic_cap_msgs[] =
+struct test_segment dynamic_cap_msgs[] =
{
{ "DynCap",
"Dynamic Capability Message, IP/Multicast",
@@ -439,7 +440,7 @@ struct test_segment opt_params[] =
{ 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
0x02, 0x02, 0x80, 0x00, /* RR (old) */
- 0x02, 0x02, 0x02, 0x00, /* RR */
+ 0x02, 0x02, 0x02, 0x00, /* RR */
},
24, SHOULD_PARSE,
},
@@ -449,7 +450,7 @@ struct test_segment opt_params[] =
0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
0x80, 0x00, /* RR (old) */
- 0x02, 0x00, /* RR */
+ 0x02, 0x00, /* RR */
},
18, SHOULD_PARSE,
},
@@ -469,7 +470,7 @@ struct test_segment opt_params[] =
0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
0x80, 0x00, /* RR (old) */
- 0x02, 0x00, /* RR */
+ 0x02, 0x00, /* RR */
0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
},
24, SHOULD_PARSE, 196614,
@@ -503,6 +504,8 @@ struct test_segment opt_params[] =
{ NULL, NULL, {0}, 0, 0}
};
+extern int bgp_capability_receive(struct peer*, bgp_size_t) ;
+
/* basic parsing test */
static void
parse_test (struct peer *peer, struct test_segment *t, int type)
@@ -513,11 +516,11 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
int oldfailed = failed;
int len = t->len;
#define RANDOM_FUZZ 35
-
+
stream_reset (peer->ibuf);
stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
stream_set_getp (peer->ibuf, RANDOM_FUZZ);
-
+
switch (type)
{
case CAPABILITY:
@@ -532,7 +535,7 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
break;
}
stream_write (peer->ibuf, t->data, t->len);
-
+
printf ("%s: %s\n", t->name, t->desc);
switch (type)
@@ -546,7 +549,7 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
printf ("peek_for_as4: as4 is %u\n", as4);
/* and it should leave getp as it found it */
assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ);
-
+
ret = bgp_open_option_parse (peer, len, &capability);
break;
case DYNCAP:
@@ -556,49 +559,49 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
printf ("unknown type %u\n", type);
exit(1);
}
-
+
if (!ret && t->validate_afi)
{
safi_t safi = t->safi;
-
+
if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
failed++;
-
+
printf ("MP: %u/%u (%u): recv %u, nego %u\n",
t->afi, t->safi, safi,
peer->afc_recv[t->afi][safi],
peer->afc_nego[t->afi][safi]);
-
+
if (t->afi_valid == VALID_AFI)
{
-
+
if (!peer->afc_recv[t->afi][safi])
failed++;
if (!peer->afc_nego[t->afi][safi])
failed++;
}
}
-
- if (as4 != t->peek_for)
+
+ if (as4 != (uint32_t)t->peek_for)
{
printf ("as4 %u != %u\n", as4, t->peek_for);
failed++;
}
-
+
printf ("parsed?: %s\n", ret ? "no" : "yes");
-
+
if (ret != t->parses)
failed++;
-
+
if (tty)
- printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
+ printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
: VT100_GREEN "OK" VT100_RESET);
else
printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
-
+
if (failed)
printf (" (%u)", failed);
-
+
printf ("\n\n");
}
@@ -610,7 +613,7 @@ main (void)
{
struct peer *peer;
int i, j;
-
+
conf_bgp_debug_fsm = -1UL;
conf_bgp_debug_events = -1UL;
conf_bgp_debug_packet = -1UL;
@@ -621,26 +624,26 @@ main (void)
term_bgp_debug_packet = -1UL;
term_bgp_debug_normal = -1UL;
term_bgp_debug_as4 = -1UL;
-
+
master = thread_master_create ();
bgp_master_init ();
-
- if (fileno (stdout) >= 0)
+
+ if (fileno (stdout) >= 0)
tty = isatty (fileno (stdout));
-
+
if (bgp_get (&bgp, &asn, NULL))
return -1;
-
+
peer = peer_create_accept (bgp);
- peer->host = "foo";
-
+ peer->host = miyagi("foo");
+
for (i = AFI_IP; i < AFI_MAX; i++)
for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
{
peer->afc[i][j] = 1;
peer->afc_adv[i][j] = 1;
}
-
+
i = 0;
while (mp_segments[i].name)
parse_test (peer, &mp_segments[i++], CAPABILITY);
@@ -649,9 +652,9 @@ main (void)
* one of the afc_nego's
*/
i = 0;
- while (test_segments[i].name)
+ while (test_segments[i].name)
parse_test (peer, &test_segments[i++], CAPABILITY);
-
+
i = 0;
while (misc_segments[i].name)
parse_test (peer, &misc_segments[i++], CAPABILITY);
@@ -661,12 +664,12 @@ main (void)
parse_test (peer, &opt_params[i++], OPT_PARAM);
SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
- peer->status = Established;
-
+ peer->state = bgp_peer_pEstablished;
+
i = 0;
while (dynamic_cap_msgs[i].name)
parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
-
+
printf ("failures: %d\n", failed);
return failed;
}
diff --git a/tests/bgp_mp_attr_test.c b/tests/bgp_mp_attr_test.c
index dde0df2f..6a445acf 100644
--- a/tests/bgp_mp_attr_test.c
+++ b/tests/bgp_mp_attr_test.c
@@ -1,4 +1,5 @@
#include <zebra.h>
+#include "miyagi.h"
#include "vty.h"
#include "stream.h"
@@ -36,17 +37,17 @@ static struct test_segment {
#define SHOULD_PARSE 0
#define SHOULD_ERR -1
int parses; /* whether it should parse or not */
-
+
/* AFI/SAFI validation */
afi_t afi;
safi_t safi;
#define VALID_AFI 1
#define INVALID_AFI 0
int afi_valid;
-} mp_reach_segments [] =
+} mp_reach_segments [] =
{
{ "IPv6",
- "IPV6 MP Reach, global nexthop, 1 NLRI",
+ "IPV6 MP Reach, global nexthop, 1 NLRI",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
/* nexthop bytes */ 16,
@@ -57,12 +58,12 @@ static struct test_segment {
/* SNPA (defunct, MBZ) */ 0x0,
/* NLRI tuples */ 32, 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
},
- (4 + 16 + 1 + 5),
+ (4 + 16 + 1 + 5),
SHOULD_PARSE,
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv6-2",
- "IPV6 MP Reach, global nexthop, 2 NLRIs",
+ "IPV6 MP Reach, global nexthop, 2 NLRIs",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
/* nexthop bytes */ 16,
@@ -71,18 +72,18 @@ static struct test_segment {
0x3, 0x4, 0x5, 0x6,
0xa1, 0xa2, 0xa3, 0xa4,
/* SNPA (defunct, MBZ) */ 0x0,
- /* NLRI tuples */ 32,
+ /* NLRI tuples */ 32,
0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
64,
0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
0x0, 0x2, 0x0, 0x3,
},
- (4 + 16 + 1 + 5 + 9),
+ (4 + 16 + 1 + 5 + 9),
SHOULD_PARSE,
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv6-default",
- "IPV6 MP Reach, global nexthop, 2 NLRIs + default",
+ "IPV6 MP Reach, global nexthop, 2 NLRIs + default",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
/* nexthop bytes */ 16,
@@ -91,7 +92,7 @@ static struct test_segment {
0x3, 0x4, 0x5, 0x6,
0xa1, 0xa2, 0xa3, 0xa4,
/* SNPA (defunct, MBZ) */ 0x0,
- /* NLRI tuples */ 32,
+ /* NLRI tuples */ 32,
0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
64,
0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
@@ -103,7 +104,7 @@ static struct test_segment {
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv6-lnh",
- "IPV6 MP Reach, global+local nexthops, 2 NLRIs + default",
+ "IPV6 MP Reach, global+local nexthops, 2 NLRIs + default",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
/* nexthop bytes */ 32,
@@ -116,7 +117,7 @@ static struct test_segment {
0x2, 0x10, 0x2, 0xff,
0x1, 0x2, 0x3, 0x4,
/* SNPA (defunct, MBZ) */ 0x0,
- /* NLRI tuples */ 32,
+ /* NLRI tuples */ 32,
0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
64,
0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
@@ -128,7 +129,7 @@ static struct test_segment {
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv6-nhlen",
- "IPV6 MP Reach, inappropriate nexthop length",
+ "IPV6 MP Reach, inappropriate nexthop length",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
/* nexthop bytes */ 4,
@@ -141,7 +142,7 @@ static struct test_segment {
0x2, 0x10, 0x2, 0xff,
0x1, 0x2, 0x3, 0x4,
/* SNPA (defunct, MBZ) */ 0x0,
- /* NLRI tuples */ 32,
+ /* NLRI tuples */ 32,
0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
64,
0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
@@ -153,7 +154,7 @@ static struct test_segment {
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv6-nhlen2",
- "IPV6 MP Reach, invalid nexthop length",
+ "IPV6 MP Reach, invalid nexthop length",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
/* nexthop bytes */ 5,
@@ -166,7 +167,7 @@ static struct test_segment {
0x2, 0x10, 0x2, 0xff,
0x1, 0x2, 0x3, 0x4,
/* SNPA (defunct, MBZ) */ 0x0,
- /* NLRI tuples */ 32,
+ /* NLRI tuples */ 32,
0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
64,
0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
@@ -178,7 +179,7 @@ static struct test_segment {
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv6-nhlen3",
- "IPV6 MP Reach, nexthop length overflow",
+ "IPV6 MP Reach, nexthop length overflow",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
/* nexthop bytes */ 32,
@@ -192,7 +193,7 @@ static struct test_segment {
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv6-nhlen4",
- "IPV6 MP Reach, nexthop length short",
+ "IPV6 MP Reach, nexthop length short",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
/* nexthop bytes */ 16,
@@ -205,7 +206,7 @@ static struct test_segment {
0x2, 0x10, 0x2, 0xff,
0x1, 0x2, 0x3, 0x4,
/* SNPA (defunct, MBZ) */ 0x0,
- /* NLRI tuples */ 32,
+ /* NLRI tuples */ 32,
0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
64,
0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
@@ -217,7 +218,7 @@ static struct test_segment {
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv6-nlri",
- "IPV6 MP Reach, NLRI bitlen overflow",
+ "IPV6 MP Reach, NLRI bitlen overflow",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
/* nexthop bytes */ 32,
@@ -230,7 +231,7 @@ static struct test_segment {
0x2, 0x10, 0x2, 0xff,
0x1, 0x2, 0x3, 0x4,
/* SNPA (defunct, MBZ) */ 0x0,
- /* NLRI tuples */ 120,
+ /* NLRI tuples */ 120,
0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
64,
0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
@@ -242,11 +243,11 @@ static struct test_segment {
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv4",
- "IPv4 MP Reach, 2 NLRIs + default",
+ "IPv4 MP Reach, 2 NLRIs + default",
{
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
/* nexthop bytes */ 4,
- /* Nexthop */ 192, 168, 0, 1,
+ /* Nexthop */ 192, 168, 0, 1,
/* SNPA (defunct, MBZ) */ 0x0,
/* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
17, 10, 2, 3, /* 10.2.3/17 */
@@ -257,11 +258,11 @@ static struct test_segment {
AFI_IP, SAFI_UNICAST, VALID_AFI,
},
{ "IPv4-nhlen",
- "IPv4 MP Reach, nexthop lenth overflow",
+ "IPv4 MP Reach, nexthop lenth overflow",
{
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
/* nexthop bytes */ 32,
- /* Nexthop */ 192, 168, 0, 1,
+ /* Nexthop */ 192, 168, 0, 1,
/* SNPA (defunct, MBZ) */ 0x0,
/* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
17, 10, 2, 3, /* 10.2.3/17 */
@@ -272,14 +273,14 @@ static struct test_segment {
AFI_IP, SAFI_UNICAST, VALID_AFI,
},
{ "IPv4-nlrilen",
- "IPv4 MP Reach, nlri lenth overflow",
+ "IPv4 MP Reach, nlri lenth overflow",
{
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
/* nexthop bytes */ 4,
- /* Nexthop */ 192, 168, 0, 1,
+ /* Nexthop */ 192, 168, 0, 1,
/* SNPA (defunct, MBZ) */ 0x0,
/* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
- 30, 10,
+ 30, 10,
0, /* 0/0 */
},
(4 + 4 + 1 + 3 + 2 + 1),
@@ -287,13 +288,13 @@ static struct test_segment {
AFI_IP, SAFI_UNICAST, VALID_AFI,
},
{ "IPv4-vpnv4",
- "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs",
+ "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs",
{
/* AFI / SAFI */ 0x0, AFI_IP, BGP_SAFI_VPNV4,
/* nexthop bytes */ 12,
/* RD */ 0, 0, 1, 2,
0, 0xff, 3, 4,
- /* Nexthop */ 192, 168, 0, 1,
+ /* Nexthop */ 192, 168, 0, 1,
/* SNPA (defunct, MBZ) */ 0x0,
/* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
17, 10, 2, 3, /* 10.2.3/17 */
@@ -305,17 +306,17 @@ static struct test_segment {
},
/* From bug #385 */
{ "IPv6-bug",
- "IPv6, global nexthop, 1 default NLRI",
+ "IPv6, global nexthop, 1 default NLRI",
{
/* AFI / SAFI */ 0x0, 0x2, 0x1,
/* nexthop bytes */ 0x20,
- /* Nexthop (global) */ 0x20, 0x01, 0x04, 0x70,
+ /* Nexthop (global) */ 0x20, 0x01, 0x04, 0x70,
0x00, 0x01, 0x00, 0x06,
0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01,
- /* Nexthop (local) */ 0xfe, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ /* Nexthop (local) */ 0xfe, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
- 0x02, 0x0c, 0xdb, 0xff,
+ 0x02, 0x0c, 0xdb, 0xff,
0xfe, 0xfe, 0xeb, 0x00,
/* SNPA (defunct, MBZ) */ 0,
/* NLRI tuples */ /* Should have 0 here for ::/0, but dont */
@@ -324,7 +325,7 @@ static struct test_segment {
SHOULD_ERR,
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
-
+
{ NULL, NULL, {0}, 0, 0}
};
@@ -332,34 +333,34 @@ static struct test_segment {
static struct test_segment mp_unreach_segments [] =
{
{ "IPv6-unreach",
- "IPV6 MP Unreach, 1 NLRI",
+ "IPV6 MP Unreach, 1 NLRI",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
/* NLRI tuples */ 32, 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
},
- (3 + 5),
+ (3 + 5),
SHOULD_PARSE,
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv6-unreach2",
- "IPV6 MP Unreach, 2 NLRIs",
+ "IPV6 MP Unreach, 2 NLRIs",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
- /* NLRI tuples */ 32,
+ /* NLRI tuples */ 32,
0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
64,
0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
0x0, 0x2, 0x0, 0x3,
},
- (3 + 5 + 9),
+ (3 + 5 + 9),
SHOULD_PARSE,
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv6-unreach-default",
- "IPV6 MP Unreach, 2 NLRIs + default",
+ "IPV6 MP Unreach, 2 NLRIs + default",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
- /* NLRI tuples */ 32,
+ /* NLRI tuples */ 32,
0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
64,
0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
@@ -371,10 +372,10 @@ static struct test_segment mp_unreach_segments [] =
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv6-unreach-nlri",
- "IPV6 MP Unreach, NLRI bitlen overflow",
+ "IPV6 MP Unreach, NLRI bitlen overflow",
{
/* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
- /* NLRI tuples */ 120,
+ /* NLRI tuples */ 120,
0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
64,
0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
@@ -386,7 +387,7 @@ static struct test_segment mp_unreach_segments [] =
AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
{ "IPv4-unreach",
- "IPv4 MP Unreach, 2 NLRIs + default",
+ "IPv4 MP Unreach, 2 NLRIs + default",
{
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
/* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
@@ -398,11 +399,11 @@ static struct test_segment mp_unreach_segments [] =
AFI_IP, SAFI_UNICAST, VALID_AFI,
},
{ "IPv4-unreach-nlrilen",
- "IPv4 MP Unreach, nlri length overflow",
+ "IPv4 MP Unreach, nlri length overflow",
{
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
/* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
- 30, 10,
+ 30, 10,
0, /* 0/0 */
},
(3 + 3 + 2 + 1),
@@ -410,13 +411,13 @@ static struct test_segment mp_unreach_segments [] =
AFI_IP, SAFI_UNICAST, VALID_AFI,
},
{ "IPv4-unreach-vpnv4",
- "IPv4/VPNv4 MP Unreach, RD, 3 NLRIs",
+ "IPv4/VPNv4 MP Unreach, RD, 3 NLRIs",
{
/* AFI / SAFI */ 0x0, AFI_IP, BGP_SAFI_VPNV4,
/* nexthop bytes */ 12,
/* RD */ 0, 0, 1, 2,
0, 0xff, 3, 4,
- /* Nexthop */ 192, 168, 0, 1,
+ /* Nexthop */ 192, 168, 0, 1,
/* SNPA (defunct, MBZ) */ 0x0,
/* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
17, 10, 2, 3, /* 10.2.3/17 */
@@ -439,13 +440,13 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
struct attr attr;
struct bgp_nlri nlri;
#define RANDOM_FUZZ 35
-
+
stream_reset (peer->ibuf);
stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
stream_set_getp (peer->ibuf, RANDOM_FUZZ);
-
+
stream_write (peer->ibuf, t->data, t->len);
-
+
printf ("%s: %s\n", t->name, t->desc);
if (type == BGP_ATTR_MP_REACH_NLRI)
@@ -456,30 +457,30 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
if (!ret)
{
safi_t safi = t->safi;
-
+
if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
failed++;
-
+
printf ("MP: %u/%u (%u): recv %u, nego %u\n",
t->afi, t->safi, safi,
peer->afc_recv[t->afi][safi],
peer->afc_nego[t->afi][safi]);
}
-
+
printf ("parsed?: %s\n", ret ? "no" : "yes");
-
+
if (ret != t->parses)
failed++;
-
+
if (tty)
- printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
+ printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
: VT100_GREEN "OK" VT100_RESET);
else
printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
-
+
if (failed)
printf (" (%u)", failed);
-
+
printf ("\n\n");
}
@@ -491,7 +492,7 @@ main (void)
{
struct peer *peer;
int i, j;
-
+
conf_bgp_debug_fsm = -1UL;
conf_bgp_debug_events = -1UL;
conf_bgp_debug_packet = -1UL;
@@ -502,26 +503,26 @@ main (void)
term_bgp_debug_packet = -1UL;
term_bgp_debug_normal = -1UL;
term_bgp_debug_as4 = -1UL;
-
+
master = thread_master_create ();
bgp_master_init ();
-
- if (fileno (stdout) >= 0)
+
+ if (fileno (stdout) >= 0)
tty = isatty (fileno (stdout));
-
+
if (bgp_get (&bgp, &asn, NULL))
return -1;
-
+
peer = peer_create_accept (bgp);
- peer->host = "foo";
-
+ peer->host = miyagi("foo") ;
+
for (i = AFI_IP; i < AFI_MAX; i++)
for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
{
peer->afc[i][j] = 1;
peer->afc_adv[i][j] = 1;
}
-
+
i = 0;
while (mp_reach_segments[i].name)
parse_test (peer, &mp_reach_segments[i++], BGP_ATTR_MP_REACH_NLRI);
diff --git a/tests/ecommunity_test.c b/tests/ecommunity_test.c
index 418f659f..3a67228d 100644
--- a/tests/ecommunity_test.c
+++ b/tests/ecommunity_test.c
@@ -1,4 +1,5 @@
#include <zebra.h>
+#include "miyagi.h"
#include "vty.h"
#include "stream.h"
@@ -15,7 +16,7 @@ struct thread_master *master = NULL;
static int failed = 0;
/* specification for a test - what the results should be */
-struct test_spec
+struct test_spec
{
const char *shouldbe; /* the string the path should parse to */
};
@@ -28,7 +29,7 @@ static struct test_segment {
const u_char data[1024];
int len;
struct test_spec sp;
-} test_segments [] =
+} test_segments [] =
{
{ /* 0 */
"ipaddr",
@@ -73,7 +74,7 @@ validate (struct ecommunity *ecom, const struct test_spec *sp)
int fails = 0;
struct ecommunity *etmp;
char *str1, *str2;
-
+
printf ("got:\n %s\n", ecommunity_str (ecom));
str1 = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_COMMUNITY_LIST);
etmp = ecommunity_str2com (str1, 0, 1);
@@ -81,7 +82,7 @@ validate (struct ecommunity *ecom, const struct test_spec *sp)
str2 = ecommunity_ecom2str (etmp, ECOMMUNITY_FORMAT_COMMUNITY_LIST);
else
str2 = NULL;
-
+
if (strcmp (sp->shouldbe, str1))
{
failed++;
@@ -94,13 +95,13 @@ validate (struct ecommunity *ecom, const struct test_spec *sp)
fails++;
printf ("dogfood: in %s\n"
" in->out %s\n",
- str1,
+ str1,
(etmp && str2) ? str2 : "NULL");
}
- ecommunity_free (etmp);
+ ecommunity_free (&etmp);
XFREE (MTYPE_ECOMMUNITY_STR, str1);
XFREE (MTYPE_ECOMMUNITY_STR, str2);
-
+
return fails;
}
@@ -109,10 +110,10 @@ static void
parse_test (struct test_segment *t)
{
struct ecommunity *ecom;
-
+
printf ("%s: %s\n", t->name, t->desc);
- ecom = ecommunity_parse (t->data, t->len);
+ ecom = ecommunity_parse (miyagi(t->data), t->len);
printf ("ecom: %s\nvalidating...:\n", ecommunity_str (ecom));
@@ -120,12 +121,12 @@ parse_test (struct test_segment *t)
printf ("OK\n");
else
printf ("failed\n");
-
+
printf ("\n");
- ecommunity_unintern (ecom);
+ ecommunity_unintern (&ecom);
}
-
+
int
main (void)
{
@@ -133,7 +134,7 @@ main (void)
ecommunity_init();
while (test_segments[i].name)
parse_test (&test_segments[i++]);
-
+
printf ("failures: %d\n", failed);
//printf ("aspath count: %ld\n", aspath_count());
return failed;
diff --git a/tests/heavy-thread.c b/tests/heavy-thread.c
index cd3a3b9d..f7a99cc5 100644
--- a/tests/heavy-thread.c
+++ b/tests/heavy-thread.c
@@ -59,17 +59,17 @@ slow_func (struct vty *vty, const char *str, const int i)
{
double x = 1;
int j;
-
+
for (j = 0; j < 300; j++)
x += sin(x)*j;
-
+
if ((i % ITERS_LATER) == 0)
printf ("%s: %d, temporary error, save this somehow and do it later..\n",
__func__, i);
-
+
if ((i % ITERS_ERR) == 0)
printf ("%s: hard error\n", __func__);
-
+
if ((i % ITERS_PRINT) == 0)
printf ("%s did %d, x = %g\n", str, i, x);
}
@@ -78,8 +78,8 @@ static int
clear_something (struct thread *thread)
{
struct work_state *ws = THREAD_ARG(thread);
-
- /* this could be like iterating through 150k of route_table
+
+ /* this could be like iterating through 150k of route_table
* or worse, iterating through a list of peers, to bgp_stop them with
* each having 150k route tables to process...
*/
@@ -93,7 +93,7 @@ clear_something (struct thread *thread)
return 0;
}
}
-
+
/* All done! */
XFREE (MTYPE_TMP, ws->str);
XFREE (MTYPE_TMP, ws);
@@ -114,22 +114,22 @@ DEFUN (clear_foo,
vty_out (vty, "%% string argument required%s", VTY_NEWLINE);
return CMD_WARNING;
}
-
+
str = argv_concat (argv, argc, 0);
-
+
if ((ws = XMALLOC(MTYPE_TMP, sizeof(*ws))) == NULL)
{
zlog_err ("%s: unable to allocate work_state", __func__);
return CMD_WARNING;
}
-
+
if (!(ws->str = XSTRDUP (MTYPE_TMP, str)))
{
zlog_err ("%s: unable to xstrdup", __func__);
XFREE (MTYPE_TMP, ws);
return CMD_WARNING;
}
-
+
ws->vty = vty;
ws->i = ITERS_FIRST;
@@ -138,8 +138,10 @@ DEFUN (clear_foo,
return CMD_SUCCESS;
}
+extern void test_init(void) ;
+
void
-test_init()
+test_init(void)
{
install_element (VIEW_NODE, &clear_foo_cmd);
}
diff --git a/tests/heavy-wq.c b/tests/heavy-wq.c
index a2c609d4..bf3ab85a 100644
--- a/tests/heavy-wq.c
+++ b/tests/heavy-wq.c
@@ -66,7 +66,7 @@ heavy_wq_add (struct vty *vty, const char *str, int i)
zlog_err ("%s: unable to allocate hn", __func__);
return;
}
-
+
hn->i = i;
if (!(hn->str = XSTRDUP (MTYPE_PREFIX_LIST_STR, str)))
{
@@ -74,47 +74,47 @@ heavy_wq_add (struct vty *vty, const char *str, int i)
XFREE (MTYPE_PREFIX_LIST, hn);
return;
}
-
+
work_queue_add (heavy_wq, hn);
-
+
return;
}
static void
-slow_func_err (struct work_queue *wq, struct work_queue_item *item)
+slow_func_err (struct work_queue *wq, work_queue_item item)
{
printf ("%s: running error function\n", __func__);
}
static void
-slow_func_del (struct work_queue *wq, void *data)
+slow_func_del (struct work_queue *wq, work_queue_item item)
{
- struct heavy_wq_node *hn = data;
+ struct heavy_wq_node *hn = item->args.data;
assert (hn && hn->str);
printf ("%s: %s\n", __func__, hn->str);
XFREE (MTYPE_PREFIX_LIST_STR, hn->str);
- hn->str = NULL;
+ hn->str = NULL;
XFREE(MTYPE_PREFIX_LIST, hn);
}
static wq_item_status
-slow_func (struct work_queue *wq, void *data)
+slow_func (struct work_queue *wq, work_queue_item item)
{
- struct heavy_wq_node *hn = data;
+ struct heavy_wq_node *hn = item->args.data;
double x = 1;
int j;
-
+
assert (hn && hn->str);
-
+
for (j = 0; j < 300; j++)
x += sin(x)*j;
-
+
if ((hn->i % ITERS_LATER) == 0)
return WQ_RETRY_LATER;
-
+
if ((hn->i % ITERS_ERR) == 0)
return WQ_RETRY_NOW;
-
+
if ((hn->i % ITERS_PRINT) == 0)
printf ("%s did %d, x = %g\n", hn->str, hn->i, x);
@@ -125,8 +125,8 @@ static void
clear_something (struct vty *vty, const char *str)
{
int i;
-
- /* this could be like iterating through 150k of route_table
+
+ /* this could be like iterating through 150k of route_table
* or worse, iterating through a list of peers, to bgp_stop them with
* each having 150k route tables to process...
*/
@@ -146,9 +146,9 @@ DEFUN (clear_foo,
vty_out (vty, "%% string argument required%s", VTY_NEWLINE);
return CMD_WARNING;
}
-
+
str = argv_concat (argv, argc, 0);
-
+
clear_something (vty, str);
XFREE (MTYPE_TMP, str);
return CMD_SUCCESS;
@@ -162,18 +162,20 @@ heavy_wq_init ()
zlog_err ("%s: could not get new work queue!", __func__);
return -1;
}
-
- heavy_wq->spec.workfunc = &slow_func;
- heavy_wq->spec.errorfunc = &slow_func_err;
+
+ heavy_wq->spec.workfunc = &slow_func;
+ heavy_wq->spec.errorfunc = &slow_func_err;
heavy_wq->spec.del_item_data = &slow_func_del;
- heavy_wq->spec.max_retries = 3;
- heavy_wq->spec.hold = 1000;
-
+ heavy_wq->spec.max_retries = 3;
+ heavy_wq->spec.hold = 1000;
+
return 0;
}
-void
-test_init()
+extern void test_init(void) ;
+
+extern void
+test_init(void)
{
install_element (VIEW_NODE, &clear_foo_cmd);
heavy_wq_init();
diff --git a/tests/heavy.c b/tests/heavy.c
index 577a4816..901fb10f 100644
--- a/tests/heavy.c
+++ b/tests/heavy.c
@@ -50,27 +50,27 @@ slow_func (struct vty *vty, const char *str, const int i)
{
double x = 1;
int j;
-
+
for (j = 0; j < 300; j++)
x += sin(x)*j;
-
+
if ((i % ITERS_LATER) == 0)
- printf ("%s: %d, temporary error, save this somehow and do it later..\n",
+ printf ("%s: %d, temporary error, save this somehow and do it later..\n",
__func__, i);
-
+
if ((i % ITERS_ERR) == 0)
printf ("%s: hard error\n", __func__);
-
+
if ((i % ITERS_PRINT) == 0)
- printf ("%s did %d, x = %g%s", str, i, x, VTY_NEWLINE);
+ printf ("%s did %d, x = %g%s", str, i, x, VTY_NEWLINE);
}
static void
clear_something (struct vty *vty, const char *str)
{
int i;
-
- /* this could be like iterating through 150k of route_table
+
+ /* this could be like iterating through 150k of route_table
* or worse, iterating through a list of peers, to bgp_stop them with
* each having 150k route tables to process...
*/
@@ -90,9 +90,9 @@ DEFUN (clear_foo,
vty_out (vty, "%% string argument required%s", VTY_NEWLINE);
return CMD_WARNING;
}
-
+
str = argv_concat (argv, argc, 0);
-
+
clear_something (vty, str);
XFREE (MTYPE_TMP, str);
return CMD_SUCCESS;
@@ -104,8 +104,10 @@ slow_vty_init()
install_element (VIEW_NODE, &clear_foo_cmd);
}
-void
-test_init()
+extern void test_init(void) ;
+
+extern void
+test_init(void)
{
slow_vty_init();
}
diff --git a/tests/main.c b/tests/main.c
index e0fbb4d5..f735e1e1 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -32,7 +32,7 @@ extern void test_init();
struct thread_master *master;
-struct option longopts[] =
+struct option longopts[] =
{
{ "daemon", no_argument, NULL, 'd'},
{ "config_file", required_argument, NULL, 'f'},
@@ -51,12 +51,14 @@ DEFUN (daemon_exit,
exit(0);
}
+extern int test_timer (struct thread *thread) ;
+
static int timer_count;
-int
+extern int
test_timer (struct thread *thread)
{
int *count = THREAD_ARG(thread);
-
+
printf ("run %d of timer\n", (*count)++);
thread_add_timer (master, test_timer, count, 5);
return 0;
@@ -81,7 +83,7 @@ usage (char *progname, int status)
if (status != 0)
fprintf (stderr, "Try `%s --help' for more information.\n", progname);
else
- {
+ {
printf ("Usage : %s [OPTION...]\n\
Daemon which does 'slow' things.\n\n\
-d, --daemon Runs in daemon mode\n\
@@ -95,8 +97,8 @@ Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
}
exit (status);
}
-
-
+
+
/* main routine. */
int
main (int argc, char **argv)
@@ -108,7 +110,7 @@ main (int argc, char **argv)
char *progname;
struct thread thread;
char *config_file = NULL;
-
+
/* Set umask before anything for security */
umask (0027);
@@ -118,16 +120,16 @@ main (int argc, char **argv)
/* master init. */
master = thread_master_create ();
- while (1)
+ while (1)
{
int opt;
opt = getopt_long (argc, argv, "dhf:A:P:v", longopts, 0);
-
+
if (opt == EOF)
break;
- switch (opt)
+ switch (opt)
{
case 0:
break;
@@ -146,7 +148,7 @@ main (int argc, char **argv)
{
vty_port = 0;
break;
- }
+ }
vty_port = atoi (optarg);
vty_port = (vty_port ? vty_port : 4000);
break;
@@ -182,16 +184,16 @@ main (int argc, char **argv)
/* Create VTY socket */
vty_serv_sock (vty_addr, vty_port, "/tmp/.heavy.sock");
-
+
/* Configuration file read*/
if (!config_file)
usage (progname, 1);
vty_read_config (config_file, NULL);
-
+
test_timer_init();
-
- test_init();
-
+
+ test_init();
+
/* Fetch next active thread. */
while (thread_fetch (master, &thread))
thread_call (&thread);
diff --git a/tests/test-checksum.c b/tests/test-checksum.c
index bd156baa..076dd4ad 100644
--- a/tests/test-checksum.c
+++ b/tests/test-checksum.c
@@ -13,7 +13,7 @@ struct acc_vals {
struct csum_vals {
struct acc_vals a;
- int x;
+ int x;
int y;
};
@@ -24,25 +24,27 @@ typedef uint16_t testoff_t;
/* Fletcher Checksum -- Refer to RFC1008. */
#define MODX 4102
-
+
/* Accumulator phase of checksum */
-static
-struct acc_vals
+static struct acc_vals
+accumulate (u_char *buffer, testsz_t len, testoff_t off)
+ __attribute__((unused)) ;
+static struct acc_vals
accumulate (u_char *buffer, testsz_t len, testoff_t off)
{
u_int8_t *p;
u_int16_t *csum;
int i, init_len, partial_len;
struct acc_vals ret;
-
+
csum = (u_int16_t *) (buffer + off);
*(csum) = 0;
-
+
p = buffer;
ret.c0 = 0;
ret.c1 = 0;
init_len = len;
-
+
while (len != 0)
{
partial_len = MIN(len, MODX);
@@ -62,9 +64,9 @@ accumulate (u_char *buffer, testsz_t len, testoff_t off)
}
/* The final reduction phase.
- * This one should be the original ospfd version
+ * This one should be the original ospfd version
*/
-static u_int16_t
+static u_int16_t
reduce_ospfd (struct csum_vals *vals, testsz_t len, testoff_t off)
{
#define x vals->x
@@ -73,7 +75,7 @@ reduce_ospfd (struct csum_vals *vals, testsz_t len, testoff_t off)
#define c1 vals->a.c1
x = ((len - off - 1) * c0 - c1) % 255;
-
+
if (x <= 0)
x += 255;
y = 510 - c0 - x;
@@ -81,7 +83,7 @@ reduce_ospfd (struct csum_vals *vals, testsz_t len, testoff_t off)
y -= 255;
/* take care endian issue. */
- return htons ((x << 8) + y);
+ return htons ((x << 8) + y);
#undef x
#undef y
#undef c0
@@ -89,7 +91,7 @@ reduce_ospfd (struct csum_vals *vals, testsz_t len, testoff_t off)
}
/* slightly different concatenation */
-static u_int16_t
+static u_int16_t
reduce_ospfd1 (struct csum_vals *vals, testsz_t len, testoff_t off)
{
#define x vals->x
@@ -105,7 +107,7 @@ reduce_ospfd1 (struct csum_vals *vals, testsz_t len, testoff_t off)
y -= 255;
/* take care endian issue. */
- return htons ((x << 8) | (y & 0xff));
+ return htons ((x << 8) | (y & 0xff));
#undef x
#undef y
#undef c0
@@ -113,7 +115,7 @@ reduce_ospfd1 (struct csum_vals *vals, testsz_t len, testoff_t off)
}
/* original isisd version */
-static u_int16_t
+static u_int16_t
reduce_isisd (struct csum_vals *vals, testsz_t len, testoff_t off)
{
#define x vals->x
@@ -121,7 +123,7 @@ reduce_isisd (struct csum_vals *vals, testsz_t len, testoff_t off)
#define c0 vals->a.c0
#define c1 vals->a.c1
u_int32_t mul;
-
+
mul = (len - off)*(c0);
x = mul - c0 - c1;
y = c1 - mul - 1;
@@ -148,7 +150,7 @@ reduce_isisd (struct csum_vals *vals, testsz_t len, testoff_t off)
}
/* Is the -1 in y wrong perhaps? */
-static u_int16_t
+static u_int16_t
reduce_isisd_yfix (struct csum_vals *vals, testsz_t len, testoff_t off)
{
#define x vals->x
@@ -156,7 +158,7 @@ reduce_isisd_yfix (struct csum_vals *vals, testsz_t len, testoff_t off)
#define c0 vals->a.c0
#define c1 vals->a.c1
u_int32_t mul;
-
+
mul = (len - off)*(c0);
x = mul - c0 - c1;
y = c1 - mul;
@@ -183,7 +185,7 @@ reduce_isisd_yfix (struct csum_vals *vals, testsz_t len, testoff_t off)
}
/* Move the mods yp */
-static u_int16_t
+static u_int16_t
reduce_isisd_mod (struct csum_vals *vals, testsz_t len, testoff_t off)
{
#define x vals->x
@@ -191,7 +193,7 @@ reduce_isisd_mod (struct csum_vals *vals, testsz_t len, testoff_t off)
#define c0 vals->a.c0
#define c1 vals->a.c1
u_int32_t mul;
-
+
mul = (len - off)*(c0);
x = mul - c1 - c0;
y = c1 - mul - 1;
@@ -218,7 +220,7 @@ reduce_isisd_mod (struct csum_vals *vals, testsz_t len, testoff_t off)
}
/* Move the mods up + fix y */
-static u_int16_t
+static u_int16_t
reduce_isisd_mody (struct csum_vals *vals, testsz_t len, testoff_t off)
{
#define x vals->x
@@ -226,7 +228,7 @@ reduce_isisd_mody (struct csum_vals *vals, testsz_t len, testoff_t off)
#define c0 vals->a.c0
#define c1 vals->a.c1
u_int32_t mul;
-
+
mul = (len - off)*(c0);
x = mul - c0 - c1;
y = c1 - mul;
@@ -264,7 +266,7 @@ struct reductions_t {
{ .name = "isisd-mody", .f = reduce_isisd_mody },
{ NULL, NULL },
};
-
+
/* The original ospfd checksum */
static u_int16_t
ospfd_checksum (u_char *buffer, testsz_t len, testoff_t off)
@@ -276,7 +278,7 @@ ospfd_checksum (u_char *buffer, testsz_t len, testoff_t off)
csum = (u_int16_t *) (buffer + off);
*(csum) = 0;
-
+
sp = buffer;
for (ep = sp + len; sp < ep; sp = q)
@@ -292,27 +294,27 @@ ospfd_checksum (u_char *buffer, testsz_t len, testoff_t off)
c0 %= 255;
c1 %= 255;
}
-
+
ospfd_vals.a.c0 = c0;
ospfd_vals.a.c1 = c1;
-
+
//printf ("%s: len %u, off %u, c0 %d, c1 %d\n",
// __func__, len, off, c0, c1);
x = ((int)(len - off - 1) * (int)c0 - (int)c1) % 255;
-
+
if (x <= 0)
x += 255;
y = 510 - c0 - x;
if (y > 255)
y -= 255;
-
+
ospfd_vals.x = x;
ospfd_vals.y = y;
-
+
buffer[off] = x;
buffer[off + 1] = y;
-
+
/* take care endian issue. */
checksum = htons ((x << 8) | (y & 0xff));
@@ -334,15 +336,15 @@ iso_csum_create (u_char * buffer, testsz_t len, testoff_t off)
int i, init_len, partial_len;
checksum = 0;
-
+
csum = (u_int16_t *) (buffer + off);
*(csum) = checksum;
-
+
p = buffer;
c0 = 0;
c1 = 0;
init_len = len;
-
+
while (len != 0)
{
partial_len = MIN(len, MODX);
@@ -361,7 +363,7 @@ iso_csum_create (u_char * buffer, testsz_t len, testoff_t off)
isisd_vals.a.c0 = c0;
isisd_vals.a.c1 = c1;
-
+
mul = (init_len - off) * c0;
x = mul - c1 - c0;
@@ -379,14 +381,14 @@ iso_csum_create (u_char * buffer, testsz_t len, testoff_t off)
x = 255;
if (y == 0)
y = 1;
-
+
isisd_vals.x = x;
isisd_vals.y = y;
-
+
checksum = htons((x << 8) | (y & 0xFF));
-
+
*(csum) = checksum;
-
+
/* return the checksum for user usage */
return checksum;
}
@@ -399,7 +401,7 @@ verify (u_char * buffer, testsz_t len)
u_int32_t c1;
u_int16_t checksum;
int i, partial_len;
-
+
p = buffer;
checksum = 0;
@@ -427,6 +429,8 @@ verify (u_char * buffer, testsz_t len)
return 1;
}
+extern int in_cksum_optimized(void *parg, int nbytes) ;
+
int /* return checksum in low-order 16 bits */
in_cksum_optimized(void *parg, int nbytes)
{
@@ -458,6 +462,7 @@ in_cksum_optimized(void *parg, int nbytes)
return(answer);
}
+extern int in_cksum_rfc(void *parg, int count) ;
int /* return checksum in low-order 16 bits */
in_cksum_rfc(void *parg, int count)
@@ -495,29 +500,29 @@ main(int argc, char **argv)
u_char buffer[BUFSIZE];
int exercise = 0;
#define EXERCISESTEP 257
-
+
srandom (time (NULL));
-
+
while (1) {
u_int16_t ospfd, isisd, lib, in_csum, in_csum_res, in_csum_rfc;
int i,j;
exercise += EXERCISESTEP;
exercise %= MAXDATALEN;
-
+
for (i = 0; i < exercise; i += sizeof (long int)) {
long int rand = random ();
-
+
for (j = sizeof (long int); j > 0; j--)
buffer[i + (sizeof (long int) - j)] = (rand >> (j * 8)) & 0xff;
}
-
+
in_csum = in_cksum(buffer, exercise);
in_csum_res = in_cksum_optimized(buffer, exercise);
in_csum_rfc = in_cksum_rfc(buffer, exercise);
if (in_csum_res != in_csum || in_csum != in_csum_rfc)
printf ("verify: in_chksum failed in_csum:%x, in_csum_res:%x,"
- "in_csum_rfc %x, len:%d\n",
+ "in_csum_rfc %x, len:%d\n",
in_csum, in_csum_res, in_csum_rfc, exercise);
ospfd = ospfd_checksum (buffer, exercise + sizeof(u_int16_t), exercise);
@@ -529,7 +534,7 @@ main(int argc, char **argv)
lib = fletcher_checksum (buffer, exercise + sizeof(u_int16_t), exercise);
if (verify (buffer, exercise + sizeof(u_int16_t)))
printf ("verify: lib failed\n");
-
+
if (ospfd != lib) {
printf ("Mismatch in values at size %u\n"
"ospfd: 0x%04x\tc0: %d\tc1: %d\tx: %d\ty: %d\n"
@@ -540,12 +545,12 @@ main(int argc, char **argv)
isisd, isisd_vals.a.c0, isisd_vals.a.c1, isisd_vals.x, isisd_vals.y,
lib
);
-
+
/* Investigate reduction phase discrepencies */
if (ospfd_vals.a.c0 == isisd_vals.a.c0
&& ospfd_vals.a.c1 == isisd_vals.a.c1) {
printf ("\n");
- for (i = 0; reducts[i].name != NULL; i++) {
+ for (i = 0; reducts[i].name != NULL; i++) {
ospfd = reducts[i].f (&ospfd_vals,
exercise + sizeof (u_int16_t),
exercise);
@@ -553,7 +558,7 @@ main(int argc, char **argv)
reducts[i].name, ospfd_vals.x & 0xff, ospfd_vals.y & 0xff, ospfd);
}
}
-
+
printf ("\n u_char testdata [] = {\n ");
for (i = 0; i < exercise; i++) {
printf ("0x%02x,%s",
diff --git a/tests/test-list_util.c b/tests/test-list_util.c
new file mode 100644
index 00000000..fc81a562
--- /dev/null
+++ b/tests/test-list_util.c
@@ -0,0 +1,2112 @@
+#include <zebra.h>
+#include <list_util.h>
+#include <string.h>
+
+/* List util torture tests
+ *
+ */
+
+struct thread_master *master; /* allow lib/zebra.c to link ! */
+
+/* prototypes */
+int main(int argc, char **argv);
+
+static void test_ssl(void);
+static void test_sdl(void);
+static void test_ddl(void);
+
+#define test_assert(true, message) \
+ do { if (!(true)) test_assert_fail(#true, message, __func__, __LINE__) ; \
+ } while (0)
+
+static void
+test_assert_fail(const char* true, const char* message, const char* func,
+ int line)
+{
+ printf("*** %s %d: (%s) not true: %s\n", func, line, true, message) ;
+
+} ;
+
+/*==============================================================================
+ * The tests.
+ */
+int
+main(int argc, char **argv)
+{
+ printf("Starting list_util tests -- %s\n",
+#ifdef __GNUC__LIST_UTIL
+ "GNUC version"
+#else
+ "not GNUC version"
+#endif
+ " -- v0.01 26-Feb-2010") ;
+
+ srand(22) ; /* Consistent testing required */
+
+ test_ssl() ;
+ test_sdl() ;
+ test_ddl() ;
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------------
+ * Construct a majic mark from two addresses
+ */
+static unsigned majic(void* a, void* b)
+{
+ uintptr_t z = (uintptr_t)a ^ (uintptr_t)b ^ (uintptr_t)&majic ;
+ return z ;
+} ;
+
+/*==============================================================================
+ * Single Base, Single Link
+ *
+ * ssl_push(base, item, next) -- add at head of list
+ * ssl_del(base, item, next) -- delete from list
+ * ssl_del_head(base, next) -- delete head of list
+ * ssl_pop(dst, base, next) -- pop head of list, if any
+ * ssl_head(base) -- return head of list
+ * ssl_next(item, next) -- step to next item, if any
+ *
+ * Cases to cover:
+ *
+ * a) adding when list is empty
+ * b) adding when list is not empty
+ * c) deletion of first item and more than one item on list
+ * d) deletion of first item when only one item on the list
+ * e) deletion of arbitrary item (list implicitly not empty)
+ * f) deletion when item not on list and list not empty
+ * g) deletion when item not on list and list is empty
+ * h) deletion of NULL item and list not empty
+ * i) deletion of NULL item and list empty
+ * j) pop of head when list not empty
+ * k) pop of head when list contains one item
+ * l) pop of head when list empty
+ * m) deletion of head when list not empty
+ * n) deletion of head when contains one item
+ * o) deletion of head when list empty
+ * p) head when list not empty
+ * q) head when list is empty
+ * r) next when not last
+ * s) next when last
+ */
+
+typedef struct ssl_test* ssl_test ;
+struct ssl_test
+{
+ ssl_test next ; /* pointer at start of structure */
+
+ unsigned majic ;
+ char dummy ;
+
+ ssl_test other_next ; /* pointer elsewhere in structure */
+} ;
+
+struct ssl_test_parent
+{
+ unsigned rubbish ;
+ char fred ;
+
+ ssl_test base ;
+
+ int z[5] ;
+} ;
+
+static struct ssl_test_parent ssl_parent ;
+
+static void
+test_ssl(void)
+{
+ ssl_test base = NULL ;
+
+ ssl_test del = NULL ;
+ ssl_test other_del = NULL ;
+ ssl_test last = NULL ;
+ ssl_test first = NULL ;
+
+ struct ssl_test dummy ;
+
+ int n = 47 ;
+
+ int i_del = 7 ; /* NB: neither of these may be 0 or 1 */
+ int i_other_del = 37 ;
+
+ ssl_test prev ;
+ ssl_test this ;
+ ssl_test other_this ;
+ ssl_test take ;
+ ssl_test temp ;
+
+ int i ;
+ int ret ;
+
+ static struct ssl_test_parent* other = &ssl_parent ;
+
+ memset(other, 77, sizeof(struct ssl_test_parent)) ;
+ other->base = NULL ;
+
+ /* Repeated insertion, starting from empty list
+ *
+ * a) adding when list is empty
+ * b) adding when list is not empty
+ *
+ * Creates lists for following tests.
+ */
+ printf("=== Testing ssl -- Single Base, Single Link -- stuff\n") ;
+
+ printf(" Creating list of items") ;
+ for (i = 1 ; i <= n ; ++i)
+ {
+ ssl_test this = calloc(1, sizeof(struct ssl_test)) ;
+
+ if (last == NULL)
+ last = this ;
+
+ this->majic = majic(this, &base) ;
+
+ this->dummy = i ;
+
+ ssl_push(base, this, next) ;
+ if (i & 1)
+ ssl_push(other->base, this, other_next) ;
+ else
+ ssl_push(ssl_parent.base, this, other_next) ;
+
+ if (i == i_del)
+ del = this ;
+ if (i == i_other_del)
+ other_del = this ;
+
+ first = this ;
+
+ printf("+") ;
+ } ;
+
+ test_assert((base == first) && (other->base == first),
+ "Failed to create consistent lists") ;
+ printf("\n") ;
+
+ passert((del != base) && (del != last)) ;
+ passert((other_del != base) && (other_del != last)) ;
+
+ /* Walk to check that have the expected items
+ *
+ * l) head when list not empty
+ * r) next when not last
+ * s) next when last
+ */
+ printf(" Walking list of items") ;
+
+ this = ssl_head(base) ;
+ test_assert(this == first, "ssl_head failed") ;
+
+ this = ssl_head(other->base) ;
+ test_assert(this == first, "ssl_head failed") ;
+
+ this = ssl_head(ssl_parent.base) ;
+ test_assert(this == first, "ssl_head failed") ;
+
+ this = ssl_next(del, next) ;
+ test_assert((this == del->next) && (this != NULL), "ssl_next failed") ;
+ this = ssl_next(last, next) ;
+ test_assert((this == last->next) && (this == NULL),
+ "ssl_next failed at end") ;
+
+ this = ssl_next(other_del, other_next) ;
+ test_assert((this == other_del->other_next) && (this != NULL),
+ "ssl_next failed") ;
+ this = ssl_next(last, other_next) ;
+ test_assert((this == last->other_next) && (this == NULL),
+ "ssl_next failed at end") ;
+
+ this = base ;
+ other_this = other->base ;
+
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ test_assert(this == other_this, "this and other_this not in step") ;
+ if (this == NULL)
+ break ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ prev = this ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+
+ printf(".") ;
+ this = ssl_next(this, next) ;
+ other_this = ssl_next(other_this, other_next) ;
+ } ;
+ printf("\n") ;
+
+ /* Deletion specifically at the start of the list
+ *
+ * c) deletion of first item and more than one item on list
+ */
+ printf(" Deleting the first item") ;
+
+ this = base ;
+ first = base->next ;
+ ret = ssl_del(base, this, next) ;
+ test_assert(ret == 0, "ssl_del did not return 0") ;
+ test_assert(first == base, "ssl_del of first item failed") ;
+
+ this = other->base ;
+ ret = ssl_del(other->base, this, other_next) ;
+ test_assert(ret == 0, "ssl_del did not return 0") ;
+ test_assert(first == other->base, "ssl_del of first item failed") ;
+
+ printf("\n") ;
+
+ --n ; /* one less on the lists ! */
+
+ /* Deletion of items from arbitrary place in list
+ *
+ * e) deletion of arbitrary item (list implicitly not empty)
+ */
+ printf(" Deleting arbitrary items") ;
+ ret = ssl_del(base, del, next) ;
+ test_assert(ret == 0, "ssl_del did not return 0") ;
+ ret = ssl_del(ssl_parent.base, other_del, other_next) ;
+ test_assert(ret == 0, "ssl_del did not return 0") ;
+ printf("\n") ;
+
+ /* Deletion of items from arbitrary place in list
+ *
+ * f) deletion when item not on list and list not empty
+ */
+ printf(" Deleting non-existant items") ;
+ ret = ssl_del(base, &dummy, next) ;
+ test_assert(ret == -1, "ssl_del did not return -1") ;
+ ret = ssl_del(other->base, &dummy, other_next) ;
+ test_assert(ret == -1, "ssl_del did not return -1") ;
+ printf("\n") ;
+
+ /* Deletion of NULL items
+ *
+ * h) deletion of NULL item and list not empty
+ */
+ printf(" Deleting NULL items") ;
+
+ this = NULL ;
+
+ ret = ssl_del(base, this, next) ;
+ test_assert(ret == 0, "ssl_del did not return 0") ;
+
+ ret = ssl_del(ssl_parent.base, this, other_next) ;
+ test_assert(ret == 0, "ssl_del did not return 0") ;
+
+ printf("\n") ;
+
+ /* Scan lists to check after deletion */
+ printf(" Base list scan") ;
+
+ this = base ;
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ if (this == NULL)
+ break ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ prev = this ;
+
+ if (i == i_del)
+ --i ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+
+ printf("*") ;
+ this = ssl_next(this, next) ;
+ } ;
+ printf("\n") ;
+
+ printf(" Other list scan") ;
+
+ other_this = other->base ;
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ if (other_this == NULL)
+ break ;
+
+ test_assert(other_this != prev, "this is same as prev") ;
+ prev = other_this ;
+
+ if (i == i_other_del)
+ --i ;
+
+ test_assert(other_this->dummy == i--, "don't have the right dummy") ;
+ test_assert(other_this->majic == majic(other_this, &base),
+ "don't have the right majic") ;
+
+ printf("*") ;
+ other_this = ssl_next(other_this, other_next) ;
+ } ;
+ printf("\n") ;
+
+ /* Dismantle lists
+ *
+ * j) pop of head when list not empty
+ * k) pop of head when list contains one item
+ * l) pop of head when list empty
+ * p) head when list not empty
+ * q) head when list is empty
+ */
+ printf(" Popping the head until list is empty\n") ;
+ printf(" Base list") ;
+
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ this = base ;
+ test_assert(this == ssl_head(base), "this is not head !") ;
+
+ temp = ssl_pop(&take, base, next) ;
+ test_assert(this == take, "this is not same as deleted head !") ;
+ test_assert(temp == take, "temp is not same as deleted head !") ;
+
+ if (this == NULL)
+ break ;
+
+ test_assert(base == this->next, "ssl_pop broken") ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ prev = this ;
+
+ if (i == i_del)
+ --i ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+ printf("-") ;
+ } ;
+ test_assert(i == 0, "not the expected final value of 'i'") ;
+ test_assert(base == NULL, "Base list should be empty") ;
+
+ this = ssl_head(base) ;
+ test_assert(this == NULL, "ssl_head of empty list failed") ;
+
+ printf("\n") ;
+
+ printf(" Other list") ;
+
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ this = other->base ;
+ test_assert(this == ssl_head(other->base), "this is not head !") ;
+
+ if (i & 1)
+ temp = ssl_pop(&take, other->base, other_next) ;
+ else
+ temp = ssl_pop(&take, ssl_parent.base, other_next) ;
+
+ test_assert(this == take, "this is not same as deleted head !") ;
+ test_assert(temp == take, "temp is not same as deleted head !") ;
+
+ if (this == NULL)
+ break ;
+
+ test_assert(other->base == this->other_next, "ssl_pop broken") ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ prev = this ;
+
+ if (i == i_other_del)
+ --i ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+ printf("-") ;
+ } ;
+ test_assert(i == 0, "not the expected final value of 'i'") ;
+ test_assert(other->base == NULL, "Other list should be empty") ;
+
+ this = ssl_head(other->base) ;
+ test_assert(this == NULL, "ssl_head of empty list failed") ;
+
+ printf("\n") ;
+
+ /* Rebuild lists to do:
+ *
+ * m) deletion of head when list not empty
+ * n) deletion of head when contains one item
+ * o) deletion of head when list empty
+ */
+ passert((base == NULL) && (other->base == NULL)) ;
+
+ last = NULL ;
+ first = NULL ;
+ prev = NULL ;
+ printf(" Building list of items again") ;
+ for (i = 1 ; i <= n ; ++i)
+ {
+ ssl_test this = calloc(1, sizeof(struct ssl_test)) ;
+
+ if (last == NULL)
+ last = this ;
+
+ this->majic = majic(this, &base) ;
+ this->dummy = i ;
+
+ ssl_push(base, this, next) ;
+ if (i & 1)
+ ssl_push(ssl_parent.base, this, other_next) ;
+ else
+ ssl_push(other->base, this, other_next) ;
+
+ test_assert(this->next == prev, "broken ssl_push") ;
+ test_assert(this->other_next == prev, "broken ssl_push") ;
+
+ test_assert(base == this, "broken ssl_push") ;
+ test_assert(other->base == this, "broken ssl_push") ;
+
+ first = this ;
+ prev = this ;
+
+ printf("+") ;
+ } ;
+
+ printf("\n") ;
+
+ printf(" Deleting the head until list is empty\n") ;
+ printf(" Base list") ;
+
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ this = base ;
+
+ ssl_del_head(base, next) ;
+
+ if (this == NULL)
+ break ;
+
+ test_assert(base == this->next, "ssl_del_head broken") ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ prev = this ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+ printf("-") ;
+ } ;
+ test_assert(i == 0, "not the expected final value of 'i'") ;
+ test_assert(base == NULL, "Base list should be empty") ;
+
+ printf("\n") ;
+
+ printf(" Other list") ;
+
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ this = other->base ;
+
+ if (i & 1)
+ ssl_del_head(ssl_parent.base, other_next) ;
+ else
+ ssl_del_head(other->base, other_next) ;
+
+ if (this == NULL)
+ break ;
+
+ test_assert(other->base == this->other_next, "ssl_del_head broken") ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ prev = this ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+ printf("-") ;
+ } ;
+ test_assert(i == 0, "not the expected final value of 'i'") ;
+ test_assert(other->base == NULL, "Other list should be empty") ;
+
+ printf("\n") ;
+
+ /* Final few tests
+ *
+ * d) deletion of first item when only one item on the list
+ * g) deletion when item not on list and list is empty
+ * i) deletion of NULL item and list empty
+ */
+
+ /* Deletion of items from arbitrary place in list */
+ printf(" Miscellaneous") ;
+
+ del->next = &dummy ;
+ ssl_push(base, del, next) ;
+ test_assert((base == del) && (del->next == NULL), "ssl_push failed ??") ;
+ ssl_del(base, del, next) ;
+ test_assert(base == NULL, "ssl_del of first and only item failed") ;
+
+ other_del->other_next = &dummy ;
+ ssl_push(other->base, other_del, other_next) ;
+ test_assert((other->base == other_del) && (other_del->other_next == NULL),
+ "ssl_push failed ??") ;
+ ssl_del(other->base, other_del, other_next) ;
+ test_assert(other->base == NULL, "ssl_del of first and only item failed") ;
+
+ ret = ssl_del(base, del, next) ;
+ test_assert(ret == -1, "ssl_del did not return -1") ;
+ test_assert(base == NULL, "ssl_del on empty list") ;
+
+ ret = ssl_del(other->base, other_del, other_next) ;
+ test_assert(ret == -1, "ssl_del did not return -1") ;
+ test_assert(other->base == NULL, "ssl_del on empty list") ;
+
+ this = NULL ;
+
+ ret = ssl_del(base, this, next) ;
+ test_assert(ret == 0, "ssl_del did not return 0") ;
+ test_assert(base == NULL, "ssl_del on empty list") ;
+
+ ret = ssl_del(other->base, this, other_next) ;
+ test_assert(ret == 0, "ssl_del did not return 0") ;
+ test_assert(other->base == NULL, "ssl_del on empty list") ;
+
+ printf("\n") ;
+
+} ;
+
+/*==============================================================================
+ * Single Base, Double Link
+ *
+ * sdl_push(base, item, list) -- add at head of list
+ * sdl_del(base, item, list) -- delete from list
+ * sdl_pop(&dst, base, next) -- pop head of list, if any
+ * sdl_head(base) -- return head of list
+ * sdl_next(item, next) -- step to next item, if any
+ * sdl_prev(item, next) -- step to prev item, if any
+ *
+ * Cases to cover:
+ *
+ * a) adding when list is empty
+ * b) adding when list is not empty
+ * c) deletion of first item and more than one item on list
+ * d) deletion of first item when only one item on the list
+ * e) deletion of arbitrary item (list implicitly not empty)
+ * f) deletion of NULL item and list not empty
+ * g) deletion of NULL item and list empty
+ * h) pop of head when list not empty
+ * i) pop of head when list contains one item
+ * j) pop of head when list empty
+ * k) deletion of head when list not empty
+ * l) deletion of head when list contains one item
+ * m) deletion of head when list empty
+ * n) head when list not empty
+ * o) head when list is empty
+ * p) next when not last
+ * q) next when last
+ * r) prev when not first
+ * s) prev when first
+ *
+ * NB: unlike single link stuff, cannot attempt to remove item which is
+ * not on the list !
+ */
+
+typedef struct sdl_test* sdl_test ;
+struct sdl_test
+{
+ struct dl_list_pair(sdl_test) list ;
+
+ unsigned majic ;
+ char dummy ;
+
+ struct dl_list_pair(sdl_test) other_list ;
+};
+
+struct sdl_test_parent
+{
+ long rubbish ;
+ char fred ;
+
+ sdl_test base ;
+
+ int z[7] ;
+} ;
+
+static struct sdl_test_parent sdl_parent ;
+
+static void
+test_sdl(void)
+{
+ sdl_test base = NULL ;
+
+ sdl_test del = NULL ;
+ sdl_test other_del = NULL ;
+ sdl_test last = NULL ;
+ sdl_test first = NULL ;
+
+ struct sdl_test dummy ;
+
+ int n = 57 ;
+
+ int i_del = 9 ; /* NB: neither of these may be 0 or 1 */
+ int i_other_del = 49 ;
+
+ sdl_test prev ;
+ sdl_test this ;
+ sdl_test other_this ;
+ sdl_test take ;
+ sdl_test temp ;
+
+ int i ;
+
+ static struct sdl_test_parent* other = &sdl_parent ;
+
+ memset(other, 99, sizeof(struct sdl_test_parent)) ;
+ other->base = NULL ;
+
+ /* Repeated insertion, starting from empty list
+ *
+ * a) adding when list is empty
+ * b) adding when list is not empty
+ *
+ * Creates lists for following tests.
+ */
+ printf("=== Testing sdl -- Single Base, Double Link -- stuff\n") ;
+
+ printf(" Creating list of items") ;
+ for (i = 1 ; i <= n ; ++i)
+ {
+ sdl_test this = calloc(1, sizeof(struct sdl_test)) ;
+
+ if (last == NULL)
+ last = this ;
+
+ this->majic = majic(this, &base) ;
+
+ this->dummy = i ;
+
+ sdl_push(base, this, list) ;
+ if (i & 1)
+ sdl_push(other->base, this, other_list) ;
+ else
+ sdl_push(sdl_parent.base, this, other_list) ;
+
+ if (i == i_del)
+ del = this ;
+ if (i == i_other_del)
+ other_del = this ;
+
+ first = this ;
+
+ printf("+") ;
+ } ;
+
+ test_assert((base == first) && (other->base == first),
+ "Failed to create consistent lists") ;
+
+ printf("\n") ;
+
+ passert((del != base) && (del != last)) ;
+ passert((other_del != base) && (other_del != last)) ;
+
+ /* Walk to check that have the expected items
+ *
+ * n) head when list not empty
+ * p) next when not last
+ * q) next when last
+ * r) prev when not first
+ * s) prev when first
+ */
+ printf(" Walking list of items") ;
+
+ this = sdl_head(base) ;
+ test_assert(this == first, "sdl_head failed") ;
+
+ this = sdl_head(other->base) ;
+ test_assert(this == first, "sdl_head failed") ;
+
+ this = sdl_head(sdl_parent.base) ;
+ test_assert(this == first, "sdl_head failed") ;
+
+ /* next on both lists */
+ this = sdl_next(first, list) ;
+ test_assert((this == first->list.next) && (this != NULL),
+ "sdl_next failed at start") ;
+ this = sdl_next(del, list) ;
+ test_assert((this == del->list.next) && (this != NULL), "sdl_next failed") ;
+ this = sdl_next(last, list) ;
+ test_assert((this == last->list.next) && (this == NULL),
+ "sdl_next failed at end") ;
+
+ this = sdl_next(first, other_list) ;
+ test_assert((this == first->other_list.next) && (this != NULL),
+ "sdl_next failed at start") ;
+ this = sdl_next(other_del, other_list) ;
+ test_assert((this == other_del->other_list.next) && (this != NULL),
+ "sdl_next failed") ;
+ this = sdl_next(last, other_list) ;
+ test_assert((this == last->other_list.next) && (this == NULL),
+ "sdl_next failed at end") ;
+
+ /* prev on both lists */
+ this = sdl_prev(first, list) ;
+ test_assert((this == first->list.prev) && (this == NULL),
+ "sdl_prev failed at start") ;
+ this = sdl_prev(del, list) ;
+ test_assert((this == del->list.prev) && (this != NULL), "sdl_prev failed") ;
+ this = sdl_prev(last, list) ;
+ test_assert((this == last->list.prev) && (this != NULL),
+ "sdl_prev failed at end") ;
+
+ this = sdl_prev(first, other_list) ;
+ test_assert((this == first->other_list.prev) && (this == NULL),
+ "sdl_prev failed at start") ;
+ this = sdl_prev(other_del, other_list) ;
+ test_assert((this == other_del->other_list.prev) && (this != NULL),
+ "sdl_prev failed") ;
+ this = sdl_prev(last, other_list) ;
+ test_assert((this == last->other_list.prev) && (this != NULL),
+ "sdl_prev failed at end") ;
+
+ this = base ;
+ other_this = other->base ;
+
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ test_assert(this == other_this, "this and other_this not in step") ;
+ if (this == NULL)
+ break ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ prev = this ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+
+ printf(".") ;
+ this = sdl_next(this, list) ;
+ other_this = sdl_next(other_this, other_list) ;
+ } ;
+ printf("\n") ;
+
+ /* Deletion specifically at the start of the list
+ *
+ * c) deletion of first item and more than one item on list
+ */
+ printf(" Deleting the first item") ;
+
+ this = base ;
+ first = base->list.next ;
+ sdl_del(base, this, list) ;
+ test_assert(first == base, "sdl_del of first item failed") ;
+ test_assert((base == NULL) || (base->list.prev == NULL), "sdl_del failed") ;
+
+ this = other->base ;
+ sdl_del(sdl_parent.base, this, other_list) ;
+ test_assert(first == other->base, "sdl_del of first item failed") ;
+ test_assert((base == NULL) || (base->other_list.prev == NULL),
+ "sdl_del failed") ;
+
+ printf("\n") ;
+
+ --n ; /* one less on the lists ! */
+
+ /* Deletion of items from arbitrary place in list
+ *
+ * e) deletion of arbitrary item (list implicitly not empty)
+ */
+ printf(" Deleting arbitrary items") ;
+ sdl_del(base, del, list) ;
+ test_assert((base == NULL) || (base->list.prev == NULL), "sdl_del failed") ;
+ sdl_del(sdl_parent.base, other_del, other_list) ;
+ test_assert((base == NULL) || (base->other_list.prev == NULL),
+ "sdl_del failed") ;
+ printf("\n") ;
+
+ /* Deletion of NULL items
+ *
+ * f) deletion of NULL item and list not empty
+ */
+ printf(" Deleting NULL items") ;
+ this = NULL ;
+ sdl_del(base, this, list) ;
+ test_assert((base == NULL) || (base->list.prev == NULL), "sdl_del failed") ;
+ sdl_del(other->base, this, other_list) ;
+ test_assert((base == NULL) || (base->other_list.prev == NULL),
+ "sdl_del failed") ;
+ printf("\n") ;
+
+ /* Scan lists to check after deletion */
+ printf(" Base list scan") ;
+
+ this = base ;
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ if (this == NULL)
+ break ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ test_assert(this->list.prev == prev, "broken prev pointer") ;
+
+ if (i == i_del)
+ --i ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+ printf("*") ;
+
+ prev = this ;
+ this = sdl_next(this, list) ;
+
+ test_assert(this == prev->list.next, "broken sdl_next") ;
+ if (this != NULL)
+ test_assert(prev == sdl_prev(this, list), "broken sdl_prev") ;
+ } ;
+ printf("\n") ;
+
+ printf(" Other list scan") ;
+
+ this = other->base ;
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ if (this == NULL)
+ break ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ test_assert(this->other_list.prev == prev, "broken prev pointer") ;
+
+ if (i == i_other_del)
+ --i ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+
+ printf("*") ;
+
+ prev = this ;
+ this = sdl_next(this, other_list) ;
+
+ test_assert(this == prev->other_list.next, "broken sdl_next") ;
+ if (this != NULL)
+ test_assert(prev == sdl_prev(this, other_list), "broken sdl_prev") ;
+ } ;
+ printf("\n") ;
+
+ /* Dismantle lists
+ *
+ * h) pop of head when list not empty
+ * i) pop of head when list contains one item
+ * j) pop of head when list empty
+ * o) head when list is empty
+ */
+ printf(" Popping the head until list is empty\n") ;
+ printf(" Base list") ;
+
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ this = sdl_head(base) ;
+ test_assert(this == base, "broken sdl_head !") ;
+
+ temp = sdl_pop(&take, base, list) ;
+ test_assert(this == take, "take is not same as deleted head !") ;
+ test_assert(this == temp, "temp is not same as deleted head !") ;
+ if (base != NULL)
+ test_assert(base->list.prev == NULL, "sdl_pop failed") ;
+
+ if (this == NULL)
+ break ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ prev = this ;
+
+ if (i == i_del)
+ --i ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+ printf("-") ;
+ } ;
+ test_assert(i == 0, "not the expected final value of 'i'") ;
+ test_assert(base == NULL, "Base list should be empty") ;
+
+ this = sdl_head(base) ;
+ test_assert(this == NULL, "sdl_head of empty list failed") ;
+
+ printf("\n") ;
+
+ printf(" Other list") ;
+
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ this = sdl_head(other->base) ;
+ test_assert(this == other->base, "broken sdl_head !") ;
+
+ if (i & 1)
+ temp = sdl_pop(&take, sdl_parent.base, other_list) ;
+ else
+ temp = sdl_pop(&take, other->base, other_list) ;
+
+ test_assert(this == take, "take is not same as deleted head !") ;
+ test_assert(this == temp, "temp is not same as deleted head !") ;
+ if (other->base != NULL)
+ test_assert(other->base->other_list.prev == NULL,
+ "sdl_pop failed") ;
+ if (this == NULL)
+ break ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ prev = this ;
+
+ if (i == i_other_del)
+ --i ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+
+ printf("-") ;
+ } ;
+ test_assert(i == 0, "not the expected final value of 'i'") ;
+ test_assert(other->base == NULL, "Other list should be empty") ;
+
+ this = sdl_head(other->base) ;
+ test_assert(this == NULL, "sdl_head of empty list failed") ;
+
+ printf("\n") ;
+
+ /* Rebuild lists to do:
+ *
+ * k) deletion of head when list not empty
+ * l) deletion of head when list contains one item
+ * m) deletion of head when list empty
+ */
+ passert((base == NULL) && (other->base == NULL)) ;
+
+ last = NULL ;
+ first = NULL ;
+ prev = NULL ;
+ printf(" Building list of items again") ;
+ for (i = 1 ; i <= n ; ++i)
+ {
+ sdl_test this = calloc(1, sizeof(struct sdl_test)) ;
+
+ if (last == NULL)
+ last = this ;
+
+ this->majic = majic(this, &base) ;
+ this->dummy = i ;
+
+ sdl_push(base, this, list) ;
+ if (i & 1)
+ sdl_push(sdl_parent.base, this, other_list) ;
+ else
+ sdl_push(other->base, this, other_list) ;
+
+ test_assert(this->list.next == prev, "broken sdl_push") ;
+ test_assert(this->other_list.next == prev, "broken sdl_push") ;
+
+ test_assert(base == this, "broken sdl_push") ;
+ test_assert(other->base == this, "broken sdl_push") ;
+
+ first = this ;
+ prev = this ;
+
+ printf("+") ;
+ } ;
+
+ printf("\n") ;
+
+ printf(" Deleting the head until list is empty\n") ;
+ printf(" Base list") ;
+
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ this = base ;
+
+ sdl_del_head(base, list) ;
+
+ if (this == NULL)
+ break ;
+
+ test_assert(base == this->list.next, "sdl_del_head broken") ;
+ if (base != NULL)
+ test_assert(base->list.prev == NULL, "sdl_del_head broken") ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ prev = this ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+ printf("-") ;
+ } ;
+ test_assert(i == 0, "not the expected final value of 'i'") ;
+ test_assert(base == NULL, "Base list should be empty") ;
+
+ printf("\n") ;
+
+ printf(" Other list") ;
+
+ prev = NULL ;
+ i = n ;
+ while (1)
+ {
+ this = other->base ;
+
+ if (i & 1)
+ sdl_del_head(other->base, other_list) ;
+ else
+ sdl_del_head(sdl_parent.base, other_list) ;
+
+ if (this == NULL)
+ break ;
+
+ test_assert(other->base == this->other_list.next, "sdl_del_head broken") ;
+ if (other->base != NULL)
+ test_assert(other->base->other_list.prev == NULL,
+ "sdl_del_head broken") ;
+
+ test_assert(this != prev, "this is same as prev") ;
+ prev = this ;
+
+ test_assert(this->dummy == i--, "don't have the right dummy") ;
+ test_assert(this->majic == majic(this, &base),
+ "don't have the right majic") ;
+ printf("-") ;
+ } ;
+ test_assert(i == 0, "not the expected final value of 'i'") ;
+ test_assert(other->base == NULL, "Other list should be empty") ;
+
+ printf("\n") ;
+
+ /* Final few tests
+ *
+ * d) deletion of first item when only one item on the list
+ * g) deletion of NULL item and list empty
+ */
+
+ /* Deletion of items from arbitrary place in list */
+ printf(" Miscellaneous") ;
+
+ del->list.next = &dummy ;
+ sdl_push(base, del, list) ;
+ test_assert((base == del) && (del->list.next == NULL), "sdl_push failed ??") ;
+ sdl_del(base, del, list) ;
+ test_assert(base == NULL, "sdl_del of first and only item failed") ;
+
+ other_del->other_list.next = &dummy ;
+ sdl_push(other->base, other_del, other_list) ;
+ test_assert((other->base == other_del) && (other_del->other_list.next == NULL),
+ "sdl_push failed ??") ;
+ sdl_del(other->base, other_del, other_list) ;
+ test_assert(other->base == NULL, "sdl_del of first and only item failed") ;
+
+ this = NULL ;
+ sdl_del(base, this, list) ;
+ test_assert(base == NULL, "sdl_del of NULL item with empty list") ;
+
+ sdl_del(other->base, this, other_list) ;
+ test_assert(other->base == NULL, "sdl_del of NULL item with empty list") ;
+
+ printf("\n") ;
+} ;
+
+/*==============================================================================
+ * Double Base, Double Link
+ *
+ * ddl_init(base) -- initialise base
+ * ddl_push(base, item, list) -- insert at head of list
+ * ddl_append(base, item, list) -- insert at tail of list
+ * ddl_in_after(after, base, item, list) -- insert after
+ * ddl_in_before(before, base, item, list) -- insert before
+ * ddl_pop(&dst, base, next) -- pop head of list, if any
+ * ddl_crop(&dst, base, next) -- crop tail of list, if any
+ * ddl_del(base, item, list) -- delete from list
+ * ddl_del_head(base, next) -- delete head of list
+ * ddl_del_tail(base, next) -- delete tail of list
+ * ddl_head(base) -- return head of list
+ * ddl_tail(base) -- return tail of list
+ * ddl_next(item, next) -- step to next item, if any
+ * ddl_prev(item, next) -- step to prev item, if any
+ *
+ * Cases to cover:
+ */
+
+/* Testing runs two lists through struct ddt_item objects. */
+
+enum list { a_list, b_list, list_count } ;
+
+typedef struct ddt_item* ddt_item ;
+
+struct ddt_list_pair dl_list_pair(ddt_item) ; /* Example struct constructor */
+struct ddt_base_pair dl_base_pair(ddt_item) ;
+
+typedef struct dl_base_pair(ddt_item) ddt_base_pair_t ;
+ /* Example typedef constructor */
+typedef struct dl_base_pair(ddt_item)* p_ddt_base_pair ;
+ /* Example typedef constructor */
+
+typedef struct ddt_list_pair* ddt_list_pair ;
+typedef struct ddt_base_pair* ddt_base_pair ;
+
+typedef struct ddt_rank* ddt_rank ;
+
+struct ddt_rank /* information for each list */
+{
+ struct ddt_list_pair list ; /* the thing we are testing */
+
+ int lister ;
+ int list_found ;
+ unsigned majic ;
+
+ int ordinal ;
+};
+
+struct ddt_item /* the test items */
+{
+ struct ddt_rank a ;
+
+ char a_rubbish[21] ;
+
+ struct ddt_rank b ;
+
+ char b_rubbish[19] ;
+} ;
+
+/* The test list base pairs, and pointers to the actual bases, for use in
+ * the verification code.
+ */
+static ddt_base_pair ddt_bases[list_count] ;
+
+/* For some tests want to construct lists and know the first, last and
+ * somewhere between items.
+ */
+
+enum where { first, middle, last, where_count } ;
+
+struct ddt_test_list_items
+{
+ struct
+ {
+ ddt_item where[where_count] ;
+ } list[list_count] ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * The test list items -- keep track here also for use in verification.
+ */
+enum { ddt_max_items = 1000 } ;
+
+static unsigned ddt_item_count = 0 ;
+static unsigned ddt_item_alloc = 0 ;
+static ddt_item ddt_items[ddt_max_items] ;
+
+static inline ddt_item
+ddt_new_item(void)
+{
+ ddt_item item ;
+
+ assert(ddt_item_count <= ddt_item_alloc) ;
+
+ if (ddt_item_count == ddt_item_alloc)
+ {
+ assert(ddt_item_alloc < ddt_max_items) ;
+ ddt_items[ddt_item_alloc++] = malloc(sizeof(struct ddt_item)) ;
+ } ;
+
+ item = ddt_items[ddt_item_count++] ;
+
+ memset(item, ddt_item_count & 0xFF, sizeof(struct ddt_item)) ;
+
+ item->a.lister = 0 ;
+ item->b.lister = 0 ;
+
+ item->a.ordinal = 0 ;
+ item->b.ordinal = 0 ;
+
+ return item ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Given an item and a list ordinal, return pointer to "rank" for item.
+ */
+static inline ddt_rank
+ddt_get_rank(ddt_item item, enum list l)
+{
+ if (item == NULL)
+ return NULL ;
+
+ if (l == a_list)
+ return &item->a ;
+ if (l == b_list)
+ return &item->b ;
+
+ assert(0) ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Keep track of what should be found on the lists, and majic marker to check
+ * that don't get lost and point into space.
+ */
+static inline unsigned
+ddt_get_majic(ddt_item item, enum list l)
+{
+ return majic(item, ddt_bases[l]) ;
+} ;
+
+static void
+ddt_test_list_add(ddt_item item, enum list l)
+{
+ ddt_rank rank = ddt_get_rank(item, l) ;
+
+ test_assert(rank->lister == 0, "already on list") ;
+
+ rank->lister = 1 ;
+ rank->majic = ddt_get_majic(item, l) ;
+ rank->ordinal = 0 ; /* unknown ordinal */
+} ;
+
+static void
+ddt_test_list_del(ddt_item item, enum list l)
+{
+ ddt_rank rank ;
+
+ if (item == NULL)
+ return ;
+
+ rank = ddt_get_rank(item, l) ;
+
+ test_assert(rank->lister == 1, "not on list") ;
+
+ rank->lister = 0 ;
+ rank->majic = 0 ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Verification code.
+ *
+ * Blunt instrument to check that all known lists are valid. Checks:
+ *
+ * * bases are both NULL together, or both not NULL.
+ *
+ * * first and last items on the list have suitable prev/next pointers.
+ *
+ * * walk list to confirm, for each item:
+ *
+ * -- prev pointer valid for each item
+ * -- item majic is correct (so not pointing somewhere invalid)
+ * -- item is supposed to be on the list
+ * -- item has not already been seen on list (list bent)
+ * -- ordinal, if not zero, is bigger than any previous non-zero ordinal
+ *
+ * * last item visited on walk is what the tail points to
+ *
+ * * for any items which are supposed to be on list, but were not found
+ */
+static void
+ddt_verify_lists(void)
+{
+ ddt_base_pair base ;
+ ddt_rank r ;
+ ddt_item this ;
+ ddt_item prev ;
+ int l ;
+ int i ;
+
+ /* Wash the found flags */
+ for (l = 0 ; l < list_count ; ++l)
+ for (i = 0 ; i < (int)ddt_item_count ; ++i)
+ ddt_get_rank(ddt_items[i], l)->list_found = 0 ;
+
+ /* Walk the lists */
+ for (l = 0 ; l < list_count ; ++l)
+ {
+ int ordinal = 0 ;
+
+ base = ddt_bases[l] ;
+ if (base == NULL)
+ continue ;
+
+ if ((base->head == NULL) || (base->tail == NULL))
+ test_assert(base->head == base->tail, "broken list bases") ;
+ else
+ {
+ r = ddt_get_rank(base->head, l) ;
+ test_assert(r->list.prev == NULL, "broken list first item->prev") ;
+ r = ddt_get_rank(base->tail, l) ;
+ test_assert(r->list.next == NULL, "broken list last item->next") ;
+
+ this = base->head ;
+ prev = NULL ;
+
+ while (this != NULL)
+ {
+ r = ddt_get_rank(this, l) ;
+
+ test_assert(r->list.prev == prev, "broken item->prev") ;
+
+ test_assert(r->lister, "should not be on this list") ;
+
+ test_assert(!r->list_found, "circular list") ;
+ r->list_found = 1 ;
+
+ if (r->ordinal != 0)
+ {
+ test_assert(r->ordinal > ordinal, "list out of order") ;
+ ordinal = r->ordinal ;
+ }
+
+ test_assert(r->majic == ddt_get_majic(this, l),
+ "wrong sort of majic") ;
+ prev = this ;
+ this = r->list.next ;
+ } ;
+
+ test_assert(base->tail == prev, "broken tail pointer") ;
+ } ;
+ } ;
+
+ /* Verify that did not miss anything should have found */
+ /* Wash the found flags */
+ for (l = 0 ; l < list_count ; ++l)
+ for (i = 0 ; i < (int)ddt_item_count ; ++i)
+ {
+ r = ddt_get_rank(ddt_items[i], l) ;
+
+ if (r->lister)
+ test_assert(r->list_found, "should have found this on list") ;
+ } ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Reset the test list handling
+ *
+ */
+static void
+ddt_reset_lists(void)
+{
+ int l ;
+
+ for (l = 0 ; l < list_count ; ++l)
+ ddl_init(*(ddt_bases[l])) ;
+
+ ddt_item_count = 0 ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Make lists with 'n' items each.
+ *
+ * If 'n' 0..3, makes lists with exactly that many items.
+ *
+ * Otherwise, list length has +/- 25% jitter.
+ */
+static void
+ddt_test_make_lists(struct ddt_test_list_items* test, int n)
+{
+ ddt_base_pair base ;
+ ddt_item item ;
+ ddt_rank rank ;
+ enum list l ;
+ int t ;
+ int m ;
+
+ int req[list_count] ;
+ int mid[list_count] ;
+
+ /* Capture the requirements */
+ t = 0 ;
+ m = 1 ;
+ for (l = 0 ; l < list_count ; ++l)
+ {
+ m += m ;
+ int j = (n + 1) / 4 ;
+
+ if (n <= 3)
+ req[l] = n ;
+ else
+ req[l] = n - j + (rand() % (j + j + 1)) ;
+
+ mid[l] = req[l] / 2 ;
+
+ t += req[l] ;
+
+ test->list[l].where[first] = NULL ;
+ test->list[l].where[middle] = NULL ;
+ test->list[l].where[last] = NULL ;
+ } ;
+
+ ddt_reset_lists() ;
+
+ /* Have t = total number of items still required
+ * m = 2^n -- where there are 'n' lists
+ */
+ while (t != 0)
+ {
+ int b ;
+ int r ;
+ r = (rand() % (m - 1)) + 1 ; /* bit pattern, at least one set */
+
+ item = ddt_new_item() ;
+
+ b = 1 ;
+ for (l = 0 ; l < list_count ; ++l)
+ {
+ if ((req[l] != 0) && ((r & b) != 0))
+ {
+ --req[l] ;
+ --t ;
+
+ ddt_test_list_add(item, l) ;
+
+ if (test->list[l].where[first] == NULL)
+ test->list[l].where[first] = item ;
+
+ if (mid[l]-- == 0)
+ test->list[l].where[middle] = item ;
+
+ test->list[l].where[last] = item ;
+
+ base = ddt_bases[l] ;
+ rank = ddt_get_rank(item, l) ;
+
+ if (base->head == NULL)
+ {
+ base->head = item ;
+ base->tail = item ;
+ rank->list.next = NULL ;
+ rank->list.prev = NULL ;
+ }
+ else if (rand() & 1)
+ {
+ rank->list.next = base->head ;
+ rank->list.prev = NULL ;
+ ddt_get_rank(base->head, l)->list.prev = item ;
+ base->head = item ;
+ }
+ else
+ {
+ rank->list.next = NULL ;
+ rank->list.prev = base->tail ;
+ ddt_get_rank(base->tail, l)->list.next = item ;
+ base->tail = item ;
+ }
+ } ;
+ b <<= 1 ;
+ }
+ } ;
+
+ /* Number the items */
+ for (l = 0 ; l < list_count ; ++l)
+ {
+ int o = 0 ;
+
+ base = ddt_bases[l] ;
+
+ item = base->head ;
+ while (item != NULL)
+ {
+ rank = ddt_get_rank(item, l) ;
+ rank->ordinal = ++o ; /* first is 1 */
+ item = rank->list.next ;
+ } ;
+ } ;
+
+ ddt_verify_lists() ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * ddl_init(base) -- initialise base
+ * ddl_push(base, item, list) -- insert at head of list
+ * ddl_append(base, item, list) -- insert at tail of list
+ * ddl_in_after(after, base, item, list) -- insert after
+ * ddl_in_before(before, base, item, list) -- insert before
+ * ddl_pop(&dst, base, next) -- pop head of list, if any
+ * ddl_crop(&dst, base, next) -- crop tail of list, if any
+ * ddl_del(base, item, list) -- delete from list
+ * ddl_del_head(base, next) -- delete head of list
+ * ddl_del_tail(base, next) -- delete tail of list
+ * ddl_head(base) -- return head of list
+ * ddl_tail(base) -- return tail of list
+ * ddl_next(item, next) -- step to next item, if any
+ * ddl_prev(item, next) -- step to prev item, if any
+ */
+
+static struct ddt_parent
+{
+ char zlxq[37] ;
+
+ struct ddt_base_pair base ;
+
+ char qxlz[45] ;
+} ddt_parent ;
+
+static void
+test_ddl(void)
+{
+ struct ddt_base_pair a_base ;
+ struct ddt_parent* b ;
+
+ struct ddt_test_list_items test ;
+ int n ;
+ int o ;
+
+ int base_n = 23 ;
+ int rand_n = 17 ;
+
+ printf("=== Testing ddl -- Double Base, Double Link -- stuff\n") ;
+
+ /* Initialise the test support */
+ ddt_bases[a_list] = &a_base ;
+ ddt_bases[b_list] = &ddt_parent.base ;
+
+ ddt_item_count = 0 ;
+ ddt_item_alloc = 0 ;
+
+ /* Initialise the list bases */
+ b = &ddt_parent ;
+ memset(b, 42, sizeof(struct ddt_parent)) ;
+
+ ddl_init(a_base) ;
+ ddl_init(b->base) ;
+
+ ddt_verify_lists() ; /* start as mean to go on */
+
+
+ /* ddl_push(base, item, list) -- insert at head of list
+ *
+ * Cases: (a) empty list
+ * (b) list with one item
+ * (c) list with multiple items
+ */
+ printf(" ddl_push test") ;
+ ddt_reset_lists() ;
+
+ n = base_n + (rand() % rand_n) ;
+ while (n)
+ {
+ ddt_item item ;
+ int r ;
+
+ printf(".") ;
+
+ item = ddt_new_item() ;
+ r = (rand() % 3) + 1 ;
+
+ if (r & 1)
+ {
+ ddl_push(a_base, item, a.list) ;
+ test_assert(a_base.head == item, "ddl_push broken") ;
+ ddt_test_list_add(item, a_list) ;
+ item->a.ordinal = n ;
+ } ;
+ ddt_verify_lists() ;
+
+ if (r & 2)
+ {
+ ddl_push(b->base, item, b.list) ;
+ test_assert(b->base.head == item, "ddl_push broken") ;
+ ddt_test_list_add(item, b_list) ;
+ item->b.ordinal = n ;
+ } ;
+ ddt_verify_lists() ;
+
+ --n ;
+ } ;
+ printf("\n") ;
+
+ /* ddl_append(base, item, list) -- insert at tail of list
+ *
+ * Cases: (a) empty list
+ * (b) list with one item
+ * (c) list with multiple items
+ */
+ printf(" ddl_append test") ;
+ ddt_reset_lists() ;
+
+ n = base_n + (rand() % rand_n) ;
+ o = 0 ;
+ while (n)
+ {
+ ddt_item item ;
+ int r ;
+
+ printf(".") ;
+ ++o ;
+
+ item = ddt_new_item() ;
+ r = (rand() % 3) + 1 ;
+
+ if (r & 1)
+ {
+ ddl_append(a_base, item, a.list) ;
+ test_assert(a_base.tail == item, "ddl_append broken") ;
+ ddt_test_list_add(item, a_list) ;
+ item->a.ordinal = o ;
+ } ;
+ ddt_verify_lists() ;
+
+ if (r & 2)
+ {
+ ddl_append(b->base, item, b.list) ;
+ test_assert(b->base.tail == item, "ddl_append broken") ;
+ ddt_test_list_add(item, b_list) ;
+ item->b.ordinal = o ;
+ } ;
+ ddt_verify_lists() ;
+
+ --n ;
+ } ;
+ printf("\n") ;
+
+ /* ddl_in_after(after, base, item, list) -- insert after
+ *
+ * Cases: (a) after first and only (so is also last)
+ * (b) after first when more than one
+ * (c) after last when more than one
+ * (d) after something between
+ */
+ printf(" ddl_in_after test") ;
+
+ n = base_n + (rand() % rand_n) ;
+ while (n)
+ {
+ ddt_item item ;
+ ddt_item after ;
+
+ printf(".") ;
+ ddt_test_make_lists(&test, n) ;
+
+ item = ddt_new_item() ;
+ after = test.list[a_list].where[n % where_count] ;
+ ddl_in_after(after, a_base, item, a.list) ;
+ test_assert(after->a.list.next == item, "ddl_in_after broken") ;
+ test_assert(item->a.list.prev == after, "ddl_in_after broken") ;
+ ddt_test_list_add(item, a_list) ;
+ ddt_verify_lists() ;
+
+ item = ddt_new_item() ;
+ after = test.list[b_list].where[n % where_count] ;
+ ddl_in_after(after, b->base, item, b.list) ;
+ test_assert(after->b.list.next == item, "ddl_in_after broken") ;
+ test_assert(item->b.list.prev == after, "ddl_in_after broken") ;
+ ddt_test_list_add(item, b_list) ;
+ ddt_verify_lists() ;
+
+ --n ;
+ } ;
+ printf("\n") ;
+
+ /* ddl_in_before(before, base, item, list) -- insert before
+ *
+ * Cases: (a) before first and only (so is also last)
+ * (b) before first when more than one
+ * (c) before last when more than one
+ * (d) before something between
+ */
+ printf(" ddl_in_before test") ;
+
+ n = base_n + (rand() % rand_n) ;
+ while (n)
+ {
+ ddt_item item ;
+ ddt_item before ;
+
+ printf(".") ;
+
+ ddt_test_make_lists(&test, n) ;
+
+ item = ddt_new_item() ;
+ before = test.list[a_list].where[n % where_count] ;
+ ddl_in_before(before, a_base, item, a.list) ;
+ test_assert(before->a.list.prev == item, "ddl_in_before broken") ;
+ test_assert(item->a.list.next == before, "ddl_in_before broken") ;
+ ddt_test_list_add(item, a_list) ;
+ ddt_verify_lists() ;
+
+ item = ddt_new_item() ;
+ before = test.list[b_list].where[n % where_count] ;
+ ddl_in_before(before, b->base, item, b.list) ;
+ test_assert(before->b.list.prev == item, "ddl_in_before broken") ;
+ test_assert(item->b.list.next == before, "ddl_in_before broken") ;
+ ddt_test_list_add(item, b_list) ;
+ ddt_verify_lists() ;
+
+ --n ;
+ } ;
+ printf("\n") ;
+
+ /* ddl_pop(&dst, base, next) -- pop head of list, if any
+ *
+ * Cases: (a) list with more than one item
+ * (b) list with one item
+ * (c) empty list
+ */
+ printf(" ddl_pop test") ;
+
+ n = base_n + (rand() % rand_n) ;
+ while (n >= 0)
+ {
+ ddt_item item ;
+ ddt_item temp ;
+ ddt_item peek ;
+ int ordinal ;
+
+ printf(".") ;
+
+ ddt_test_make_lists(&test, n) ;
+
+ ordinal = 0 ;
+ while (1)
+ {
+ peek = a_base.head ;
+ temp = ddl_pop(&item, a_base, a.list) ;
+ test_assert(temp == item, "ddl_pop broken") ;
+ test_assert(peek == item, "ddl_pop broken") ;
+
+ ddt_test_list_del(item, a_list) ;
+ ddt_verify_lists() ;
+
+ if (item == NULL)
+ break ;
+
+ ++ordinal ;
+ test_assert(item->a.ordinal == ordinal, "ddl_pop not in order") ;
+ } ;
+
+ ordinal = 0 ;
+ while (1)
+ {
+ peek = b->base.head ;
+ temp = ddl_pop(&item, b->base, b.list) ;
+ test_assert(temp == item, "ddl_pop broken") ;
+ test_assert(peek == item, "ddl_pop broken") ;
+
+ ddt_test_list_del(item, b_list) ;
+ ddt_verify_lists() ;
+
+ if (item == NULL)
+ break ;
+
+ ++ordinal ;
+ test_assert(item->b.ordinal == ordinal, "ddl_pop not in order") ;
+ } ;
+
+ --n ;
+ } ;
+ printf("\n") ;
+
+ /* ddl_crop(&dst, base, next) -- crop tail of list, if any
+ *
+ * Cases: (a) list with more than one item
+ * (b) list with one item
+ * (c) empty list
+ */
+
+ printf(" ddl_crop test") ;
+
+ n = base_n + (rand() % rand_n) ;
+ while (n >= 0)
+ {
+ ddt_item item ;
+ ddt_item temp ;
+ ddt_item peek ;
+ int ordinal ;
+
+ printf(".") ;
+
+ ddt_test_make_lists(&test, n) ;
+
+ ordinal = 0 ;
+ while (1)
+ {
+ peek = a_base.tail ;
+ temp = ddl_crop(&item, a_base, a.list) ;
+ test_assert(temp == item, "ddl_crop broken") ;
+ test_assert(peek == item, "ddl_crop broken") ;
+
+ ddt_test_list_del(item, a_list) ;
+ ddt_verify_lists() ;
+
+ if (item == NULL)
+ break ;
+
+ if (ordinal == 0)
+ ordinal = item->a.ordinal ;
+ else
+ {
+ test_assert(ordinal > 0, "ordinal out of whack") ;
+ --ordinal ;
+ test_assert(item->a.ordinal == ordinal, "ddl_crop not in order") ;
+ } ;
+ } ;
+
+ ordinal = 0 ;
+ while (1)
+ {
+ peek = b->base.tail ;
+ temp = ddl_crop(&item, b->base, b.list) ;
+ test_assert(temp == item, "ddl_crop broken") ;
+ test_assert(peek == item, "ddl_crop broken") ;
+
+ ddt_test_list_del(item, b_list) ;
+ ddt_verify_lists() ;
+
+ if (item == NULL)
+ break ;
+
+ if (ordinal == 0)
+ ordinal = item->b.ordinal ;
+ else
+ {
+ test_assert(ordinal > 0, "ordinal out of whack") ;
+ --ordinal ;
+ test_assert(item->b.ordinal == ordinal, "ddl_crop not in order") ;
+ } ;
+ } ;
+
+ --n ;
+ } ;
+ printf("\n") ;
+
+ /* ddl_del(base, item, list) -- delete from list
+ *
+ * Cases: (a) first and only (so is also last)
+ * (b) first when more than one
+ * (c) last when more than one
+ * (d) something between
+ */
+ printf(" ddl_del test") ;
+
+ n = base_n + (rand() % rand_n) ;
+ while (n)
+ {
+ ddt_item item ;
+
+ printf(".") ;
+
+ ddt_test_make_lists(&test, n) ;
+
+ item = test.list[a_list].where[n % where_count] ;
+ ddl_del(a_base, item, a.list) ;
+ ddt_test_list_del(item, a_list) ;
+ ddt_verify_lists() ;
+
+ item = test.list[b_list].where[n % where_count] ;
+ ddl_del(b->base, item, b.list) ;
+ ddt_test_list_del(item, b_list) ;
+ ddt_verify_lists() ;
+
+ --n ;
+ } ;
+ printf("\n") ;
+
+ /* ddl_del_head(base, next) -- delete head of list
+ *
+ * Cases: (a) list with more than one item
+ * (b) list with one item
+ * (c) empty list
+ */
+ printf(" ddl_del_head test") ;
+
+ n = base_n + (rand() % rand_n) ;
+ while (n >= 0)
+ {
+ ddt_item item ;
+ ddt_item peek ;
+
+ printf(".") ;
+
+ ddt_test_make_lists(&test, n) ;
+
+ while (1)
+ {
+ item = a_base.head ;
+ peek = (item != NULL) ? item->a.list.next : NULL ;
+
+ ddl_del_head(a_base, a.list) ;
+
+ test_assert(a_base.head == peek, "ddl_del_head broken") ;
+
+ ddt_test_list_del(item, a_list) ;
+ ddt_verify_lists() ;
+
+ if (item == NULL)
+ break ;
+ } ;
+
+ while (1)
+ {
+ item = b->base.head ;
+ peek = (item != NULL) ? item->b.list.next : NULL ;
+
+ ddl_del_head(b->base, b.list) ;
+
+ test_assert(b->base.head == peek, "ddl_del_head broken") ;
+
+ ddt_test_list_del(item, b_list) ;
+ ddt_verify_lists() ;
+
+ if (item == NULL)
+ break ;
+ } ;
+
+ --n ;
+ } ;
+ printf("\n") ;
+
+ /* ddl_del_tail(base, next) -- delete tail of list
+ *
+ * Cases: (a) list with more than one item
+ * (b) list with one item
+ * (c) empty list
+ */
+ printf(" ddl_del_tail test") ;
+
+ n = base_n + (rand() % rand_n) ;
+ while (n >= 0)
+ {
+ ddt_item item ;
+ ddt_item peek ;
+
+ printf(".") ;
+
+ ddt_test_make_lists(&test, n) ;
+
+ while (1)
+ {
+ item = a_base.tail ;
+ peek = (item != NULL) ? item->a.list.prev : NULL ;
+
+ ddl_del_tail(a_base, a.list) ;
+
+ test_assert(a_base.tail == peek, "ddl_del_tail broken") ;
+
+ ddt_test_list_del(item, a_list) ;
+ ddt_verify_lists() ;
+
+ if (item == NULL)
+ break ;
+ } ;
+
+ while (1)
+ {
+ item = b->base.tail ;
+ peek = (item != NULL) ? item->b.list.prev : NULL ;
+
+ ddl_del_tail(b->base, b.list) ;
+
+ test_assert(b->base.tail == peek, "ddl_del_tail broken") ;
+
+ ddt_test_list_del(item, b_list) ;
+ ddt_verify_lists() ;
+
+ if (item == NULL)
+ break ;
+ } ;
+
+ --n ;
+ } ;
+ printf("\n") ;
+
+ /* ddl_head(base) -- return head of list
+ * ddl_tail(base) -- return tail of list
+ *
+ * Cases: (a) list with more than one item
+ * (b) list with one item
+ * (c) empty list
+ */
+ printf(" ddl_head & ddl_tail test") ;
+
+ n = base_n + (rand() % rand_n) ;
+ while (n >= 0)
+ {
+ printf(".") ;
+
+ ddt_test_make_lists(&test, n) ;
+
+ test_assert(ddl_head(a_base) == a_base.head, "ddl_head broken") ;
+ test_assert(ddl_tail(a_base) == a_base.tail, "ddl_head broken") ;
+ test_assert(ddl_head(b->base) == b->base.head, "ddl_head broken") ;
+ test_assert(ddl_tail(b->base) == b->base.tail, "ddl_head broken") ;
+
+ --n ;
+ } ;
+ printf("\n") ;
+
+
+ /* ddl_next(item, next) -- step to next item, if any
+ * ddl_prev(item, next) -- step to prev item, if any
+ *
+ * Cases: (a) at first and only (so is also last)
+ * (b) at first when more than one
+ * (c) at last when more than one
+ * (d) at something between
+ */
+ printf(" ddl_next and ddl_prev test") ;
+
+ n = base_n + (rand() % rand_n) ;
+ while (n)
+ {
+ ddt_item item ;
+ ddt_item where ;
+
+ printf(".") ;
+
+ ddt_test_make_lists(&test, n) ;
+
+ where = test.list[a_list].where[n % where_count] ;
+ item = ddl_next(where, a.list) ;
+ test_assert(item == where->a.list.next, "ddl_next broken") ;
+
+ where = test.list[b_list].where[n % where_count] ;
+ item = ddl_next(where, b.list) ;
+ test_assert(item == where->b.list.next, "ddl_next broken") ;
+
+ where = test.list[a_list].where[n % where_count] ;
+ item = ddl_prev(where, a.list) ;
+ test_assert(item == where->a.list.prev, "ddl_prev broken") ;
+
+ where = test.list[b_list].where[n % where_count] ;
+ item = ddl_prev(where, b.list) ;
+ test_assert(item == where->b.list.prev, "ddl_prev broken") ;
+
+ --n ;
+ } ;
+ printf("\n") ;
+
+
+}
+
+/*
+ * TODO
+ *
+ */
diff --git a/tests/test-privs.c b/tests/test-privs.c
index a888ea0f..568fe79a 100644
--- a/tests/test-privs.c
+++ b/tests/test-privs.c
@@ -125,26 +125,42 @@ main (int argc, char **argv)
#define PRIV_STATE() \
((test_privs.current_state() == ZPRIVS_RAISED) ? "Raised" : "Lowered")
- printf ("%s\n", PRIV_STATE());
+ printf ("Initial state: %s\n", PRIV_STATE());
+
+ test_privs.change(ZPRIVS_RAISE);
+ printf ("Change raise: state: %s\n", PRIV_STATE());
+
test_privs.change(ZPRIVS_RAISE);
+ printf ("Change raise: state: %s\n", PRIV_STATE());
- printf ("%s\n", PRIV_STATE());
test_privs.change(ZPRIVS_LOWER);
+ printf ("Change lower: state: %s\n", PRIV_STATE());
+
+ test_privs.change(ZPRIVS_LOWER);
+ printf ("Change lower: state: %s\n", PRIV_STATE());
- printf ("%s\n", PRIV_STATE());
+ printf ("Get ids %s\n", PRIV_STATE());
zprivs_get_ids (&ids);
/* terminate privileges */
zprivs_terminate(&test_privs);
/* but these should continue to work... */
- printf ("%s\n", PRIV_STATE());
+ printf ("Terminated state: %s\n", PRIV_STATE());
+
+ test_privs.change(ZPRIVS_RAISE);
+ printf ("Change raise: state: %s\n", PRIV_STATE());
+
test_privs.change(ZPRIVS_RAISE);
+ printf ("Change raise: state: %s\n", PRIV_STATE());
- printf ("%s\n", PRIV_STATE());
test_privs.change(ZPRIVS_LOWER);
+ printf ("Change lower: state: %s\n", PRIV_STATE());
+
+ test_privs.change(ZPRIVS_LOWER);
+ printf ("Change lower: state: %s\n", PRIV_STATE());
- printf ("%s\n", PRIV_STATE());
+ printf ("Get ids %s\n", PRIV_STATE());
zprivs_get_ids (&ids);
printf ("terminating\n");
diff --git a/tests/test-sig.c b/tests/test-sig.c
index 63aab6f0..d9eb24f0 100644
--- a/tests/test-sig.c
+++ b/tests/test-sig.c
@@ -2,6 +2,10 @@
#include <sigevent.h>
#include "lib/log.h"
+extern void sighup (void) ;
+extern void sigusr1 (void) ;
+extern void sigusr2 (void) ;
+
void
sighup (void)
{
@@ -20,7 +24,7 @@ sigusr2 (void)
printf ("processed usr2\n");
}
-struct quagga_signal_t sigs[] =
+struct quagga_signal_t sigs[] =
{
{
.signal = SIGHUP,
@@ -44,13 +48,13 @@ main (void)
{
master = thread_master_create ();
signal_init (master, Q_SIGC(sigs), sigs);
-
+
zlog_default = openzlog("testsig", ZLOG_NONE,
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
zlog_set_level (NULL, ZLOG_DEST_STDOUT, LOG_DEBUG);
zlog_set_level (NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
-
+
while (thread_fetch (master, &t))
thread_call (&t);
diff --git a/tests/test-stream.c b/tests/test-stream.c
index 785ce588..e145436f 100644
--- a/tests/test-stream.c
+++ b/tests/test-stream.c
@@ -2,7 +2,7 @@
#include <stream.h>
#include <thread.h>
-static long int ham = 0xdeadbeefdeadbeef;
+static int64_t ham = 0xdeadbeefdeadbeef;
struct thread_master *master;
static void
@@ -11,9 +11,9 @@ print_stream (struct stream *s)
size_t getp = stream_get_getp (s);
printf ("endp: %ld, readable: %ld, writeable: %ld\n",
- stream_get_endp (s),
- STREAM_READABLE (s),
- STREAM_WRITEABLE (s));
+ (long int)stream_get_endp (s),
+ (long int)STREAM_READABLE (s),
+ (long int)STREAM_WRITEABLE (s));
while (STREAM_READABLE (s))
{
@@ -48,7 +48,7 @@ main (void)
printf ("c: 0x%hhx\n", stream_getc (s));
printf ("w: 0x%hx\n", stream_getw (s));
printf ("l: 0x%x\n", stream_getl (s));
- printf ("q: 0x%lx\n", stream_getq (s));
+ printf ("q: 0x%llx\n", (long long unsigned)stream_getq (s));
return 0;
}
diff --git a/tests/test-symtab.c b/tests/test-symtab.c
new file mode 100644
index 00000000..ed83e607
--- /dev/null
+++ b/tests/test-symtab.c
@@ -0,0 +1,344 @@
+#include <zebra.h>
+#include <symtab.h>
+
+/* Symtab torture tests
+ *
+ */
+
+/* prototypes */
+void assert_true(int result, const char * message);
+int main(int argc, char **argv);
+void test_symbol_table_init_new(void);
+void test_symbol_table_lookup(void);
+void call_back_function_set(symbol sym, void* value);
+void call_back_function_change(symbol sym, void* value);
+void call_back_function_unset(symbol sym, void* value);
+void test_call_back(void);
+void test_ref(void);
+void test_ref_heavy(void);
+
+struct thread_master *master;
+
+void
+assert_true(int result, const char * message)
+{
+ if (!result)
+ {
+ printf("Assert failed: %s\n", message);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+
+ test_symbol_table_init_new();
+ test_symbol_table_lookup();
+ test_call_back();
+ test_ref();
+ test_ref_heavy();
+
+ return 0;
+}
+
+void
+test_symbol_table_init_new(void)
+{
+ symbol_table table = NULL;
+ char name[] = "name";
+ char value[] = "value";
+ symbol sym = NULL;
+ symbol sym2 = NULL;
+ void * old_value = NULL;
+
+ printf("test_symbol_table_init_new\n");
+ table = symbol_table_init_new(table, NULL, 0, 0, NULL, NULL);
+ assert_true(table != NULL, "table == NULL");
+
+ /* expect to not find */
+ sym = symbol_lookup(table, name, 0);
+ assert_true(sym == NULL, "sym != NULL");
+
+ /* add */
+ sym = symbol_lookup(table, name, 1);
+ symbol_set_value(sym, value);
+ assert_true(sym != NULL, "sym == NULL");
+ assert_true(strcmp(symbol_get_name(sym), name) == 0, "strcmp(symbol_get_name(sym), name) != 0");
+
+ /* find */
+ sym2 = symbol_lookup(table, name, 0);
+ assert_true(sym == sym2, "sym != sym2");
+ assert_true(symbol_get_value(sym) == value, "symbol_get_value(sym) != value");
+
+ old_value = symbol_delete(sym);
+ assert_true(value == old_value, "value != old_value");
+
+ while ((old_value = symbol_table_ream(table, 1)) != NULL)
+ {
+ }
+
+}
+
+void
+test_symbol_table_lookup(void)
+{
+ symbol_table table = NULL;
+ char buf[20];
+ symbol sym = NULL;
+ int i;
+ char *value = NULL;
+ const int len = 100000;
+ struct symbol_walker itr;
+ vector v = NULL;
+
+ printf("test_symbol_table_lookup\n");
+ table = symbol_table_init_new(table, NULL, 0, 0, NULL, NULL);
+
+ /* add */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d-name", i);
+ sym = symbol_lookup(table, buf, 1);
+ assert_true(sym != NULL, "add: sym == NULL");
+ assert_true(strcmp(symbol_get_name(sym), buf) == 0,
+ "strcmp(symbol_get_name(sym), buf) != 0");
+
+ sprintf(buf, "%d-value", i);
+ value = strdup(buf);
+ symbol_set_value(sym, value);
+ assert_true(symbol_get_value(sym) == value,
+ "symbol_get_value(sym) != value");
+ }
+
+ /* find */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d-name", i);
+ sym = symbol_lookup(table, buf, 0);
+ assert_true(sym != NULL, "find: sym == NULL");
+ assert_true(strcmp(symbol_get_name(sym), buf) == 0,
+ "strcmp(symbol_get_name(sym), buf) != 0");
+
+ sprintf(buf, "%d-value", i);
+ assert_true(strcmp(symbol_get_value(sym), buf) == 0,
+ "strcmp(symbol_get_value(sym), buf) != 0");
+ }
+
+ /* walk with symbol_walker */
+ symbol_walk_start(table, &itr);
+ i = 0;
+ do
+ {
+ sym = symbol_walk_next(&itr);
+ if (sym != NULL) {
+ ++i;
+ }
+ } while (sym != NULL);
+ assert_true(i == len, "i != len");
+
+ /* extract vector */
+ v = symbol_table_extract(table, NULL, NULL, 1, NULL);
+ assert_true(vector_end(v) == (unsigned)len, "vector_get_end(v) != len");
+ vector_free(v);
+
+ while ((value = symbol_table_ream(table, 1)) != NULL)
+ {
+ free(value);
+ }
+}
+
+void
+test_call_back(void)
+{
+ symbol_table table = NULL;
+ char name[] = "name";
+ char value[] = "value";
+ char new_value[] = "new value";
+ symbol sym = NULL;
+
+ printf("test_call_back\n");
+ table = symbol_table_init_new(table, NULL, 0, 0, NULL, NULL);
+ assert_true(table != NULL, "table == NULL");
+
+ /* add */
+ symbol_table_set_value_call_back(table, call_back_function_set);
+ sym = symbol_lookup(table, name, 1);
+ symbol_set_value(sym, value);
+
+ /* change */
+ symbol_table_set_value_call_back(table, call_back_function_change);
+ sym = symbol_lookup(table, name, 1);
+ symbol_set_value(sym, new_value);
+
+ /* delete */
+ symbol_table_set_value_call_back(table, call_back_function_unset);
+ symbol_unset_value(sym);
+
+ while ((symbol_table_ream(table, 1)) != NULL)
+ {
+ }
+}
+
+void call_back_function_set(symbol sym, void* value)
+{
+ assert_true(symbol_get_value(sym) != NULL && value == NULL,
+ "symbol_get_value(sym) == NULL || value != NULL");
+}
+
+void call_back_function_change(symbol sym, void* value)
+{
+ assert_true(symbol_get_value(sym) != NULL && value != NULL,
+ "symbol_get_value(sym) == NULL || value == NULL");
+}
+
+
+void call_back_function_unset(symbol sym, void* value)
+{
+ assert_true(symbol_get_value(sym) == NULL && value != NULL,
+ "symbol_get_value(sym) != NULL || value == NULL");
+}
+
+void
+test_ref(void)
+{
+ symbol_table table = NULL;
+ char name[] = "name";
+ char value[] = "value";
+ symbol sym = NULL;
+ symbol_ref ref = NULL;
+ symbol_ref ref1 = NULL;
+ symbol_ref ref2 = NULL;
+ struct symbol_ref walk;
+ const int num_refs = 2;
+ long int itag = 0;
+
+ printf("test_ref\n");
+ table = symbol_table_init_new(table, NULL, 0, 0, NULL, NULL);
+
+ /* add */
+ sym = symbol_lookup(table, name, 1);
+ symbol_set_value(sym, value);
+
+ /* create references, in reverse order so that walk in order */
+ ref2 = symbol_set_ref(NULL, sym);
+ assert_true(ref2 != NULL, "ref2 == NULL");
+ sym_ref_set_i_tag(ref2, 2);
+ assert_true(sym_ref_i_tag(ref2) == 2, "sym_ref_i_tag(ref2) != 2");
+
+ ref1 = symbol_set_ref(NULL, sym);
+ assert_true(ref1 != NULL, "ref1 == NULL");
+ sym_ref_set_i_tag(ref1, 1);
+ assert_true(sym_ref_i_tag(ref1) == 1, "sym_ref_i_tag(ref1) != 1");
+
+ /* walk references */
+ itag = 1;
+ symbol_ref_walk_start(sym, &walk) ;
+ assert_true(sym->ref_list == &walk, "sym->ref_list != &walk");
+ assert_true(walk.next == ref1, "walk.next != ref1");
+ assert_true(ref1->next == ref2, "ref1->next != ref2");
+ assert_true(ref2->next == NULL, "ref2->next != NULL");
+
+ while ((ref = symbol_ref_walk_step(&walk)) != NULL)
+ {
+ assert_true(sym_ref_i_tag(ref) == itag, "sym_ref_i_tag(ref) != itag");
+ ++itag;
+ }
+ assert_true(itag == num_refs + 1, "itag != num_refs + 1");
+
+ symbol_ref_walk_end(&walk);
+
+ /* clean up */
+ symbol_unset_ref(ref1, 1);
+ symbol_unset_ref(ref2, 1);
+
+ while ((symbol_table_ream(table, 1)) != NULL)
+ {
+ }
+}
+
+void
+test_ref_heavy(void)
+{
+ symbol_table table = NULL;
+ char name[] = "name";
+ char value[] = "value";
+ symbol sym = NULL;
+ symbol_ref ref = NULL;
+ struct symbol_ref walk;
+ const long int num_refs = 100000;
+ long int itag = 0;
+
+ printf("test_ref_heavy\n");
+ table = symbol_table_init_new(table, NULL, 0, 0, NULL, NULL);
+
+ /* add */
+ sym = symbol_lookup(table, name, 1);
+ symbol_set_value(sym, value);
+
+ /* create references, in reverse order so that walk in order */
+ for (itag = num_refs; itag > 0; --itag)
+ {
+ ref = symbol_set_ref(NULL, sym);
+ assert_true(ref != NULL, "ref == NULL");
+ sym_ref_set_i_tag(ref, itag);
+ assert_true(sym_ref_i_tag(ref) == itag, "sym_ref_i_tag(ref) != itag");
+ }
+
+ /* walk references */
+ itag = 1;
+ symbol_ref_walk_start(sym, &walk) ;
+ assert_true(sym->ref_list == &walk, "sym->ref_list != &walk");
+
+ while ((ref = symbol_ref_walk_step(&walk)) != NULL)
+ {
+ assert_true(sym_ref_i_tag(ref) == itag, "sym_ref_i_tag(ref) != itag");
+ ++itag;
+ symbol_unset_ref(ref, 1);
+ }
+ assert_true(itag == num_refs + 1, "itag != num_refs + 1");
+
+ symbol_ref_walk_end(&walk);
+
+ while ((symbol_table_ream(table, 1)) != NULL)
+ {
+ }
+}
+
+
+/*
+ *
+ * TODO
+ *
+
+symbol_table_set_parent
+symbol_table_get_parent
+symbol_hash_string
+symbol_hash_bytes
+symbol_table_set_value_call_back
+symbol_table_free
+symbol_unset_value
+symbol_select_cmp
+symbol_sort_cmp
+symbol_table_extract
+symbol_sort_cmp
+symbol_get_name_len
+symbol_get_table
+symbol_zero_ref
+symbol_dec_ref
+symbol_init_ref
+symbol_set_ref
+symbol_unset_ref
+symbol_unset_ref_free
+symbol_unset_ref_keep
+sym_ref_symbol
+sym_ref_value
+sym_ref_name
+sym_ref_name_len
+sym_ref_parent
+sym_ref_p_tag
+sym_ref_u_tag
+sym_ref_i_tag
+sym_ref_set_parent
+sym_ref_set_p_tag
+sym_ref_set_i_tag
+ */
diff --git a/tests/test-vector.c b/tests/test-vector.c
new file mode 100644
index 00000000..808a7666
--- /dev/null
+++ b/tests/test-vector.c
@@ -0,0 +1,1377 @@
+#include <zebra.h>
+#include <vector.h>
+
+/* Vector torture tests
+ *
+ */
+
+/* prototypes */
+void assert_true(int result, const char * message);
+int main(int argc, char **argv);
+void test_vector_init(void);
+void test_vector_set_index(void);
+void test_vector_lookup(void);
+void test_vector_lookup_ensure(void);
+void test_vector_unset(void);
+void test_vector_set_index_null(void);
+void test_vector_copy(void);
+void test_vector_set(void);
+void test_vector_growth(void);
+
+/* GMCH interface */
+void test_vector_init_new(void);
+void test_vector_set_item(void);
+void test_vector_insert_item(void);
+void test_vector_insert_item_here(void);
+void test_vector_delete_item(void);
+void do_test_insert(const int rider);
+int sort_cmp(const void* const* a, const void* const* b);
+void test_vector_sort(void);
+void test_vector_bsearch(void);
+void test_vector_move_item_here(void);
+void do_test_move_item_here(const int rider, vector_index ins, vector_index src,
+ char strings[][10], const vector_index len) ;
+void test_vector_part_reverse(void);
+void test_vector_copy_here(void);
+void test_vector_move_here(void);
+void test_vector_copy_append(void);
+void test_vector_move_append(void);
+void test_vector_insert(void);
+void test_vector_delete(void);
+void test_vector_discard(void);
+void test_vector_sak(void);
+
+struct thread_master *master;
+
+/* objects to put in the vectors */
+static char s0[5];
+static char s1000[5];
+static char s2000[5];
+
+void
+assert_true(int result, const char * message)
+{
+ if (!result)
+ {
+ printf("Assert failed: %s\n", message);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ strcpy(s0, "0");
+ strcpy(s1000, "1000");
+ strcpy(s2000, "2000");
+
+ test_vector_init();
+ test_vector_set_index();
+ test_vector_lookup();
+ test_vector_lookup_ensure();
+ test_vector_unset();
+ test_vector_set_index_null();
+ test_vector_copy();
+ test_vector_set();
+ test_vector_growth();
+
+ /* GMCH interface */
+ test_vector_init_new();
+ test_vector_set_item();
+ test_vector_insert_item();
+ test_vector_insert_item_here();
+ test_vector_delete_item();
+ test_vector_sort();
+ test_vector_bsearch();
+ test_vector_move_item_here();
+ test_vector_part_reverse();
+ test_vector_copy_here();
+ test_vector_move_here();
+ test_vector_copy_append();
+ test_vector_move_append();
+ test_vector_insert();
+ test_vector_delete();
+ test_vector_discard();
+ test_vector_sak();
+
+ return 0;
+}
+
+void
+test_vector_init(void)
+{
+ vector v = NULL;
+
+ printf("test_vector_init\n");
+ v = vector_init(10);
+
+ assert_true(v != NULL,
+ "v == NULL");
+ assert_true(vector_count(v) == 0,
+ "vector_count != 0");
+ assert_true(vector_active(v) == 0,
+ "vector_active != 0");
+
+ vector_free(v);
+}
+
+void
+test_vector_set_index(void)
+{
+ vector v = NULL;
+
+ printf("test_vector_set_index\n");
+ v = vector_init(0);
+
+ vector_set_index(v, 1000, s1000);
+ assert_true(vector_count(v) == 1,
+ "vector_count != 1");
+ assert_true(vector_active(v) == 1001,
+ "vector_active != 1001");
+ assert_true(vector_slot(v,1000) == s1000,
+ "vector_slot != 1000");
+
+ vector_free(v);
+}
+
+void
+test_vector_lookup(void)
+{
+ vector v = NULL;
+
+ printf("test_vector_lookup\n");
+ v = vector_init(0);
+
+ vector_set_index(v, 1000, s1000);
+
+ assert_true(vector_lookup(v,1000) == s1000,
+ "vector_lookup != 1000");
+ assert_true(vector_lookup(v,1001) == NULL,
+ "vector_lookup != NULL");
+
+ vector_free(v);
+}
+
+void
+test_vector_lookup_ensure(void)
+{
+ vector v = NULL;
+
+ printf("test_vector_lookup_ensure\n");
+ v = vector_init(0);
+
+ vector_set_index(v, 1000, s1000);
+
+ assert_true(vector_lookup_ensure(v,1000) == s1000,
+ "vector_lookup_ensure != 1000");
+ assert_true(vector_lookup_ensure(v,1001) == NULL,
+ "vector_lookup_ensure != NULL");
+
+ vector_free(v);
+}
+
+void
+test_vector_unset(void)
+{
+ vector v = NULL;
+
+ printf("test_vector_unset\n");
+ v = vector_init(0);
+
+ vector_set_index(v, 1000, s1000);
+ vector_set_index(v, 2000, s2000);
+ assert_true(vector_count(v) == 2,
+ "vector_count != 2");
+ assert_true(vector_active(v) == 2001,
+ "vector_active != 2001");
+
+ vector_unset(v, 2000);
+ assert_true(vector_count(v) == 1,
+ "vector_count != 1");
+ assert_true(vector_active(v) == 1001,
+ "vector_active != 1001");
+
+ vector_free(v);
+}
+
+void
+test_vector_set_index_null(void)
+{
+ vector v = NULL;
+
+ printf("test_vector_set_index_null\n");
+ v = vector_init(0);
+
+ vector_set_index(v, 1000, s1000);
+ vector_set_index(v, 2000, s2000);
+ assert_true(vector_count(v) == 2,
+ "vector_count != 2");
+ assert_true(vector_active(v) == 2001,
+ "vector_active != 2001");
+
+ /* storing a NULL is not the same as vector_unset() */
+ vector_set_index(v, 2000, NULL);
+ assert_true(vector_count(v) == 1,
+ "vector_count != 1");
+ assert_true(vector_active(v) == 2001,
+ "vector_active != 2001");
+
+ /* GMCH change in semantics */
+ vector_unset(v, 1000);
+ assert_true(vector_count(v) == 0,
+ "vector_count != 0");
+ assert_true(vector_active(v) == 2001,
+ "vector_active != 2001 ignore post GMCH");
+ assert_true(vector_active(v) == 0,
+ "vector_active != 0 ignore pre GMCH");
+
+ vector_free(v);
+}
+
+void
+test_vector_copy(void)
+{
+ vector v1 = NULL;
+ vector v2 = NULL;
+ int i;
+ const int len = 100;
+ char buf[10];
+
+ printf("test_vector_copy\n");
+
+ /* to help debug objects are strings of their index */
+ v1 = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d", i);
+ vector_set_index(v1, i, strdup(buf));
+ }
+
+ v2 = vector_copy(v1);
+ assert_true(v2 != NULL, "v2 == NULL");
+ assert_true(v1 != v2, "v1 == v2");
+
+ /* check contents are the same */
+ for (i = 0; i < len; ++i)
+ {
+ assert_true(vector_slot(v1, i) == vector_slot(v2, i), "v1 != v2");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_slot(v1, i));
+ }
+
+ vector_free(v1);
+ vector_free(v2);
+}
+
+void
+test_vector_set(void)
+{
+ vector v = NULL;
+ int i;
+ const int len = 1000;
+ char buf[10];
+
+ printf("test_vector_set\n");
+
+ /* to help debug objects are strings of their index */
+ v = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d", i);
+ vector_set_index(v, i, strdup(buf));
+ }
+
+ assert_true(vector_count(v) == (unsigned)len,
+ "vector_count != 1000");
+ assert_true(vector_active(v) == (unsigned)len,
+ "vector_active != 1000");
+
+ vector_set(v, s1000);
+ assert_true(vector_count(v) == len + 1,
+ "vector_count != 1001");
+ assert_true(vector_active(v) == len + 1,
+ "vector_active != 1001");
+ assert_true(vector_slot(v,1000) == s1000,
+ "vector_slot != 1000");
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_growth(void)
+{
+ vector v = NULL;
+ int i;
+ const int len = 150000;
+ char buf[10];
+
+ printf("test_vector_growth\n");
+
+ /* to help debug objects are strings of their index */
+ v = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d", i);
+ vector_set_index(v, i, strdup(buf));
+ }
+
+ assert_true(vector_count(v) == (unsigned)len,
+ "vector_count != len");
+ assert_true(vector_active(v) == (unsigned)len,
+ "vector_active != len");
+
+ /* check contents are correct */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d", i);
+ assert_true(strcmp(vector_slot(v, i), buf) == 0, "vector_slot(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ vector_free(v);
+}
+
+
+/* post GMCH interface */
+
+void
+test_vector_init_new(void)
+{
+ vector v = NULL;
+ void * item = NULL;
+
+ printf("test_vector_init_new\n");
+
+ v = vector_init_new(v, 0);
+ assert_true(v != NULL, "v == NULL");
+ assert_true(vector_is_empty(v), "!vector_is_empty(v)");
+ assert_true(vector_end(v) == 0, "vector_end(v) != 0");
+
+ vector_push_item(v, s0);
+ assert_true(vector_end(v) == 1, "vector_end(v) != 1");
+
+ item = vector_pop_item(v);
+ assert_true(item == s0, "item != s0");
+ assert_true(vector_is_empty(v), "!vector_is_empty(v)");
+ assert_true(vector_end(v) == 0, "vector_end(v) != 0");
+
+ vector_free(v);
+}
+
+void
+test_vector_set_item(void)
+{
+ vector v = NULL;
+ void * item = NULL;
+
+ printf("test_vector_set_item\n");
+
+ v = vector_init_new(v, 0);
+ vector_set_item(v, 0, s0);
+ vector_set_item(v, 1000, s1000);
+ vector_set_item(v, 2000, s2000);
+ assert_true(vector_end(v) == 2001, "vector_end(v) != 2001");
+
+ item = vector_get_item(v, 0);
+ assert_true(item == s0, "item != s0");
+ item = vector_get_item(v, 1000);
+ assert_true(item == s1000, "item != s1000");
+ item = vector_get_item(v, 2000);
+ assert_true(item == s2000, "item != s2000");
+
+ item = vector_get_first_item(v);
+ assert_true(item == s0, "item != s0");
+
+ item = vector_get_last_item(v);
+ assert_true(item == s2000, "item != s2000");
+
+ vector_free(v);
+}
+void
+test_vector_insert_item(void)
+{
+ do_test_insert(2);
+}
+
+void
+test_vector_insert_item_here(void)
+{
+ do_test_insert(-1);
+ do_test_insert(0);
+ do_test_insert(1);
+}
+
+void
+test_vector_delete_item(void)
+{
+ do_test_insert(3);
+}
+
+void
+do_test_insert(const int rider)
+{
+ vector v = NULL;
+ const vector_index len = 100;
+ const vector_index ins = 50;
+ vector_index i;
+ char buf[10];
+ vector_index check_end = len + 1;
+ vector_index check_ins = ins;
+ int check_shift = 1;
+
+ switch(rider)
+ {
+ case -1:
+ printf("test_vector_insert_here before\n");
+ break;
+ case 0:
+ printf("test_vector_insert_here at\n");
+ check_shift = 0;
+ check_end = len;
+ break;
+ case 1:
+ printf("test_vector_insert_here after\n");
+ check_ins++;
+ break;
+ case 2:
+ printf("test_vector_insert\n");
+ break;
+ case 3:
+ printf("test_vector_delete\n");
+ check_shift = -1;
+ check_end = len - 1;
+ break;
+ }
+
+ v = vector_init_new(v, 0);
+
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d", i);
+ vector_set_item(v, i, strdup(buf));
+ }
+
+ switch(rider)
+ {
+ case -1:
+ case 0:
+ case 1:
+ vector_insert_item_here(v, ins, rider, strdup(s1000));
+ break;
+ case 2:
+ vector_insert_item(v, ins, strdup(s1000));
+ break;
+ case 3:
+ free(vector_delete_item(v, ins));
+ break;
+ }
+
+ assert_true(vector_end(v) == check_end, "vector_end(v) != check_end");
+
+ /* check contents are correct */
+ for (i = 0; i < check_ins; ++i)
+ {
+ sprintf(buf, "%d", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ if (rider != 3)
+ {
+ assert_true(strcmp(vector_get_item(v, check_ins), s1000) == 0,
+ "vector_get_item(v, check_ins) != s1000");
+ }
+
+ for (i = check_ins + 1; i < check_end; ++i)
+ {
+ sprintf(buf, "%d", i - check_shift);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0, "vector_get_item(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < vector_end(v); ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_sort(void)
+{
+ vector v = NULL;
+ int i;
+ const int len = 100;
+ char buf[10];
+
+ printf("test_vector_sort\n");
+
+ v = vector_init(0);
+
+ vector_sort(v, sort_cmp); /* null sort */
+
+ /* initialize backwards, using width so that lexical = numerical order */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%9d", i);
+ vector_set_index(v, len - i - 1, strdup(buf));
+ }
+
+ vector_sort(v, sort_cmp);
+
+ /* check contents are correct */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%9d", i);
+ assert_true(strcmp(vector_slot(v, i), buf) == 0, "vector_slot(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ vector_free(v);
+}
+
+int
+sort_cmp(const void* const* a, const void* const* b)
+{
+ return strcmp(*a, *b);
+}
+
+void
+test_vector_bsearch(void)
+{
+ vector v = NULL;
+ int i;
+ const int len = 2000;
+ char buf[20];
+ char target[20];
+ vector_index target_index = 0;
+ int result;
+ vector_index index;
+
+ printf("test_vector_bsearch\n");
+
+ sprintf(target, "%9u", target_index);
+ v = vector_init(0);
+
+ index = vector_bsearch(v, sort_cmp, target, &result); /* null search */
+ assert_true(index == 0, "index != 0");
+ assert_true(result == -1, "result != -1");
+
+ /* initialize, using width so that lexical = numerical order */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%9d", i);
+ vector_set_index(v, i, strdup(buf));
+ }
+
+ for (target_index = 0; target_index < (unsigned)len; ++target_index)
+ {
+ sprintf(target, "%9u", target_index);
+ index = vector_bsearch(v, sort_cmp, target, &result);
+ assert_true(index == target_index, "index != target_index");
+ assert_true(result == 0, "result != 0");
+ assert_true(strcmp(vector_get_item(v, index), target) == 0,
+ "strcmp(vector_get_item(v, index), target)) != 0");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_move_item_here(void)
+{
+ const uint n = 20 ;
+ const uint l = n - 1 ;
+ char strings[n][10] ;
+ uint i ;
+
+ for (i = 0 ; i < n ; ++i)
+ sprintf(strings[i], "item=%2u", i) ;
+
+ do_test_move_item_here(-1, 8, 16, strings, n);
+ do_test_move_item_here( 0, 8, 16, strings, n);
+ do_test_move_item_here(+1, 8, 16, strings, n);
+
+ do_test_move_item_here(-1, 16, 8, strings, n);
+ do_test_move_item_here( 0, 16, 8, strings, n);
+ do_test_move_item_here(+1, 16, 8, strings, n);
+
+ do_test_move_item_here(-1, 9, 9, strings, n);
+ do_test_move_item_here( 0, 9, 9, strings, n);
+ do_test_move_item_here(+1, 9, 9, strings, n);
+
+ do_test_move_item_here(-1, 10, 9, strings, n);
+ do_test_move_item_here( 0, 10, 9, strings, n);
+ do_test_move_item_here(+1, 10, 9, strings, n);
+
+ do_test_move_item_here(-1, 9, 10, strings, n);
+ do_test_move_item_here( 0, 9, 10, strings, n);
+ do_test_move_item_here(+1, 9, 10, strings, n);
+
+ do_test_move_item_here(-1, 11, 9, strings, n);
+ do_test_move_item_here( 0, 11, 9, strings, n);
+ do_test_move_item_here(+1, 11, 9, strings, n);
+
+ do_test_move_item_here(-1, 9, 11, strings, n);
+ do_test_move_item_here( 0, 9, 11, strings, n);
+ do_test_move_item_here(+1, 9, 11, strings, n);
+
+ do_test_move_item_here(-1, 0, 10, strings, n);
+ do_test_move_item_here( 0, 0, 10, strings, n);
+ do_test_move_item_here(+1, 0, 10, strings, n);
+
+ do_test_move_item_here(-1, 10, 0, strings, n);
+ do_test_move_item_here( 0, 10, 0, strings, n);
+ do_test_move_item_here(+1, 10, 0, strings, n);
+
+ do_test_move_item_here(-1, 0, l, strings, n);
+ do_test_move_item_here( 0, 0, l, strings, n);
+ do_test_move_item_here(+1, 0, l, strings, n);
+
+ do_test_move_item_here(-1, l, 0, strings, n);
+ do_test_move_item_here( 0, l, 0, strings, n);
+ do_test_move_item_here(+1, l, 0, strings, n);
+
+ do_test_move_item_here(-1, 10, l, strings, n);
+ do_test_move_item_here( 0, 10, l, strings, n);
+ do_test_move_item_here(+1, 10, l, strings, n);
+
+ do_test_move_item_here(-1, l, 10, strings, n);
+ do_test_move_item_here( 0, l, 10, strings, n);
+ do_test_move_item_here(+1, l, 10, strings, n);
+
+ do_test_move_item_here(-1, 0, 0, strings, n);
+ do_test_move_item_here( 0, 0, 0, strings, n);
+ do_test_move_item_here(+1, 0, 0, strings, n);
+
+ do_test_move_item_here(-1, 1, 1, strings, n);
+ do_test_move_item_here( 0, 1, 1, strings, n);
+ do_test_move_item_here(+1, 1, 1, strings, n);
+
+ do_test_move_item_here(-1, 0, 1, strings, n);
+ do_test_move_item_here( 0, 0, 1, strings, n);
+ do_test_move_item_here(+1, 0, 1, strings, n);
+
+ do_test_move_item_here(-1, 1, 0, strings, n);
+ do_test_move_item_here( 0, 1, 0, strings, n);
+ do_test_move_item_here(+1, 1, 0, strings, n);
+
+ do_test_move_item_here(-1, 0, 2, strings, n);
+ do_test_move_item_here( 0, 0, 2, strings, n);
+ do_test_move_item_here(+1, 0, 2, strings, n);
+
+ do_test_move_item_here(-1, 2, 0, strings, n);
+ do_test_move_item_here( 0, 2, 0, strings, n);
+ do_test_move_item_here(+1, 2, 0, strings, n);
+
+ do_test_move_item_here(-1, l, l, strings, n);
+ do_test_move_item_here( 0, l, l, strings, n);
+ do_test_move_item_here(+1, l, l, strings, n);
+
+ do_test_move_item_here(-1,l-1, l, strings, n);
+ do_test_move_item_here( 0,l-1, l, strings, n);
+ do_test_move_item_here(+1,l-1, l, strings, n);
+
+ do_test_move_item_here(-1, l,l-1, strings, n);
+ do_test_move_item_here( 0, l,l-1, strings, n);
+ do_test_move_item_here(+1, l,l-1, strings, n);
+}
+
+void
+do_test_move_item_here(const int rider, vector_index ins, vector_index src,
+ char strings[][10], const vector_index len)
+{
+ vector v = NULL;
+ vector_index i, e, check_end ;
+ vector_index hi, lo ;
+ char* expect[len] ;
+
+ p_vector_item dest_item = NULL;
+
+ switch(rider)
+ {
+ case -1:
+ printf("test_vector_move_here before dst=%2d, src=%2d\n", src, ins);
+ break;
+
+ case 0:
+ printf("test_vector_move_here at dst=%2d, src=%2d\n", src, ins);
+ --check_end ;
+ break;
+
+ case 1:
+ printf("test_vector_move_here after dst=%2d, src=%2d\n", src, ins);
+ break;
+ } ;
+
+ /* Build the test vector and perform action */
+
+ v = vector_init_new(v, 0);
+
+ for (i = 0; i < len; ++i)
+ vector_set_item(v, i, strdup(strings[i]));
+
+ dest_item = vector_get_item(v, ins); /* item to free if rider == 0 */
+
+ vector_move_item_here(v, ins, rider, src);
+
+ /* Build the expected result. */
+
+ if (ins <= src)
+ {
+ lo = ins ;
+ hi = src ;
+ }
+ else
+ {
+ lo = src ;
+ hi = ins ;
+ } ;
+
+ check_end = (rider != 0) ? len : len - 1 ;
+ i = 0 ;
+ e = 0 ;
+
+ while (i < lo)
+ expect[i++] = strings[e++] ;
+
+ if (lo == hi)
+ {
+ /* Special case -- do nothing if rider != 0
+ * drop entry if rider == 0
+ */
+ if (rider == 0)
+ ++e ;
+ }
+ else if (lo == (hi - 1))
+ {
+ /* Special case -- ins and src next to each other !
+ *
+ * If rider != 0 -- insert ins and src in the required order
+ * If rider == 0 -- insert just src
+ */
+ if (rider < 0)
+ {
+ expect[i++] = strings[src] ;
+ expect[i++] = strings[ins] ;
+ }
+ else if (rider == 0)
+ {
+ expect[i++] = strings[src] ;
+ }
+ else
+ {
+ expect[i++] = strings[ins] ;
+ expect[i++] = strings[src] ;
+ } ;
+ e += 2 ;
+ }
+ else
+ {
+ /* Now we know that ins and src are separated by at least 1 entry.
+ */
+ uint be ;
+
+ be = hi - 1 ;
+
+ if (ins < src)
+ {
+ /* At insertion point, so insert ins and src in the required order
+ * or insert juist the src.
+ */
+ if (rider < 0)
+ {
+ expect[i++] = strings[src] ;
+ expect[i++] = strings[ins] ;
+ ++be ;
+ }
+ else if (rider == 0)
+ {
+ expect[i++] = strings[src] ;
+ }
+ else
+ {
+ expect[i++] = strings[ins] ;
+ expect[i++] = strings[src] ;
+ ++be ;
+ } ;
+
+ ++be ;
+ } ;
+
+ e += 1 ;
+
+ while (i < be)
+ expect[i++] = strings[e++] ;
+
+ if (ins > src)
+ {
+ /* At insertion point, so insert ins and src in the required order
+ * or insert juist the src.
+ */
+ if (rider < 0)
+ {
+ expect[i++] = strings[src] ;
+ expect[i++] = strings[ins] ;
+ }
+ else if (rider == 0)
+ {
+ expect[i++] = strings[src] ;
+ }
+ else
+ {
+ expect[i++] = strings[ins] ;
+ expect[i++] = strings[src] ;
+ } ;
+ } ;
+
+ e = hi + 1 ;
+ } ;
+
+ while (i < check_end)
+ expect[i++] = strings[e++] ;
+
+ /* check contents are correct */
+ assert_true(vector_end(v) == check_end, "vector_end(v) != check_end");
+
+ for (i = 0 ; i < check_end ; ++i)
+ {
+ if (strcmp(vector_get_item(v, i), expect[i]) != 0)
+ {
+ assert_true(0, "vector_get_item(v, i) != expected") ;
+ break ;
+ } ;
+ } ;
+
+ /* free contents */
+ for (i = 0; i < vector_end(v); ++i)
+ free(vector_slot(v, i));
+
+ if (rider == 0)
+ free(dest_item);
+
+ vector_free(v);
+}
+
+void
+test_vector_part_reverse(void)
+{
+ vector v = NULL;
+ const vector_index len = 100;
+ const vector_index rstart = 50;
+ const vector_index rstop = 70;
+ vector_index i;
+ char buf[10];
+
+ printf("test_vector_part_reverse\n");
+
+ v = vector_init_new(v, 0);
+
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_item(v, i, strdup(buf));
+ }
+
+ vector_part_reverse(v, rstart, rstop - rstart);
+ assert_true(vector_end(v) == len, "vector_end(v) != len");
+
+ /* check contents are correct */
+
+ /* before reversed section */
+ for (i = 0; i < rstart - 1; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "before reversed vector_get_item(v, i) != buf");
+ }
+
+ /* reversed section */
+ for (i = rstart; i < rstop; ++i)
+ {
+ sprintf(buf, "%u", rstop - (i - rstart + 1));
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "reversed vector_get_item(v, i) != buf");
+ }
+
+ /* after reversed section */
+ for (i = rstop; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "after reversed vector_get_item(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < vector_end(v); ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_copy_here(void)
+{
+ vector v1 = NULL;
+ vector v2 = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ char buf[10];
+
+ printf("test_vector_copy_here\n");
+
+ /* to help debug objects are strings of their index */
+ v1 = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v1, i, strdup(buf));
+ }
+
+ v2 = vector_copy_here(v2, v1);
+ assert_true(v2 != NULL, "v2 == NULL");
+ assert_true(v1 != v2, "v1 == v2");
+
+ /* check contents are the same */
+ for (i = 0; i < len; ++i)
+ {
+ assert_true(vector_get_item(v1, i) == vector_get_item(v2, i), "v1 != v2");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_get_item(v1, i));
+ }
+
+ vector_free(v1);
+ vector_free(v2);
+}
+
+void
+test_vector_move_here(void)
+{
+ vector v1 = NULL;
+ vector v2 = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ char buf[10];
+
+ printf("test_vector_move_here\n");
+
+ /* to help debug objects are strings of their index */
+ v1 = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v1, i, strdup(buf));
+ }
+
+ v2 = vector_move_here(v2, v1);
+ assert_true(v2 != NULL, "v2 == NULL");
+ assert_true(v1 != v2, "v1 == v2");
+ assert_true(vector_end(v1) == 0, "vector_end(v1) != 0");
+
+ /* check contents are the same */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v2, i), buf) == 0,
+ "vector_get_item(v2, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_get_item(v2, i));
+ }
+
+ vector_free(v1);
+ vector_free(v2);
+}
+
+void
+test_vector_copy_append(void)
+{
+ vector v1 = NULL;
+ vector v2 = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ char buf[10];
+
+ printf("test_vector_copy_append\n");
+
+ /* to help debug objects are strings of their index */
+ v2 = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v2, i, strdup(buf));
+ }
+
+ v1 = vector_init(0);
+ for (i = len; i < 2 * len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v1, i - len, strdup(buf));
+ }
+
+ v2 = vector_copy_append(v2, v1);
+ assert_true(v2 != NULL, "v2 == NULL");
+ assert_true(v1 != v2, "v1 == v2");
+ assert_true(vector_end(v2) == 2 * len, "vector_end(v2) != 2 * len");
+
+ /* check contents */
+ for (i = 0; i < 2 * len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v2, i), buf) == 0,
+ "vector_get_item(v2, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < 2 * len; ++i)
+ {
+ free(vector_get_item(v2, i));
+ }
+
+ vector_free(v1);
+ vector_free(v2);
+}
+
+void
+test_vector_move_append(void)
+{
+ vector v1 = NULL;
+ vector v2 = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ char buf[10];
+
+ printf("test_vector_move_append\n");
+
+ /* to help debug objects are strings of their index */
+ v2 = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v2, i, strdup(buf));
+ }
+
+ v1 = vector_init(0);
+ for (i = len; i < 2 * len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v1, i - len, strdup(buf));
+ }
+
+ v2 = vector_move_append(v2, v1);
+ assert_true(v2 != NULL, "v2 == NULL");
+ assert_true(v1 != v2, "v1 == v2");
+ assert_true(vector_end(v2) == 2 * len, "vector_end(v2) != 2 * len");
+ assert_true(vector_end(v1) == 0, "vector_end(v1) != 0");
+
+ /* check contents */
+ for (i = 0; i < 2 * len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v2, i), buf) == 0,
+ "vector_get_item(v2, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < 2 * len; ++i)
+ {
+ free(vector_get_item(v2, i));
+ }
+
+ vector_free(v1);
+ vector_free(v2);
+}
+
+void
+test_vector_insert(void)
+{
+ vector v = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ const vector_index istart = 50;
+ const vector_index istop = 70;
+ char buf[10];
+
+ printf("test_vector_insert\n");
+
+ /* to help debug objects are strings of their index */
+
+ v = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v, i, strdup(buf));
+ }
+
+ vector_insert(v, istart, istop - istart);
+ assert_true(vector_end(v) == len + (istop - istart),
+ "vector_end(v) != len + (istop - istart)");
+
+ /* check contents */
+ for (i = 0; i < istart; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ for (i = istart + 1; i < istop; ++i)
+ {
+ assert_true(vector_get_item(v, i) == NULL,
+ "vector_get_item(v, i) != NULL");
+ }
+
+ for (i = istop; i < len + (istop - istart); ++i)
+ {
+ sprintf(buf, "%u", i - (istop - istart));
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < len + (istop - istart); ++i)
+ {
+ free(vector_get_item(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_delete(void)
+{
+ vector v = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ const vector_index dstart = 50;
+ const vector_index dstop = 70;
+ char buf[10];
+
+ printf("test_vector_delete\n");
+
+ /* to help debug objects are strings of their index */
+
+ v = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ if (i < dstart || i >= dstop)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v, i, strdup(buf));
+ }
+ else
+ {
+ vector_set_index(v, i, s0);
+ }
+ }
+
+ vector_delete(v, dstart, dstop - dstart);
+ assert_true(vector_end(v) == len - (dstop - dstart),
+ "vector_end(v) != len - (dstop - dstart)");
+
+ /* check contents */
+ for (i = 0; i < dstart; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ for (i = dstart; i < len - (dstop - dstart); ++i)
+ {
+ sprintf(buf, "%u", i + (dstop - dstart));
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < len - (dstop - dstart); ++i)
+ {
+ free(vector_get_item(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_discard(void)
+{
+ vector v = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ const vector_index dstart = 50;
+ char buf[10];
+
+ printf("test_vector_discard\n");
+
+ /* to help debug objects are strings of their index */
+
+ v = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ if (i < dstart)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v, i, strdup(buf));
+ }
+ else
+ {
+ vector_set_index(v, i, s0);
+ }
+ }
+
+ vector_discard(v, dstart);
+ assert_true(vector_end(v) == dstart,
+ "vector_end(v) != dstart");
+
+ /* check contents */
+ for (i = 0; i < dstart; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < dstart; ++i)
+ {
+ free(vector_get_item(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_sak(void)
+{
+ vector v1 = NULL;
+ vector v2 = NULL;
+ vector v3 = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ const vector_index sstart = 60;
+ const vector_index sstop = 70;
+ const vector_index dstart = 40;
+ const vector_index dstop = 50;
+ char buf[10];
+
+ printf("test_vector_sak\n");
+
+ /* to help debug objects are strings of their index */
+
+ v2 = vector_init(0);
+ v3 = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v2, i, strdup(buf));
+ vector_set_index(v3, i, strdup(buf));
+ }
+
+ v1 = vector_sak(1, v1, v2, dstart, dstop - dstart,
+ v3, sstart, sstop - sstart, 0);
+ assert_true(v1 != NULL, "v1 == NULL");
+
+ assert_true(vector_end(v1) == (dstop - dstart),
+ "vector_end(v1) != (dstop - dstart)");
+ assert_true(vector_end(v2) == len,
+ "vector_end(v2) != len");
+ assert_true(vector_end(v3) == len,
+ "vector_end(v3) != len");
+
+ /* check contents v1 */
+ for (i = 0; i < dstop - dstart; ++i)
+ {
+ sprintf(buf, "%u", i + dstart);
+ assert_true(vector_get_item(v1, i) != NULL,
+ "vector_get_item(v1, i) == NULL");
+ assert_true(strcmp(vector_get_item(v1, i), buf) == 0,
+ "vector_get_item(v1, i) != buf");
+ }
+
+ /* check contents v2 */
+ for (i = 0; i < dstart; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v2, i), buf) == 0,
+ "vector_get_item(v2, i) != buf");
+ }
+ for (i = dstart; i < dstop; ++i)
+ {
+ sprintf(buf, "%u", i - dstart + sstart);
+ assert_true(strcmp(vector_get_item(v2, i), buf) == 0,
+ "vector_get_item(v2, i) != buf");
+ }
+ for (i = dstop; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v2, i), buf) == 0,
+ "vector_get_item(v2, i) != buf");
+ }
+
+ /* check contents v3 */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v3, i), buf) == 0,
+ "vector_get_item(v3, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_get_item(v3, i));
+ }
+
+ vector_free(v1);
+ vector_free(v2);
+ vector_free(v3);
+}
+/*
+ * TODO
+ *
+
+vector_re_init
+vector_reset
+vector_ream
+vector_sak
+vector_chop
+vector_decant
+vector_extend_by_1
+
+*/