1/* 2 * Automated Testing Framework (atf) 3 * 4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <stdio.h> 31#include <stdlib.h> 32#include <string.h> 33 34#include <atf-c.h> 35 36#include "sanity.h" 37#include "test_helpers.h" 38#include "text.h" 39 40/* --------------------------------------------------------------------- 41 * Auxiliary functions. 42 * --------------------------------------------------------------------- */ 43 44#define REQUIRE_ERROR(exp) \ 45 do { \ 46 atf_error_t err = exp; \ 47 ATF_REQUIRE(atf_is_error(err)); \ 48 atf_error_free(err); \ 49 } while (0) 50 51static 52size_t 53array_size(const char *words[]) 54{ 55 size_t count; 56 const char **word; 57 58 count = 0; 59 for (word = words; *word != NULL; word++) 60 count++; 61 62 return count; 63} 64 65static 66void 67check_split(const char *str, const char *delim, const char *words[]) 68{ 69 atf_list_t list; 70 const char **word; 71 size_t i; 72 73 printf("Splitting '%s' with delimiter '%s'\n", str, delim); 74 CE(atf_text_split(str, delim, &list)); 75 76 printf("Expecting %zd words\n", array_size(words)); 77 ATF_CHECK_EQ(atf_list_size(&list), array_size(words)); 78 79 for (word = words, i = 0; *word != NULL; word++, i++) { 80 printf("Word at position %zd should be '%s'\n", i, words[i]); 81 ATF_CHECK_STREQ((const char *)atf_list_index_c(&list, i), words[i]); 82 } 83 84 atf_list_fini(&list); 85} 86 87static 88atf_error_t 89word_acum(const char *word, void *data) 90{ 91 char *acum = data; 92 93 strcat(acum, word); 94 95 return atf_no_error(); 96} 97 98static 99atf_error_t 100word_count(const char *word ATF_DEFS_ATTRIBUTE_UNUSED, void *data) 101{ 102 size_t *counter = data; 103 104 (*counter)++; 105 106 return atf_no_error(); 107} 108 109struct fail_at { 110 int failpos; 111 int curpos; 112}; 113 114static 115atf_error_t 116word_fail_at(const char *word ATF_DEFS_ATTRIBUTE_UNUSED, void *data) 117{ 118 struct fail_at *fa = data; 119 atf_error_t err; 120 121 if (fa->failpos == fa->curpos) 122 err = atf_no_memory_error(); /* Just a random error. */ 123 else { 124 fa->curpos++; 125 err = atf_no_error(); 126 } 127 128 return err; 129} 130 131/* --------------------------------------------------------------------- 132 * Test cases for the free functions. 133 * --------------------------------------------------------------------- */ 134 135ATF_TC(for_each_word); 136ATF_TC_HEAD(for_each_word, tc) 137{ 138 atf_tc_set_md_var(tc, "descr", "Checks the atf_text_for_each_word" 139 "function"); 140} 141ATF_TC_BODY(for_each_word, tc) 142{ 143 size_t cnt; 144 char acum[1024]; 145 146 cnt = 0; 147 strcpy(acum, ""); 148 RE(atf_text_for_each_word("1 2 3", " ", word_count, &cnt)); 149 RE(atf_text_for_each_word("1 2 3", " ", word_acum, acum)); 150 ATF_REQUIRE(cnt == 3); 151 ATF_REQUIRE(strcmp(acum, "123") == 0); 152 153 cnt = 0; 154 strcpy(acum, ""); 155 RE(atf_text_for_each_word("1 2 3", ".", word_count, &cnt)); 156 RE(atf_text_for_each_word("1 2 3", ".", word_acum, acum)); 157 ATF_REQUIRE(cnt == 1); 158 ATF_REQUIRE(strcmp(acum, "1 2 3") == 0); 159 160 cnt = 0; 161 strcpy(acum, ""); 162 RE(atf_text_for_each_word("1 2 3 4 5", " ", word_count, &cnt)); 163 RE(atf_text_for_each_word("1 2 3 4 5", " ", word_acum, acum)); 164 ATF_REQUIRE(cnt == 5); 165 ATF_REQUIRE(strcmp(acum, "12345") == 0); 166 167 cnt = 0; 168 strcpy(acum, ""); 169 RE(atf_text_for_each_word("1 2.3.4 5", " .", word_count, &cnt)); 170 RE(atf_text_for_each_word("1 2.3.4 5", " .", word_acum, acum)); 171 ATF_REQUIRE(cnt == 5); 172 ATF_REQUIRE(strcmp(acum, "12345") == 0); 173 174 { 175 struct fail_at fa; 176 fa.failpos = 3; 177 fa.curpos = 0; 178 atf_error_t err = atf_text_for_each_word("a b c d e", " ", 179 word_fail_at, &fa); 180 ATF_REQUIRE(atf_is_error(err)); 181 ATF_REQUIRE(atf_error_is(err, "no_memory")); 182 ATF_REQUIRE(fa.curpos == 3); 183 atf_error_free(err); 184 } 185} 186 187ATF_TC(format); 188ATF_TC_HEAD(format, tc) 189{ 190 atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form " 191 "strings using a variable parameters list"); 192} 193ATF_TC_BODY(format, tc) 194{ 195 char *str; 196 atf_error_t err; 197 198 err = atf_text_format(&str, "%s %s %d", "Test", "string", 1); 199 ATF_REQUIRE(!atf_is_error(err)); 200 ATF_REQUIRE(strcmp(str, "Test string 1") == 0); 201 free(str); 202} 203 204static 205void 206format_ap(char **dest, const char *fmt, ...) 207{ 208 va_list ap; 209 atf_error_t err; 210 211 va_start(ap, fmt); 212 err = atf_text_format_ap(dest, fmt, ap); 213 va_end(ap); 214 215 ATF_REQUIRE(!atf_is_error(err)); 216} 217 218ATF_TC(format_ap); 219ATF_TC_HEAD(format_ap, tc) 220{ 221 atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form " 222 "strings using a va_list argument"); 223} 224ATF_TC_BODY(format_ap, tc) 225{ 226 char *str; 227 228 format_ap(&str, "%s %s %d", "Test", "string", 1); 229 ATF_REQUIRE(strcmp(str, "Test string 1") == 0); 230 free(str); 231} 232 233ATF_TC(split); 234ATF_TC_HEAD(split, tc) 235{ 236 atf_tc_set_md_var(tc, "descr", "Checks the split function"); 237} 238ATF_TC_BODY(split, tc) 239{ 240 { 241 const char *words[] = { NULL }; 242 check_split("", " ", words); 243 } 244 245 { 246 const char *words[] = { NULL }; 247 check_split(" ", " ", words); 248 } 249 250 { 251 const char *words[] = { NULL }; 252 check_split(" ", " ", words); 253 } 254 255 { 256 const char *words[] = { "a", "b", NULL }; 257 check_split("a b", " ", words); 258 } 259 260 { 261 const char *words[] = { "a", "b", "c", "d", NULL }; 262 check_split("a b c d", " ", words); 263 } 264 265 { 266 const char *words[] = { "foo", "bar", NULL }; 267 check_split("foo bar", " ", words); 268 } 269 270 { 271 const char *words[] = { "foo", "bar", "baz", "foobar", NULL }; 272 check_split("foo bar baz foobar", " ", words); 273 } 274 275 { 276 const char *words[] = { "foo", "bar", NULL }; 277 check_split(" foo bar", " ", words); 278 } 279 280 { 281 const char *words[] = { "foo", "bar", NULL }; 282 check_split("foo bar", " ", words); 283 } 284 285 { 286 const char *words[] = { "foo", "bar", NULL }; 287 check_split("foo bar ", " ", words); 288 } 289 290 { 291 const char *words[] = { "foo", "bar", NULL }; 292 check_split(" foo bar ", " ", words); 293 } 294} 295 296ATF_TC(split_delims); 297ATF_TC_HEAD(split_delims, tc) 298{ 299 atf_tc_set_md_var(tc, "descr", "Checks the split function using " 300 "different delimiters"); 301} 302ATF_TC_BODY(split_delims, tc) 303{ 304 305 { 306 const char *words[] = { NULL }; 307 check_split("", "/", words); 308 } 309 310 { 311 const char *words[] = { " ", NULL }; 312 check_split(" ", "/", words); 313 } 314 315 { 316 const char *words[] = { " ", NULL }; 317 check_split(" ", "/", words); 318 } 319 320 { 321 const char *words[] = { "a", "b", NULL }; 322 check_split("a/b", "/", words); 323 } 324 325 { 326 const char *words[] = { "a", "bcd", "ef", NULL }; 327 check_split("aLONGDELIMbcdLONGDELIMef", "LONGDELIM", words); 328 } 329} 330 331ATF_TC(to_bool); 332ATF_TC_HEAD(to_bool, tc) 333{ 334 atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_bool function"); 335} 336ATF_TC_BODY(to_bool, tc) 337{ 338 bool b; 339 340 RE(atf_text_to_bool("true", &b)); ATF_REQUIRE(b); 341 RE(atf_text_to_bool("TRUE", &b)); ATF_REQUIRE(b); 342 RE(atf_text_to_bool("yes", &b)); ATF_REQUIRE(b); 343 RE(atf_text_to_bool("YES", &b)); ATF_REQUIRE(b); 344 345 RE(atf_text_to_bool("false", &b)); ATF_REQUIRE(!b); 346 RE(atf_text_to_bool("FALSE", &b)); ATF_REQUIRE(!b); 347 RE(atf_text_to_bool("no", &b)); ATF_REQUIRE(!b); 348 RE(atf_text_to_bool("NO", &b)); ATF_REQUIRE(!b); 349 350 b = false; 351 REQUIRE_ERROR(atf_text_to_bool("", &b)); 352 ATF_REQUIRE(!b); 353 b = true; 354 REQUIRE_ERROR(atf_text_to_bool("", &b)); 355 ATF_REQUIRE(b); 356 357 b = false; 358 REQUIRE_ERROR(atf_text_to_bool("tru", &b)); 359 ATF_REQUIRE(!b); 360 b = true; 361 REQUIRE_ERROR(atf_text_to_bool("tru", &b)); 362 ATF_REQUIRE(b); 363 364 b = false; 365 REQUIRE_ERROR(atf_text_to_bool("true2", &b)); 366 ATF_REQUIRE(!b); 367 b = true; 368 REQUIRE_ERROR(atf_text_to_bool("true2", &b)); 369 ATF_REQUIRE(b); 370 371 b = false; 372 REQUIRE_ERROR(atf_text_to_bool("fals", &b)); 373 ATF_REQUIRE(!b); 374 b = true; 375 REQUIRE_ERROR(atf_text_to_bool("fals", &b)); 376 ATF_REQUIRE(b); 377 378 b = false; 379 REQUIRE_ERROR(atf_text_to_bool("false2", &b)); 380 ATF_REQUIRE(!b); 381 b = true; 382 REQUIRE_ERROR(atf_text_to_bool("false2", &b)); 383 ATF_REQUIRE(b); 384} 385 386ATF_TC(to_long); 387ATF_TC_HEAD(to_long, tc) 388{ 389 atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_long function"); 390} 391ATF_TC_BODY(to_long, tc) 392{ 393 long l; 394 395 RE(atf_text_to_long("0", &l)); ATF_REQUIRE_EQ(l, 0); 396 RE(atf_text_to_long("-5", &l)); ATF_REQUIRE_EQ(l, -5); 397 RE(atf_text_to_long("5", &l)); ATF_REQUIRE_EQ(l, 5); 398 RE(atf_text_to_long("123456789", &l)); ATF_REQUIRE_EQ(l, 123456789); 399 400 l = 1212; 401 REQUIRE_ERROR(atf_text_to_long("", &l)); 402 ATF_REQUIRE_EQ(l, 1212); 403 REQUIRE_ERROR(atf_text_to_long("foo", &l)); 404 ATF_REQUIRE_EQ(l, 1212); 405 REQUIRE_ERROR(atf_text_to_long("1234x", &l)); 406 ATF_REQUIRE_EQ(l, 1212); 407} 408 409/* --------------------------------------------------------------------- 410 * Main. 411 * --------------------------------------------------------------------- */ 412 413ATF_TP_ADD_TCS(tp) 414{ 415 ATF_TP_ADD_TC(tp, for_each_word); 416 ATF_TP_ADD_TC(tp, format); 417 ATF_TP_ADD_TC(tp, format_ap); 418 ATF_TP_ADD_TC(tp, split); 419 ATF_TP_ADD_TC(tp, split_delims); 420 ATF_TP_ADD_TC(tp, to_bool); 421 ATF_TP_ADD_TC(tp, to_long); 422 423 return atf_no_error(); 424} 425