Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

t_tc_path.c

Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 2004, 2005 by Kevin L. Mitchell <klmitch@mit.edu>
00003 **
00004 ** This program is free software; you can redistribute it and/or modify
00005 ** it under the terms of the GNU General Public License as published by
00006 ** the Free Software Foundation; either version 2 of the License, or
00007 ** (at your option) any later version.
00008 **
00009 ** This program is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 ** GNU General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU General Public License
00015 ** along with this program; if not, write to the Free Software
00016 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 **
00018 ** @(#)$Id: t_tc_path.c,v 1.5 2005/06/08 04:38:39 klmitch Exp $
00019 */
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 
00031 #include "test-harness.h"
00032 
00033 #include "treeconf_int.h"
00034 
00035 RCSTAG("@(#)$Id: t_tc_path.c,v 1.5 2005/06/08 04:38:39 klmitch Exp $");
00036 
00037 TEST_PROG(t_tc_path, "Test tc_path() function")
00038 TEST_DEP(t_tc_path, t_tc_break)
00039 
00048 struct test {
00049   const char *test;           
00050   const char *path;           
00051   const char *def;            
00052   unsigned int flags;         
00053   unsigned int xret;          
00054   int elem_cnt;               
00055   int elem_loc;               
00056   struct test_elem *elems;    
00057   int subst_cnt;        
00058   treeconf_subst_t *substs;   
00059 };
00060 
00069 struct test_elem {
00070   const char *filename;       
00071   unsigned int test_flags;    
00072   unsigned int ret_val;       
00073 };
00074 
00081 #define TEST_ACCESS     0x0001      /* should access return true for this one? */
00082 
00089 #define TEST_XSEARCHED  0x1000      /* access call expected */
00090 
00097 #define TEST_XCALLED    0x2000      /* callback expected */
00098 
00105 #define TEST_SEARCHED   0x4000      /* did access get called? */
00106 
00113 #define TEST_CALLED     0x8000      /* was callback called? */
00114 
00120 #define TEST_EXPECTED   (TEST_XSEARCHED | TEST_XCALLED)
00121 
00127 #define TEST_ACTUAL     (TEST_SEARCHED | TEST_CALLED)
00128 
00138 #define TEST_ELEM(name, flags, ret) { (name), (flags), (ret) }
00139 
00156 #define TEST_PATH(test, path, default, flags, xret, cnt, elems, s_cnt, subs)  \
00157       { TEST_NAME(test), (path), (default), (flags), (xret), (cnt), 0,      \
00158         (elems), (s_cnt), (subs) }
00159 
00168 #define TEST_ELEMS(elems)     (sizeof(elems) / sizeof(struct test_elem))
00169 
00176 static struct test *curr_test = 0;
00177 
00193 int
00194 access(const char *pathname, int mode)
00195 {
00196   if (!curr_test) /* allow initial tc_path() call test */
00197     return 0;
00198 
00199   /* sanity-check the test... */
00200   if (curr_test->elem_loc >= curr_test->elem_cnt ||
00201       strcmp(pathname, curr_test->elems[curr_test->elem_loc].filename))
00202     FAIL(curr_test->test, FATAL(0), "access() passed unexpected pathname "
00203        "\"%s\"", pathname);
00204 
00205   /* mark searched */
00206   curr_test->elems[curr_test->elem_loc].test_flags |= TEST_SEARCHED;
00207 
00208   /* return what we're supposed to return */
00209   return curr_test->elems[curr_test->elem_loc++].test_flags & TEST_ACCESS ?
00210     0 : -1;
00211 }
00212 
00225 static unsigned int
00226 callback(const char *file, void *data)
00227 {
00228   if (!curr_test) /* allow initial tc_path() call test */
00229     return 0;
00230 
00231   /* sanity-check the test... */
00232   if (!curr_test->elem_loc ||
00233       curr_test->elem_loc > curr_test->elem_cnt ||
00234       strcmp(file, curr_test->elems[curr_test->elem_loc - 1].filename) ||
00235       !(curr_test->elems[curr_test->elem_loc - 1].test_flags & TEST_SEARCHED))
00236     FAIL(curr_test->test, FATAL(0), "callback() passed unexpected pathname "
00237        "\"%s\"", file);
00238 
00239   /* mark called */
00240   curr_test->elems[curr_test->elem_loc - 1].test_flags |= TEST_CALLED;
00241 
00242   /* return what we're supposed to return */
00243   return curr_test->elems[curr_test->elem_loc - 1].ret_val;
00244 }
00245 
00254 static void
00255 do_test(struct test *test)
00256 {
00257   unsigned int err;
00258   int i;
00259 
00260   curr_test = test; /* this is the current test... */
00261 
00262   /* call tc_path... */
00263   err = tc_path(test->path, test->def, test->substs, test->subst_cnt,
00264             test->flags, callback, 0);
00265 
00266   /* correct return value? */
00267   if (err != test->xret) {
00268     FAIL(test->test, 0, "tc_path() call failed with unexpected return %u",
00269        err);
00270     return;
00271   }
00272 
00273   /* OK, check all the elements and make sure they're correct */
00274   for (err = 0, i = 0; i < test->elem_cnt; i++)
00275     if ((((test->elems[i].test_flags & TEST_ACTUAL) >> 2) &
00276        (test->elems[i].test_flags & TEST_EXPECTED)) !=
00277       (test->elems[i].test_flags & TEST_EXPECTED))
00278       fprintf(stderr, "%s:%d:%d: searched/called mismatch for element "
00279             "\"%s\": 0x%04x\n", test->test, i, err++,
00280             test->elems[i].filename, test->elems[i].test_flags);
00281 
00282   /* pass or fail the test */
00283   if (err)
00284     FAIL(test->test, 0, "tc_path() call did not properly process search");
00285   else
00286     PASS(test->test, "tc_path() call properly processed search");
00287 }
00288 
00289 TEST_DECL(t_tc_path, tc_path_basic, "Test that tc_path() works correctly "
00290         "for basic tests")
00297 static struct test_elem basic_elems[] = {
00298   TEST_ELEM("foo", TEST_XSEARCHED, 0),
00299   TEST_ELEM("baz", TEST_XSEARCHED, 0),
00300   TEST_ELEM("bink", TEST_ACCESS | TEST_XCALLED | TEST_XSEARCHED, 0),
00301   TEST_ELEM("bar", TEST_ACCESS, 0)
00302 };
00303 
00304 TEST_DECL(t_tc_path, tc_path_all, "Test that tc_path() with TC_PATH_ALL "
00305         "searches all files")
00312 static struct test_elem all_elems[] = {
00313   TEST_ELEM("foo", TEST_ACCESS | TEST_XCALLED | TEST_XSEARCHED, 0),
00314   TEST_ELEM("baz", TEST_ACCESS | TEST_XCALLED | TEST_XSEARCHED, 0),
00315   TEST_ELEM("bink", TEST_XSEARCHED, 0),
00316   TEST_ELEM("bar", TEST_XSEARCHED, 0)
00317 };
00318 
00325 treeconf_subst_t substs[] = {
00326   TC_SUBST_INIT('a', "foo", 0),
00327   TC_SUBST_INIT('b', "baz", TC_SUBST_INSECURE),
00328   TC_SUBST_INIT('c', "bink", 0),
00329   TC_SUBST_INIT('d', "bar", TC_SUBST_INSECURE)
00330 };
00331 
00338 #define NUM_SUBSTS      (sizeof(substs) / sizeof(treeconf_subst_t))
00339 
00340 TEST_DECL(t_tc_path, tc_path_substs, "Test that tc_path() handles "
00341         "substitutions properly")
00342 
00343 
00349 static struct test_elem subst_elems[] = {
00350   TEST_ELEM("foo", TEST_XSEARCHED, 0),
00351   TEST_ELEM("baz", TEST_XSEARCHED, 0),
00352   TEST_ELEM("bink", TEST_XSEARCHED, 0),
00353   TEST_ELEM("bar", TEST_XSEARCHED, 0)
00354 };
00355 
00356 TEST_DECL(t_tc_path, tc_path_secure, "Test that tc_path() handles "
00357         "security properly")
00364 static struct test_elem secure_elems[] = {
00365   TEST_ELEM("foo", TEST_XSEARCHED, 0),
00366   TEST_ELEM("bink", TEST_XSEARCHED, 0)
00367 };
00368 
00374 static struct test tests[] = {
00375   TEST_PATH(tc_path_basic, "foo::bar", "baz:bink", 0, 0,
00376           TEST_ELEMS(basic_elems), basic_elems, 0, 0),
00377   TEST_PATH(tc_path_all, "foo::bar", "baz:bink", TC_PATH_ALL, 0,
00378           TEST_ELEMS(all_elems), all_elems, 0, 0),
00379   TEST_PATH(tc_path_substs, "%a::%d", "%b:%c", TC_PATH_ALL, 0,
00380           TEST_ELEMS(subst_elems), subst_elems, NUM_SUBSTS, substs),
00381   TEST_PATH(tc_path_secure, "%a::%d", "%b:%c", TC_PATH_SECURE | TC_PATH_ALL, 0,
00382           TEST_ELEMS(secure_elems), secure_elems, NUM_SUBSTS, substs)
00383 };
00384 
00391 #define NUM_TESTS (sizeof(tests) / sizeof(struct test))
00392 
00399 int
00400 main(int argc, char **argv)
00401 {
00402   unsigned int err = 0;
00403   int i;
00404 
00405   TEST(t_tc_path, tc_path_call, "Test that tc_path() may be called",
00406        (!(err = tc_path(0, "foo:bar", 0, 0, 0, callback, 0))), FATAL(0),
00407        ("tc_path() call successful"),
00408        ("tc_path() call failed with error %u", err));
00409 
00410   for (i = 0; i < NUM_TESTS; i++)
00411     do_test(&tests[i]);
00412 
00413   return 0;
00414 }

Generated on Wed Jun 8 09:18:27 2005 for treeconf by  doxygen 1.3.9.1