1 | /* |
---|
2 | * vector test suite. |
---|
3 | * |
---|
4 | * Written by Russ Allbery <rra@stanford.edu> |
---|
5 | * Copyright 2009 Board of Trustees, Leland Stanford Jr. University |
---|
6 | * Copyright (c) 2004, 2005, 2006 |
---|
7 | * by Internet Systems Consortium, Inc. ("ISC") |
---|
8 | * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, |
---|
9 | * 2002, 2003 by The Internet Software Consortium and Rich Salz |
---|
10 | * |
---|
11 | * See LICENSE for licensing terms. |
---|
12 | */ |
---|
13 | |
---|
14 | #include <config.h> |
---|
15 | #include <portable/system.h> |
---|
16 | |
---|
17 | #include <sys/wait.h> |
---|
18 | |
---|
19 | #include <tests/tap/basic.h> |
---|
20 | #include <util/util.h> |
---|
21 | |
---|
22 | |
---|
23 | int |
---|
24 | main(void) |
---|
25 | { |
---|
26 | struct vector *vector; |
---|
27 | struct cvector *cvector; |
---|
28 | const char cstring[] = "This is a\ttest. "; |
---|
29 | const char tabs[] = "test\t\ting\t"; |
---|
30 | static const char nulls1[] = "This\0is\0a\0test."; |
---|
31 | static const char nulls2[] = "This is a\t\0es\0. "; |
---|
32 | char empty[] = ""; |
---|
33 | char buffer[256]; |
---|
34 | char *string; |
---|
35 | char *p; |
---|
36 | pid_t child; |
---|
37 | |
---|
38 | plan(95); |
---|
39 | |
---|
40 | vector = vector_new(); |
---|
41 | ok(vector != NULL, "vector_new returns non-NULL"); |
---|
42 | vector_add(vector, cstring); |
---|
43 | is_int(1, vector->count, "vector_add increases count"); |
---|
44 | ok(vector->strings[0] != cstring, "...and allocated new memory"); |
---|
45 | vector_resize(vector, 4); |
---|
46 | is_int(4, vector->allocated, "vector_resize works"); |
---|
47 | vector_add(vector, cstring); |
---|
48 | vector_add(vector, cstring); |
---|
49 | vector_add(vector, cstring); |
---|
50 | is_int(4, vector->allocated, "...and no reallocation when adding strings"); |
---|
51 | is_int(4, vector->count, "...and the count matches"); |
---|
52 | is_string(cstring, vector->strings[0], "added the right string"); |
---|
53 | is_string(cstring, vector->strings[1], "added the right string"); |
---|
54 | is_string(cstring, vector->strings[2], "added the right string"); |
---|
55 | is_string(cstring, vector->strings[3], "added the right string"); |
---|
56 | ok(vector->strings[1] != vector->strings[2], "each pointer is different"); |
---|
57 | ok(vector->strings[2] != vector->strings[3], "each pointer is different"); |
---|
58 | ok(vector->strings[3] != vector->strings[0], "each pointer is different"); |
---|
59 | ok(vector->strings[0] != cstring, "each pointer is different"); |
---|
60 | vector_clear(vector); |
---|
61 | is_int(0, vector->count, "vector_clear works"); |
---|
62 | is_int(4, vector->allocated, "...but doesn't free the allocation"); |
---|
63 | string = xstrdup(cstring); |
---|
64 | vector_add(vector, cstring); |
---|
65 | vector_add(vector, string); |
---|
66 | is_int(2, vector->count, "added two strings to the vector"); |
---|
67 | ok(vector->strings[1] != string, "...and the pointers are different"); |
---|
68 | vector_resize(vector, 1); |
---|
69 | is_int(1, vector->count, "vector_resize shrinks the vector"); |
---|
70 | ok(vector->strings[0] != cstring, "...and the pointer is different"); |
---|
71 | vector_addn(vector, cstring, 4); |
---|
72 | is_int(2, vector->count, "vector_addn increments count"); |
---|
73 | is_string("This", vector->strings[1], "...and adds the right data"); |
---|
74 | vector_free(vector); |
---|
75 | free(string); |
---|
76 | |
---|
77 | cvector = cvector_new(); |
---|
78 | ok(cvector != NULL, "cvector_new returns non-NULL"); |
---|
79 | cvector_add(cvector, cstring); |
---|
80 | is_int(1, cvector->count, "cvector_add adds a string"); |
---|
81 | ok(cvector->strings[0] == cstring, "...and keeps the same pointer"); |
---|
82 | cvector_resize(cvector, 4); |
---|
83 | is_int(4, cvector->allocated, "cvector_resize works"); |
---|
84 | cvector_add(cvector, cstring); |
---|
85 | cvector_add(cvector, cstring); |
---|
86 | cvector_add(cvector, cstring); |
---|
87 | is_int(4, cvector->allocated, "...and subsequent adds don't resize"); |
---|
88 | is_int(4, cvector->count, "...and the count is right"); |
---|
89 | ok(cvector->strings[1] == cvector->strings[2], "all pointers match"); |
---|
90 | ok(cvector->strings[2] == cvector->strings[3], "all pointers match"); |
---|
91 | ok(cvector->strings[3] == cvector->strings[0], "all pointers match"); |
---|
92 | ok(cvector->strings[0] == cstring, "all pointers match"); |
---|
93 | cvector_clear(cvector); |
---|
94 | is_int(0, cvector->count, "cvector_clear works"); |
---|
95 | is_int(4, cvector->allocated, "...but doesn't free the allocation"); |
---|
96 | string = xstrdup(cstring); |
---|
97 | cvector_add(cvector, cstring); |
---|
98 | cvector_add(cvector, string); |
---|
99 | is_int(2, cvector->count, "added two strings to the vector"); |
---|
100 | ok(cvector->strings[1] == string, "...and the pointers match"); |
---|
101 | cvector_resize(cvector, 1); |
---|
102 | is_int(1, cvector->count, "cvector_resize shrinks the vector"); |
---|
103 | ok(cvector->strings[0] == cstring, "...and the pointers match"); |
---|
104 | cvector_free(cvector); |
---|
105 | free(string); |
---|
106 | |
---|
107 | vector = vector_split_space("This is a\ttest. ", NULL); |
---|
108 | is_int(4, vector->count, "vector_split_space returns right count"); |
---|
109 | is_int(4, vector->allocated, "...and allocation"); |
---|
110 | is_string("This", vector->strings[0], "...first string"); |
---|
111 | is_string("is", vector->strings[1], "...second string"); |
---|
112 | is_string("a", vector->strings[2], "...third string"); |
---|
113 | is_string("test.", vector->strings[3], "...fourth string"); |
---|
114 | vector_add(vector, cstring); |
---|
115 | is_string(cstring, vector->strings[4], "...and can add another"); |
---|
116 | ok(vector->strings[4] != cstring, "allocates a new pointer"); |
---|
117 | is_int(5, vector->allocated, "allocation goes up by one"); |
---|
118 | vector = vector_split(cstring, 't', vector); |
---|
119 | is_int(3, vector->count, "resplitting returns the right count"); |
---|
120 | is_int(5, vector->allocated, "...but doesn't change allocation"); |
---|
121 | is_string("This is a\t", vector->strings[0], "...first string"); |
---|
122 | is_string("es", vector->strings[1], "...second string"); |
---|
123 | is_string(". ", vector->strings[2], "...third string"); |
---|
124 | ok(vector->strings[0] != cstring, "...and allocated new string"); |
---|
125 | p = vector_join(vector, "fe"); |
---|
126 | is_string("This is a\tfeesfe. ", p, "vector_join works"); |
---|
127 | free(p); |
---|
128 | vector_free(vector); |
---|
129 | |
---|
130 | string = xstrdup(cstring); |
---|
131 | cvector = cvector_split_space(string, NULL); |
---|
132 | is_int(4, cvector->count, "cvector_split_space returns right count"); |
---|
133 | is_int(4, cvector->allocated, "...and allocation"); |
---|
134 | is_string("This", cvector->strings[0], "...first string"); |
---|
135 | is_string("is", cvector->strings[1], "...second string"); |
---|
136 | is_string("a", cvector->strings[2], "...third string"); |
---|
137 | is_string("test.", cvector->strings[3], "...fourth string"); |
---|
138 | ok(memcmp(string, nulls1, 16) == 0, "original string modified in place"); |
---|
139 | cvector_add(cvector, cstring); |
---|
140 | ok(cvector->strings[4] == cstring, "cvector_add then works"); |
---|
141 | is_int(5, cvector->allocated, "...and allocation increases by one"); |
---|
142 | free(string); |
---|
143 | string = xstrdup(cstring); |
---|
144 | cvector = cvector_split(string, 't', cvector); |
---|
145 | is_int(3, cvector->count, "cvector_split into same cvector works"); |
---|
146 | is_int(5, cvector->allocated, "...and doesn't lower allocation"); |
---|
147 | is_string("This is a\t", cvector->strings[0], "...first string"); |
---|
148 | is_string("es", cvector->strings[1], "...second string"); |
---|
149 | is_string(". ", cvector->strings[2], "...third string"); |
---|
150 | ok(cvector->strings[0] == string, "no new memory is allocated"); |
---|
151 | ok(memcmp(string, nulls2, 18) == 0, "...and string is modified in place"); |
---|
152 | p = cvector_join(cvector, "oo"); |
---|
153 | is_string("This is a\tooesoo. ", p, "cvector_join works"); |
---|
154 | free(p); |
---|
155 | cvector_free(cvector); |
---|
156 | free(string); |
---|
157 | |
---|
158 | vector = vector_split("", ' ', NULL); |
---|
159 | is_int(1, vector->count, "vector_split on empty string"); |
---|
160 | is_string("", vector->strings[0], "...returns only empty string"); |
---|
161 | vector_free(vector); |
---|
162 | cvector = cvector_split(empty, ' ', NULL); |
---|
163 | is_int(1, cvector->count, "cvector_split on empty string"); |
---|
164 | is_string("", vector->strings[0], "...returns only empty string"); |
---|
165 | cvector_free(cvector); |
---|
166 | |
---|
167 | vector = vector_split_space("", NULL); |
---|
168 | is_int(0, vector->count, "vector_split_space on empty string"); |
---|
169 | vector_free(vector); |
---|
170 | cvector = cvector_split_space(empty, NULL); |
---|
171 | is_int(0, cvector->count, "cvector_split_space on empty string"); |
---|
172 | cvector_free(cvector); |
---|
173 | |
---|
174 | vector = vector_split(tabs, '\t', NULL); |
---|
175 | is_int(4, vector->count, "vector_split on tab string"); |
---|
176 | is_string("test", vector->strings[0], "...first string"); |
---|
177 | is_string("", vector->strings[1], "...second string"); |
---|
178 | is_string("ing", vector->strings[2], "...third string"); |
---|
179 | is_string("", vector->strings[3], "...fourth string"); |
---|
180 | p = vector_join(vector, ""); |
---|
181 | is_string("testing", p, "vector_join with an empty string works"); |
---|
182 | free(p); |
---|
183 | vector_free(vector); |
---|
184 | |
---|
185 | string = xstrdup(tabs); |
---|
186 | cvector = cvector_split(string, '\t', NULL); |
---|
187 | is_int(4, cvector->count, "cvector_split on tab string"); |
---|
188 | is_string("test", cvector->strings[0], "...first string"); |
---|
189 | is_string("", cvector->strings[1], "...second string"); |
---|
190 | is_string("ing", cvector->strings[2], "...third string"); |
---|
191 | is_string("", cvector->strings[3], "...fourth string"); |
---|
192 | p = cvector_join(cvector, ""); |
---|
193 | is_string("testing", p, "cvector_join with an empty string works"); |
---|
194 | free(p); |
---|
195 | cvector_free(cvector); |
---|
196 | free(string); |
---|
197 | |
---|
198 | vector = vector_split_space("foo\nbar", NULL); |
---|
199 | is_int(1, vector->count, "newline is not space for vector_split_space"); |
---|
200 | is_string("foo\nbar", vector->strings[0], "...first string"); |
---|
201 | vector_free(vector); |
---|
202 | |
---|
203 | string = xstrdup("foo\nbar"); |
---|
204 | cvector = cvector_split_space(string, NULL); |
---|
205 | is_int(1, cvector->count, "newline is not space for cvector_split_space"); |
---|
206 | is_string("foo\nbar", cvector->strings[0], "...first string"); |
---|
207 | cvector_free(cvector); |
---|
208 | |
---|
209 | vector = vector_new(); |
---|
210 | vector_add(vector, "/bin/sh"); |
---|
211 | vector_add(vector, "-c"); |
---|
212 | snprintf(buffer, sizeof(buffer), "echo ok %d - vector_exec", testnum++); |
---|
213 | vector_add(vector, buffer); |
---|
214 | child = fork(); |
---|
215 | if (child < 0) |
---|
216 | sysbail("unable to fork"); |
---|
217 | else if (child == 0) |
---|
218 | if (vector_exec("/bin/sh", vector) < 0) |
---|
219 | sysnotice("# unable to exec /bin/sh"); |
---|
220 | waitpid(child, NULL, 0); |
---|
221 | vector_free(vector); |
---|
222 | |
---|
223 | cvector = cvector_new(); |
---|
224 | cvector_add(cvector, "/bin/sh"); |
---|
225 | cvector_add(cvector, "-c"); |
---|
226 | snprintf(buffer, sizeof(buffer), "echo ok %d - cvector_exec", testnum++); |
---|
227 | cvector_add(cvector, buffer); |
---|
228 | child = fork(); |
---|
229 | if (child < 0) |
---|
230 | sysdie("unable to fork"); |
---|
231 | else if (child == 0) |
---|
232 | if (cvector_exec("/bin/sh", cvector) < 0) |
---|
233 | syswarn("unable to exec /bin/sh"); |
---|
234 | waitpid(child, NULL, 0); |
---|
235 | cvector_free(cvector); |
---|
236 | |
---|
237 | return 0; |
---|
238 | } |
---|