00001 #include <string.h>
00002 #include <stdlib.h>
00003 #include <stdio.h>
00004 #include <sys/stat.h>
00005 #include <sys/time.h>
00006 #include <sys/types.h>
00007 #include <fcntl.h>
00008 #include <signal.h>
00009 #include <u/libu.h>
00010
00011 int test_suite_misc_register (u_test_t *t);
00012
00013 static int test_u_path_snprintf (u_test_case_t *tc);
00014 static int test_u_strtok (u_test_case_t *tc);
00015 static int test_u_atoi (u_test_case_t *tc);
00016
00017 #ifdef HAVE_SETITIMER
00018 static int test_u_rdwr (u_test_case_t *tc);
00019
00020 struct itimerval itv;
00021 size_t file_size, buf_size;
00022
00023 static void setitv(struct itimerval *pitv)
00024 {
00025 memset(pitv, 0, sizeof(struct itimerval));
00026
00027 pitv->it_value.tv_sec = 0;
00028 pitv->it_value.tv_usec = 1;
00029 }
00030
00031 static void onsigalrm(int s)
00032 {
00033 u_unused_args(s);
00034 setitv(&itv);
00035 con_if(setitimer(ITIMER_REAL, &itv, NULL) < 0);
00036 }
00037
00038 static int cat_file(const char *fn, unsigned int *phash)
00039 {
00040 ssize_t tot = 0, c = 0;
00041 unsigned int hash = 0;
00042 int fd, i;
00043 struct stat st;
00044 char *buf = NULL;
00045
00046 con_err_sif(stat(fn, &st) < 0);
00047
00048 buf = u_malloc(buf_size);
00049 con_err_if(buf == NULL);
00050
00051 memset(buf, 0, buf_size);
00052
00053 fd = open(fn, O_NONBLOCK | O_RDONLY);
00054 con_err_if(fd < 0);
00055
00056 for(tot = 0; ; tot += c)
00057 {
00058 c = u_read(fd, buf, buf_size);
00059
00060 con_err_sif(c < 0);
00061
00062 for(i = 0; i < c; ++i)
00063 hash += buf[i];
00064
00065 dbg_ifb(c == 0)
00066 break;
00067 }
00068
00069 close(fd);
00070
00071 *phash = hash;
00072
00073 con_err_ifm(st.st_size != tot, "file size differs (%d != %d)",
00074 st.st_size, tot);
00075
00076 u_free(buf);
00077
00078 return 0;
00079 err:
00080 if(buf)
00081 u_free(buf);
00082 return 1;
00083 }
00084
00085 static int gen_file(const char *fn, unsigned int *phash)
00086 {
00087 int fd = -1;
00088 char *buf = NULL;
00089 unsigned int hash = 0;
00090 size_t i, c, size = file_size;
00091
00092 buf = u_malloc(buf_size);
00093 con_err_if(buf == NULL);
00094
00095 memset(buf, 0, buf_size);
00096
00097 fd = open(fn, O_CREAT | O_WRONLY | O_NONBLOCK, 0600);
00098 con_err_sif(fd < 0);
00099
00100 while(size)
00101 {
00102 c = (size < buf_size ? size : buf_size);
00103
00104 for(i = 0; i < c; ++i)
00105 buf[i] = (char) i;
00106
00107 con_err_if(u_write(fd, buf, c) < 0);
00108
00109 for(i = 0; i < c; ++i)
00110 hash += buf[i];
00111
00112 size -= c;
00113 }
00114
00115 close(fd);
00116 u_free(buf);
00117
00118 *phash = hash;
00119
00120 return 0;
00121 err:
00122 if(fd >= 0)
00123 close(fd);
00124 if(buf)
00125 u_free(buf);
00126 return ~0;
00127 }
00128
00129 static int tmp_u_rdwr(int rd, const char *fn, unsigned int *phash)
00130 {
00131 int read_rc, write_rc;
00132
00133
00134 signal(SIGALRM, onsigalrm);
00135 setitv(&itv);
00136 con_err_if(setitimer(ITIMER_REAL, &itv, NULL) < 0);
00137
00138 if(rd)
00139 read_rc = cat_file(fn, phash);
00140 else
00141 write_rc = gen_file(fn, phash);
00142
00143
00144 signal(SIGALRM, SIG_IGN);
00145 memset(&itv, 0, sizeof(itv));
00146 setitimer(ITIMER_REAL, &itv, &itv);
00147 signal(SIGALRM, SIG_DFL);
00148
00149 if(rd)
00150 con_err_if(read_rc);
00151 else
00152 con_err_if(write_rc);
00153
00154 return 0;
00155 err:
00156 return ~0;
00157 }
00158
00159 static int test_u_rdwr (u_test_case_t *tc)
00160 {
00161 char fn[U_FILENAME_MAX + 1] = { 0 };
00162 unsigned int hash_read, hash_write;
00163 int i;
00164
00165 buf_size = 1;
00166 file_size = 1013;
00167
00168
00169 for(i = 0; i < 10; ++i)
00170 {
00171
00172 buf_size = (buf_size << 1) + 1;
00173 file_size = (file_size << 1) + 1;
00174
00175 u_test_err_if(tmpnam(fn) == NULL);
00176
00177 u_test_err_if(tmp_u_rdwr(0 , fn, &hash_write));
00178
00179 u_test_err_if(tmp_u_rdwr(1 , fn, &hash_read));
00180
00181 u_test_err_if(hash_read != hash_write);
00182
00183 unlink(fn);
00184 }
00185
00186 return U_TEST_SUCCESS;
00187 err:
00188 u_test_case_printf(tc, "failed. file: %s file_size: %d, buf_size: %d",
00189 fn, file_size, buf_size);
00190 return U_TEST_FAILURE;
00191 }
00192 #endif
00193
00194 static int test_u_strtok (u_test_case_t *tc)
00195 {
00196 char **tv = NULL;
00197 size_t nelems, i, j;
00198 enum { MAX_TOKENS = 100 };
00199
00200 struct vt_s
00201 {
00202 const char *in;
00203 const char *delim;
00204 const char *ex[MAX_TOKENS];
00205 } vt[] = {
00206 {
00207
00208 "this . is , a : test ; string |",
00209 " \t",
00210 {
00211 "this",
00212 ".",
00213 "is",
00214 ",",
00215 "a",
00216 ":",
00217 "test",
00218 ";",
00219 "string",
00220 "|",
00221 NULL
00222 }
00223 },
00224 {
00225
00226 "this . is , a : test ; string |",
00227 ".",
00228 {
00229 "this ",
00230 " is , a : test ; string |",
00231 NULL
00232 }
00233 },
00234 {
00235
00236 "this . is , a : test ; string |",
00237 ",",
00238 {
00239 "this . is ",
00240 " a : test ; string |",
00241 NULL
00242 }
00243 },
00244 {
00245
00246 "this .. is ,, a : test ; string |",
00247 ",.:",
00248 {
00249 "this ",
00250 " is ",
00251 " a ",
00252 " test ; string |",
00253 NULL
00254 }
00255 },
00256 {
00257
00258 "is .. this ,, a : test ; string ||? |",
00259 ",.:;|",
00260 {
00261 "is ",
00262 " this ",
00263 " a ",
00264 " test ",
00265 " string ",
00266 "? ",
00267 NULL
00268 }
00269 },
00270 {
00271
00272 " is .. this ,, a : test ; string ||? |",
00273 " ,.:;|",
00274 {
00275 "is",
00276 "this",
00277 "a",
00278 "test",
00279 "string",
00280 "?",
00281 NULL
00282 }
00283 },
00284 {
00285
00286 " is .. this ,, a : test ; string ||? |",
00287 "-",
00288 {
00289 " is .. this ,, a : test ; string ||? |",
00290 NULL
00291 }
00292 },
00293 {
00294
00295 "|,,, | ,",
00296 "|, ",
00297 { NULL }
00298 },
00299 {
00300
00301 "",
00302 "|, ",
00303 { NULL }
00304 },
00305 {
00306 NULL,
00307 NULL,
00308 { NULL }
00309 }
00310 };
00311
00312 for (i = 0; vt[i].in; i++)
00313 {
00314 u_test_err_ifm (u_strtok(vt[i].in, vt[i].delim, &tv, &nelems),
00315 "u_strtok failed on input: %s", vt[i].in);
00316
00317 for (j = 0; j < nelems; j++)
00318 {
00319 u_test_err_ifm (strcmp(tv[j], vt[i].ex[j]),
00320 "%s != %s (tv idx=%zu)", tv[j], vt[i].ex[j], i);
00321 }
00322
00323 u_test_err_ifm (vt[i].ex[j] != NULL,
00324 "got %zu tokens from u_strtok, need some more (tv idx=%zu)",
00325 nelems, i);
00326
00327 u_strtok_cleanup(tv, nelems);
00328 tv = NULL;
00329 }
00330
00331 return U_TEST_SUCCESS;
00332 err:
00333 u_strtok_cleanup(tv, nelems);
00334 return U_TEST_FAILURE;
00335 }
00336
00337 static int test_u_path_snprintf (u_test_case_t *tc)
00338 {
00339 struct vt_s
00340 {
00341 const char *src, *ex;
00342 } vt[] = {
00343 { "", "" },
00344 { "/", "/" },
00345 { "//", "/" },
00346 { "///", "/" },
00347 { "a", "a" },
00348 { "ab", "ab" },
00349 { "abc", "abc" },
00350 { "a/b", "a/b" },
00351 { "/a", "/a" },
00352 { "//a", "/a" },
00353 { "///a", "/a" },
00354 { "////a", "/a" },
00355 { "/a//", "/a/" },
00356 { "/a///", "/a/" },
00357 { "/a////", "/a/" },
00358 { "a//b", "a/b" },
00359 { "a///b", "a/b" },
00360 { "a////b", "a/b" },
00361 { "a/b//c", "a/b/c" },
00362 { "a/b//c/", "a/b/c/" },
00363 { "a//b//c//", "a/b/c/" },
00364 { NULL, NULL }
00365 };
00366 int i;
00367 char buf[4096];
00368
00369 for(i = 0; vt[i].src; ++i)
00370 {
00371 u_path_snprintf(buf, sizeof(buf), '/', "%s", vt[i].src);
00372 u_test_err_ifm(strcmp(buf, vt[i].ex), "src: %s exp: %s got: %s",
00373 vt[i].src, vt[i].ex, buf);
00374 }
00375
00376 return U_TEST_SUCCESS;
00377 err:
00378 return U_TEST_FAILURE;
00379 }
00380
00381 static int test_u_atoi (u_test_case_t *tc)
00382 {
00383 int i, j, rc, dummy = 0;
00384
00385 struct
00386 {
00387 const char *in;
00388 int ex, rc;
00389 } vt[] = {
00390
00391 { "-32767", -32767, 0 },
00392
00393 { "32767", 32767, 0 },
00394
00395
00396
00397
00398
00399
00400 { "123abc", 123, 0 },
00401 { " +1+1", 1, 0 },
00402 { "abc123", dummy, ~0 },
00403 { "1b2c3", 1, 0 },
00404 { "bongo", dummy, ~0 },
00405
00406
00407 #if (INT_MIN < (-2147483647 - 1))
00408 { "-2147483648", dummy, ~0 },
00409 #elif (INT_MIN == (-2147483647 - 1))
00410 { "-2147483648", -2147483648, 0 },
00411 { "-2147483649", dummy, ~0 },
00412 #else
00413 { "-2147483649", -2147483649, 0 },
00414 #endif
00415
00416
00417 #if (INT_MAX < 2147483647)
00418 { "2147483647", dummy, ~0 },
00419 #elif (INT_MAX == 2147483647)
00420 { "2147483647", 2147483647, 0 },
00421 { "2147483648", dummy, ~0 },
00422 #else
00423 { "2147483648", 2147483648, 0 },
00424 #endif
00425
00426 { NULL, 0, 0 }
00427 };
00428
00429 for (i = 0; vt[i].in; ++i)
00430 {
00431 rc = u_atoi(vt[i].in, &j);
00432
00433 u_test_err_ifm (rc != vt[i].rc,
00434 "unexpected return code %d != %d (tested conversion was: %s)",
00435 rc, vt[i].rc, vt[i].in);
00436
00437 if (rc == 0)
00438 {
00439 u_test_err_ifm (j != vt[i].ex,
00440 "unexpected conversion value %d != %d on %s",
00441 j, vt[i].ex, vt[i].in);
00442 }
00443 }
00444
00445 return U_TEST_SUCCESS;
00446 err:
00447 return U_TEST_FAILURE;
00448 }
00449
00450 int test_suite_misc_register (u_test_t *t)
00451 {
00452 u_test_suite_t *ts = NULL;
00453
00454 con_err_if (u_test_suite_new("Miscellaneous Utilities", &ts));
00455
00456 #ifdef HAVE_SETITIMER
00457 con_err_if (u_test_case_register("Various I/O routines", test_u_rdwr, ts));
00458 #endif
00459
00460 con_err_if (u_test_case_register("u_path_snprintf function",
00461 test_u_path_snprintf, ts));
00462 con_err_if (u_test_case_register("u_strtok function", test_u_strtok, ts));
00463 con_err_if (u_test_case_register("u_atoi function", test_u_atoi, ts));
00464
00465 return u_test_suite_add(ts, t);
00466 err:
00467 u_test_suite_free(ts);
00468 return ~0;
00469 }