OpenDNSSEC-enforcer  1.4.1
test_string_util.c
Go to the documentation of this file.
1 /*
2  * $Id: test_string_util.c 3811 2010-08-26 15:05:19Z jakob $
3  *
4  * Copyright (c) 2008-2009 Nominet UK. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
29 /*+
30  * Filename: test_string_util.c
31  *
32  * Description:
33  * This modules holds the unit tests for the functions in string_util.c.
34  * module.
35  *
36  * The test program makes use of the CUnit framework, as described in
37  * http://cunit.sourceforge.net
38 -*/
39 
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <string.h>
43 
44 #include "CUnit/Basic.h"
45 
46 #include "ksm/memory.h"
47 #include "ksm/string_util.h"
48 #include "test_routines.h"
49 
50 
51 
52 
53 /*
54  * TestCompare - Compare Strings
55  * TestCompare - Compare Strings N characters
56  *
57  * Description:
58  * Compares two strings. Unlike strcmp, this can cope with NULL strings,
59  * and considers both equal if both are NULL.
60  *
61  * Although the CU_ASSERT_TRUE of the result could be done here, it
62  * is actually done in the caller so that if a test fails, CUnit will
63  * give some indication of the failing test.
64  *
65  * Arguments:
66  * const char* actual (input)
67  * The string being compared.
68  *
69  * const char* expected (input)
70  * The expected value of the string.
71  *
72  * size_t count (TestCompareN only)
73  * Length of sterings to compare.
74  *
75  * Returns:
76  * int
77  * 1 Strings were identical
78  * 0 Strings were different
79  */
80 
81 static int TestCompareN(const char* actual, const char* expected, size_t count)
82 {
83  int ok; /* Success status */
84 
85  if ((! actual) && (! expected)) {
86  ok = 1;
87  }
88  else if (actual && (! expected)) {
89  ok = 0;
90  }
91  else if ((! actual) && expected) {
92  ok = 0;
93  }
94  else {
95  ok = (memcmp(actual, expected, count) == 0);
96  }
97 
98  return ok;
99 }
100 
101 static int TestCompare(const char* actual, const char* expected)
102 {
103  int ok; /* Success status */
104 
105  if ((! actual) && (! expected)) {
106  ok = 1;
107  }
108  else if (actual && (! expected)) {
109  ok = 0;
110  }
111  else if ((! actual) && expected) {
112  ok = 0;
113  }
114  else {
115  ok = (strcmp(actual, expected) == 0);
116  }
117 
118  return ok;
119 }
120 
121 
122 
123 /*
124  * TestStrXxx - Test Routines
125  *
126  * Description:
127  * A set of routines, each testing one particular string utility routine.
128  * Each utility routine is tested by two routines:
129  *
130  * TestStrXxx Tests utillity routine for one string
131  * TestStrXxxExecute Calls TestStrXxx for a variety of strings.
132  *
133  * Arguments:
134  * Varies.
135  */
136 
137 
138 /* StrStrdup */
139 
140 static void TestStrStrdupExecute(const char* test)
141 {
142  char* testdup = StrStrdup(test);
143  CU_ASSERT_TRUE(TestCompare(testdup, test == NULL ? "" : test));
144  StrFree(testdup);
145 
146  return;
147 }
148 
149 static void TestStrStrdup(void)
150 {
151  TestStrStrdupExecute(NULL);
152  TestStrStrdupExecute("");
153  TestStrStrdupExecute(" ");
154  TestStrStrdupExecute("a test string");
155 
156  return;
157 }
158 
159 /* StrStrncpy */
160 
161 static void TestStrStrncpyExecute(const char* test, const char* expected,
162  size_t destlen)
163 {
164  char* dest = MemMalloc(destlen); /* Create target area */
165  StrStrncpy(dest, test, destlen); /* Copy data */
166  CU_ASSERT_TRUE(TestCompare(dest, expected));/* Compare */
167  MemFree(dest); /* Free up memory */
168 }
169 
170 static void TestStrStrncpy(void)
171 {
172  char dummy[100];
173  static const char* TEST = "A dummy string"; /* Must be < sizeof(dummy) */
174 
175  TestStrStrncpyExecute("alpha", "alpha", 100); /* More than enough space */
176  TestStrStrncpyExecute("beta", "beta", 5); /* Enough space */
177  TestStrStrncpyExecute("gamma", "gamm", 5); /* 1 character too small */
178  TestStrStrncpyExecute("delta", "d", 2); /* Very small */
179  TestStrStrncpyExecute("epsilon", "", 1); /* Minimum possible */
180 
181  /* Finally some tests on what should be no-ops */
182 
183  strcpy(dummy, TEST);
184  StrStrncpy(dummy, NULL, 100);
185  CU_ASSERT_STRING_EQUAL(dummy, "");
186 
187  strcpy(dummy, TEST);
188  StrStrncpy(dummy, "xyz", 0);
189  CU_ASSERT_STRING_EQUAL(dummy, TEST);
190 
191  /*
192  * The final check tests that the routine does not generate a segmentation
193  * fault if the destination is NULL.
194  */
195 
196  StrStrncpy(NULL, "xyz", 52);
197 
198  return;
199 }
200 
201 /* StrStrncat */
202 
203 static void TestStrStrncatExecute(const char* dst, const char* src,
204  size_t dstlen, const char* expected)
205 {
206  char* newdst = NULL;
207 
208  if (dst) {
209  newdst = MemMalloc(dstlen); /* Create target area */
210  StrStrncpy(newdst, dst, dstlen); /* Copy data */
211  }
212  StrStrncat(newdst, src, dstlen);
213  CU_ASSERT_TRUE(TestCompare(newdst, expected));/* Compare */
214 
215  MemFree(newdst); /* Free up memory */
216 }
217 
218 static void TestStrStrncat(void)
219 {
220  TestStrStrncatExecute("alpha", "beta", 100, "alphabeta");
221  TestStrStrncatExecute("alpha", "beta", 6, "alpha");
222  TestStrStrncatExecute("alpha", "beta", 7, "alphab");
223  TestStrStrncatExecute("alpha", "beta", 8, "alphabe");
224  TestStrStrncatExecute("alpha", "beta", 9, "alphabet");
225  TestStrStrncatExecute("alpha", "beta", 10, "alphabeta");
226  TestStrStrncatExecute("alpha", "beta", 11, "alphabeta");
227 
228  TestStrStrncatExecute("alpha ", "beta", 9, "alpha be");
229  TestStrStrncatExecute("alpha ", "beta", 10, "alpha bet");
230  TestStrStrncatExecute("alpha ", "beta", 11, "alpha beta");
231  TestStrStrncatExecute("alpha ", "beta", 12, "alpha beta");
232 
233  TestStrStrncatExecute("", "beta", 1, "");
234  TestStrStrncatExecute("", "beta", 2, "b");
235  TestStrStrncatExecute("", "beta", 3, "be");
236  TestStrStrncatExecute("", "beta", 4, "bet");
237  TestStrStrncatExecute("", "beta", 5, "beta");
238  TestStrStrncatExecute("", "beta", 6, "beta");
239 
240  TestStrStrncatExecute(NULL, "gamma", 6, NULL);
241 
242  return;
243 }
244 
245 /* StrUncomment */
246 
247 static void TestStrUncommentExecute(const char* test, const char* expected)
248 {
249  char* testdup = test ? strdup(test) : NULL;
250 
251  StrUncomment(testdup);
252  CU_ASSERT_TRUE(TestCompare(testdup, expected));
253 
254  free(testdup);
255 
256  return;
257 }
258 
259 static void TestStrUncomment(void)
260 {
261  TestStrUncommentExecute(NULL, NULL);
262  TestStrUncommentExecute("", "");
263  TestStrUncommentExecute(" \t ", " \t ");
264  TestStrUncommentExecute("This is a string with a #comment",
265  "This is a string with a ");
266  TestStrUncommentExecute("This is a string with a # ## comment",
267  "This is a string with a ");
268  TestStrUncommentExecute("#This is a leading comment", "");
269  TestStrUncommentExecute("\t\t#comment", "\t\t");
270  TestStrUncommentExecute("A string with no comment",
271  "A string with no comment");
272 
273  return;
274 }
275 
276 /* StrWhitespace */
277 
278 static void TestStrWhitespaceExecute(const char* test, const char* expected)
279 {
280  char* testdup = test ? strdup(test) : NULL;
281 
282  StrWhitespace(testdup);
283  CU_ASSERT_TRUE(TestCompare(testdup, expected));
284 
285  free(testdup);
286 
287  return;
288 }
289 
290 static void TestStrWhitespace(void)
291 {
292  TestStrWhitespaceExecute(NULL, NULL);
293  TestStrWhitespaceExecute("", "");
294  TestStrWhitespaceExecute(" \t ", " ");
295  TestStrWhitespaceExecute(" \r\n", " ");
296  TestStrWhitespaceExecute("A\tstring\twith\tembedded\ttabs",
297  "A string with embedded tabs");
298  TestStrWhitespaceExecute("no_whitespace", "no_whitespace");
299  TestStrWhitespaceExecute("\r\nwhitespace\t\t", " whitespace ");
300 
301  return;
302 }
303 
304 /* StrTrimR */
305 
306 static void TestStrTrimRExecute(const char* test, const char* expected)
307 {
308  char* testdup = test ? strdup(test) : NULL;
309 
310  StrTrimR(testdup);
311  CU_ASSERT_TRUE(TestCompare(testdup, expected));
312 
313  free(testdup);
314 
315  return;
316 }
317 
318 static void TestStrTrimR(void)
319 {
320  TestStrTrimRExecute(NULL, NULL);
321  TestStrTrimRExecute("", "");
322  TestStrTrimRExecute("\t\tabc", "\t\tabc");
323  TestStrTrimRExecute("abc\t\t", "abc");
324  TestStrTrimRExecute(" alpha ", " alpha");
325  TestStrTrimRExecute(" alpha beta\n", " alpha beta");
326 
327  return;
328 }
329 
330 /* StrTrimL */
331 
332 static void TestStrTrimLExecute(const char* test, const char* expected)
333 {
334  char* testdup = test ? strdup(test) : NULL;
335 
336  char* trimmed = StrTrimL(testdup);
337  CU_ASSERT_TRUE(TestCompare(trimmed, expected));
338 
339  free(testdup);
340 
341  return;
342 }
343 
344 static void TestStrTrimL(void)
345 {
346  TestStrTrimLExecute(NULL, NULL);
347  TestStrTrimLExecute("", "");
348  TestStrTrimLExecute("\t\tabc", "abc");
349  TestStrTrimLExecute("abc\t\t", "abc\t\t");
350  TestStrTrimLExecute(" alpha ", "alpha ");
351  TestStrTrimLExecute(" alpha beta\n", "alpha beta\n");
352 
353  return;
354 }
355 
356 /* StrTrim */
357 
358 static void TestStrTrimExecute(const char* test, const char* expected)
359 {
360  char* testdup = test ? strdup(test) : NULL;
361 
362  char* modstr = StrTrim(testdup);
363  CU_ASSERT_TRUE(TestCompare(modstr, expected));
364 
365  free(testdup);
366 
367  return;
368 }
369 
370 static void TestStrTrim(void)
371 {
372  TestStrTrimExecute(NULL, NULL);
373  TestStrTrimExecute("", "");
374  TestStrTrimExecute("\t\tabc", "abc");
375  TestStrTrimExecute("abc\t\t", "abc");
376  TestStrTrimExecute(" alpha ", "alpha");
377  TestStrTrimExecute(" alpha beta\n", "alpha beta");
378 
379  return;
380 }
381 
382 /* StrToLower */
383 
384 static void TestStrToLowerExecute(const char* test, const char* expected)
385 {
386  char* testdup = test ? strdup(test) : NULL;
387 
388  size_t length = StrToLower(testdup);
389  CU_ASSERT_TRUE(TestCompare(testdup, expected));
390  if (test) {
391  CU_ASSERT_EQUAL(length, strlen(expected));
392  }
393  else {
394  CU_ASSERT_EQUAL(length, 0);
395  }
396 
397  free(testdup);
398 
399  return;
400 }
401 
402 static void TestStrToLower(void)
403 {
404  TestStrToLowerExecute(NULL, NULL);
405  TestStrToLowerExecute("abc", "abc");
406  TestStrToLowerExecute("ABC", "abc");
407  TestStrToLowerExecute("AbC", "abc");
408  TestStrToLowerExecute("AbC d e F", "abc d e f");
409 
410  return;
411 }
412 
413 
414 /* StrToUpper */
415 
416 static void TestStrToUpperExecute(const char* test, const char* expected)
417 {
418  char* testdup = test ? strdup(test) : NULL;
419 
420  size_t length = StrToUpper(testdup);
421  CU_ASSERT_TRUE(TestCompare(testdup, expected));
422  if (test) {
423  CU_ASSERT_EQUAL(length, strlen(expected));
424  }
425  else {
426  CU_ASSERT_EQUAL(length, 0);
427  }
428 
429  free(testdup);
430 
431  return;
432 }
433 
434 static void TestStrToUpper(void)
435 {
436  TestStrToUpperExecute(NULL, NULL);
437  TestStrToUpperExecute("abc", "ABC");
438  TestStrToUpperExecute("ABC", "ABC");
439  TestStrToUpperExecute("AbC", "ABC");
440  TestStrToUpperExecute("AbC d e F", "ABC D E F");
441 
442  return;
443 }
444 
445 
446 /* StrReplaceChar */
447 
448 static void TestStrReplaceCharExecute(const char* test, const char* expected,
449  char search, char replace, int expected_count)
450 {
451  char* testdup = test ? strdup(test) : NULL;
452 
453  int count = StrReplaceChar(testdup, search, replace);
454  CU_ASSERT_TRUE(TestCompare(testdup, expected));
455  CU_ASSERT_EQUAL(count, expected_count);
456 
457  free(testdup);
458 
459  return;
460 }
461 
462 static void TestStrReplaceChar(void)
463 {
464  TestStrReplaceCharExecute(NULL, NULL, 'a', 'b', 0);
465  TestStrReplaceCharExecute("ABCDEF", "ABCDEF", 'a', 'b', 0);
466  TestStrReplaceCharExecute(",abc", "@abc", ',', '@', 1);
467  TestStrReplaceCharExecute("abc,", "abc@", ',', '@', 1);
468  TestStrReplaceCharExecute(",abc,", "@abc@", ',', '@', 2);
469  TestStrReplaceCharExecute("ab,c", "ab@c", ',', '@', 1);
470  TestStrReplaceCharExecute("abacadae", "ebecedee", 'a', 'e', 4);
471 
472  return;
473 }
474 
475 
476 /* StrReplaceCharN */
477 
478 static void TestStrReplaceCharNExecute(const char* test, size_t testlen,
479  const char* expected, char search, char replace, int expected_count)
480 {
481  int count = 0; /* Replacement count */
482  char* testdup = NULL; /* String copy */
483 
484  if (test) {
485  testdup = MemMalloc(testlen + 1);
486  memcpy(testdup, test, testlen);
487  testdup[testlen] = '\0';
488  }
489 
490  count = StrReplaceCharN(testdup, testlen, search, replace);
491  CU_ASSERT_TRUE(TestCompareN(testdup, expected, testlen));
492  CU_ASSERT_EQUAL(count, expected_count);
493  if (testdup) {
494  MemFree(testdup);
495  }
496 
497  return;
498 }
499 
500 static void TestStrReplaceCharN(void)
501 {
502  TestStrReplaceCharNExecute(NULL, 5, NULL, 'a', 'b', 0);
503  TestStrReplaceCharNExecute("ABCDEF", 6, "ABCDEF", 'a', 'b', 0);
504  TestStrReplaceCharNExecute("ABCDEF", 6, "BBCDEF", 'A', 'B', 1);
505  TestStrReplaceCharNExecute("ABC\0EF", 6, "ABCCEF", '\0', 'C', 1);
506  TestStrReplaceCharNExecute("ABC\0EF\0", 7, "ABCCEFC", '\0', 'C', 2);
507  TestStrReplaceCharNExecute("\0", 1, " ", '\0', ' ', 1);
508 
509  return;
510 }
511 
512 
513 /* StrTrimmedLength */
514 
515 static void TestStrTrimmedLengthExecute(const char* test, size_t expected)
516 {
517  CU_ASSERT_EQUAL(StrTrimmedLength(test), expected);
518 
519  return;
520 }
521 
522 static void TestStrTrimmedLength(void)
523 {
524  TestStrTrimmedLengthExecute(NULL, 0);
525  TestStrTrimmedLengthExecute("", 0);
526  TestStrTrimmedLengthExecute(" ", 0);
527  TestStrTrimmedLengthExecute("\n\n\r\t", 0);
528  TestStrTrimmedLengthExecute("abc", 3);
529  TestStrTrimmedLengthExecute(" abc", 3);
530  TestStrTrimmedLengthExecute("defg \n", 4);
531  TestStrTrimmedLengthExecute("\t\tabcdef\t ", 6);
532  TestStrTrimmedLengthExecute(" abcdefg ", 7);
533  TestStrTrimmedLengthExecute(" a b c d e f ", 11);
534  TestStrTrimmedLengthExecute(" a\r\tb", 4);
535  TestStrTrimmedLengthExecute(" xy zzy ", 6);
536 
537  return;
538 }
539 
540 
541 /*
542  * TestStr - Create Test Suite
543  *
544  * Description:
545  * Adds the string test suite to the CUnit test registry
546  * and adds all the tests to it.
547  *
548  * Arguments:
549  * None.
550  *
551  * Returns:
552  * int
553  * Return status. 0 => Success.
554  */
555 
556 int TestStr(void); /* Declaration */
557 int TestStr(void)
558 {
559  struct test_testdef tests[] = {
560  {"StrReplaceCharN", TestStrReplaceCharN},
561  {"StrReplaceChar", TestStrReplaceChar},
562  {"StrStrdup", TestStrStrdup},
563  {"StrStrncpy", TestStrStrncpy},
564  {"StrStrncat", TestStrStrncat},
565  {"StrToLower", TestStrToLower},
566  {"StrToUpper", TestStrToUpper},
567  {"StrTrimL", TestStrTrimL},
568  {"StrTrimR", TestStrTrimR},
569  {"StrTrim", TestStrTrim},
570  {"StrTrimmedLength",TestStrTrimmedLength},
571  {"StrUncomment", TestStrUncomment},
572  {"StrWhitespace", TestStrWhitespace},
573  {NULL, NULL}
574  };
575 
576  return TcuCreateSuite("String Utility", NULL, NULL, tests);
577 }