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

t_treeconf.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_treeconf.c,v 1.7 2005/06/08 04:38:39 klmitch Exp $
00019 */
00027 #include "test-harness.h"
00028 
00029 #include <errno.h>
00030 #include <string.h>
00031 
00032 #include "treeconf_int.h"
00033 
00034 RCSTAG("@(#)$Id: t_treeconf.c,v 1.7 2005/06/08 04:38:39 klmitch Exp $");
00035 
00036 TEST_PROG(t_treeconf, "Test treeconf function suite")
00037 TEST_DEP(t_treeconf, t_tc_break)
00038 
00045 static int change;
00046 
00056 static void
00057 t_change(treeconf_ctx_t *ctx, treeconf_node_t *node)
00058 {
00059   change++;
00060   return;
00061 }
00062 
00080 static int
00081 nodown_false(treeconf_ctx_t *ctx, treeconf_node_t *parent,
00082            treeconf_str_t *name, int elements)
00083 {
00084   return 0;
00085 }
00086 
00104 static int
00105 nodown_true(treeconf_ctx_t *ctx, treeconf_node_t *parent,
00106           treeconf_str_t *name, int elements)
00107 {
00108   return 1;
00109 }
00110 
00117 int
00118 main(int argc, char **argv)
00119 {
00120   treeconf_ctx_t ctx = TREECONF_CTX_INIT;
00121   treeconf_node_t *node = 0, *node2 = 0;
00122   const char *value;
00123   unsigned int err = 0;
00124 
00125   /***************************************************************************/
00126   /* Test simple tc_register cases                                           */
00127   /***************************************************************************/
00128 
00129   /* Create tree node "foo"--checks creation of tree nodes */
00130   TEST(t_treeconf, tc_register_treenode,
00131        "Test creation of tree nodes by tc_register()",
00132        (!(err = tc_register(&ctx, "foo", 0, 0, 0, 0, 0)) &&
00133       (tn_type(tx_config(&ctx)) & TC_NODETYPE_MASK) == TC_NODETYPE_NODE),
00134        FATAL(0),
00135        ("tc_register() successfully created tree node \"foo\""),
00136        ("tc_register() call failed with error %u", err));
00137 
00138   /* Create variable node "foo.bar" with default "bar"--checks creation
00139    * of variable nodes
00140    */
00141   TEST(t_treeconf, tc_register_varnode,
00142        "Test creation of variable nodes by tc_register()",
00143        (!(err = tc_register(&ctx, "foo.bar", "bar", 0, 0, 0, 0))), FATAL(0),
00144        ("tc_register() successfully created variable node \"foo.bar\""),
00145        ("tc_register() call failed with error %u", err));
00146 
00147   /* Create tree node "foo.baz.bink"--checks creation of a tree node with
00148    * implicit nodes
00149    */
00150   TEST(t_treeconf, tc_register_impltree,
00151        "Test creation of implicit tree nodes for tree nodes by tc_register()",
00152        (!(err = tc_register(&ctx, "foo.baz.bink", 0, 0, 0, 0, 0))), FATAL(0),
00153        ("tc_register() successfully created tree node \"foo.baz.bink\""),
00154        ("tc_register() call failed with error %u", err));
00155 
00156   /* Create variable node "foo.bink.foo" with default "baz" and a change
00157    * callback--checks creation of a variable node with implicit nodes
00158    */
00159   TEST(t_treeconf, tc_register_implvar,
00160        "Test creation of implicit tree nodes for var nodes by tc_register()",
00161        (!(err = tc_register(&ctx, "foo.bink.foo", "baz", 0, 0, t_change, 0))),
00162        FATAL(0),
00163        ("tc_register() successfully created variable node \"foo.bink.foo\""),
00164        ("tc_register() call failed with error %u", err));
00165 
00166   /* Attempt creation of "foo.baz" variable node with default "blah"--checks
00167    * rejection of variable nodes replacing implicit tree nodes
00168    */
00169   TEST(t_treeconf, tc_register_replimpl,
00170        "Test tc_register() rejects replacement of implicit tree nodes",
00171        ((err = tc_register(&ctx, "foo.baz", "blah", 0, 0, 0, 0)) ==
00172       TC_ERR_MULTREG), 0,
00173        ("tc_register() rejected replacement of implicit tree node with a "
00174       "variable node"),
00175        ("tc_register() did not reject variable node replacement and returned "
00176       "error code %u", err));
00177 
00178   /***************************************************************************/
00179   /* Test simple tc_find cases                                               */
00180   /***************************************************************************/
00181 
00182   /* Attempt lookup of node "foo" */
00183   TEST(t_treeconf, tc_find_node,
00184        "Test tc_find() can find desired existing node",
00185        (!(err = tc_find(&ctx, "foo", &node, 0)) && node), FATAL(0),
00186        ("tc_find() successfully located variable node \"foo\""),
00187        ("tc_find() failed to locate existing variable node \"foo\" and "
00188       "returned error code %u", err));
00189 
00190   /* Attempt lookup of non-existant node "root"; should return ENOENT. */
00191   TEST(t_treeconf, tc_find_none_root,
00192        "Test that tc_find() fails to find non-existant root nodes",
00193        ((err = tc_find(&ctx, "root", &node2, 0)) == ENOENT), FATAL(0),
00194        ("tc_find() correctly returned failure when looking up \"root\""),
00195        ("tc_find() returned unexpected error code %u looking up non-existant "
00196       "node \"root\"", err));
00197 
00198   /* Attempt lookup of non-existant node "foo.none.here"; should return
00199    * ENOENT.
00200    */
00201   TEST(t_treeconf, tc_find_none_leaf,
00202        "Test that tc_find() fails to find non-existant leaf nodes",
00203        ((err = tc_find(&ctx, "foo.none.here", &node2, 0)) == ENOENT), FATAL(0),
00204        ("tc_find() correctly returned failure when looking up "
00205       "\"foo.none.here\""),
00206        ("tc_find() returned unexpected error code %u looking up non-existant "
00207       "node \"foo.none.here\"", err));
00208 
00209   /* Test that nodown returning false results in ENOENT */
00210   tn_nodown(node) = nodown_false;
00211   TEST(t_treeconf, tc_find_nodown_false,
00212        "Test that tc_find() will not create implicit nodes when nodown "
00213        "returns false",
00214        ((err = tc_find(&ctx, "foo.nodown.here", &node2, 0)) == ENOENT),
00215        FATAL(0),
00216        ("tc_find() correctly returned failure looking up \"foo.nodown.here\" "
00217       "when nodown callback returned false"),
00218        ("tc_find() returned unexpected error code %u looking up non-existant "
00219       "node \"foo.nodown.here\" with nodown returning false", err));
00220 
00221   /* Test that nodown returning true results in implicit node creation */
00222   tn_nodown(node) = nodown_true;
00223   TEST(t_treeconf, tc_find_nodown_true,
00224        "Test that tc_find() will create implicit nodes when nodown returns "
00225        "true",
00226        (!(err = tc_find(&ctx, "foo.nodown.here", &node2, 0)) &&
00227       (tn_type(node2) & TC_NODETYPE_IMPLICIT)), FATAL(0),
00228        ("tc_find() successfully created implicit node \"foo.nodown.here\" "
00229       "when nodown callback returned true"),
00230        ("tc_find() returned unexpected error code %u looking up non-existant "
00231       "node \"foo.nodown.here\" with nodown returning true", err));
00232 
00233   /***************************************************************************/
00234   /* Test complex tc_register cases                                          */
00235   /***************************************************************************/
00236 
00237   /* Test that relative registration works */
00238   TEST(t_treeconf, tc_register_relative,
00239        "Test creation of nodes relative to a given node",
00240        (!(err = tc_register(&ctx, "qux", "aye", node, 0, 0, 0))), FATAL(0),
00241        ("tc_register() successfully created node \"qux\" relative to parent "
00242       "node \"foo\""),
00243        ("tc_register() failed to create node \"qux\" relative to parent node "
00244       "\"foo\" and returned error code %u", err));
00245 
00246   /* Test that implicit nodes can be overridden */
00247   TEST(t_treeconf, tc_register_override,
00248        "Test that an implicit node can be overridden by an explicit node",
00249        (!(err = tc_register(&ctx, "foo.nodown", "blah", 0, 0, 0, 0)) &&
00250       !(err = tc_find(&ctx, "foo.nodown", &node2, 0)) &&
00251       !(tn_type(node2) & TC_NODETYPE_IMPLICIT) &&
00252       (err = tc_find(&ctx, "foo.nodown.here", &node2, 0)) == ENOENT),
00253        FATAL(0),
00254        ("tc_register() override of implicit node successful"),
00255        ("tc_register() failed, tc_find() failed, node created as implicit, "
00256       "or subnode still exists; error code %u", err));
00257 
00258   /***************************************************************************/
00259   /* Test tc_get                                                             */
00260   /***************************************************************************/
00261 
00262   /* Test that tc_get() won't return non-existant variables */
00263   TEST(t_treeconf, tc_get_noent,
00264        "Test that tc_get() doesn't retrieve non-existant nodes",
00265        ((err = tc_get(&ctx, "bar", 0, 0)) == ENOENT), 0,
00266        ("tc_get() properly failed to retrieve non-existant variable"),
00267        ("tc_get() failed in retrieving non-existant variable with unexpected "
00268       "error code %u", err));
00269 
00270   /* Test that tc_get() won't try to return a value from a tree node */
00271   TEST(t_treeconf, tc_get_mismatch,
00272        "Test that tc_get() will not retrieve a tree node's value",
00273        ((err = tc_get(&ctx, "foo", 0, 0)) == TC_ERR_MISMATCH), 0,
00274        ("tc_get() properly failed to retrieve tree node as variable"),
00275        ("tc_get() failed in retrieving tree node as variable with unexpected "
00276       "error code %u", err));
00277 
00278   /* Test that tc_get() returns the correct value */
00279   TEST(t_treeconf, tc_get_variable,
00280        "Test that tc_get() will properly retrieve a variable's value",
00281        (!(err = tc_get(&ctx, "foo.bar", &value, 0)) &&
00282       !strcmp(value, "bar")), 0,
00283        ("tc_get() properly retrieved value of \"foo.bar\""),
00284        ("tc_get() failed to retrieve correct value of \"foo.bar\"; error code "
00285       "%u", err));
00286 
00287   /***************************************************************************/
00288   /* Test tc_set                                                             */
00289   /***************************************************************************/
00290 
00291   /* Test tc_set() on a basic variable */
00292   TEST(t_treeconf, tc_set_basic,
00293        "Test that tc_set() will set a simple variable",
00294        (!(err = tc_set(&ctx, "foo.bar", "rab", 0)) &&
00295       !(err = tc_get(&ctx, "foo.bar", &value, 0)) &&
00296       !strcmp(value, "rab")), FATAL(0),
00297        ("tc_set() set \"foo.bar\" to \"rab\""),
00298        ("tc_set() failed to set \"foo.bar\" to \"rab\"; error code %u", err));
00299 
00300   /* Test tc_set() rejects non-existant node "root"; should return ENOENT. */
00301   TEST(t_treeconf, tc_set_none_root,
00302        "Test that tc_set() fails to set non-existant root nodes",
00303        ((err = tc_set(&ctx, "root", "blah", 0)) == ENOENT), FATAL(0),
00304        ("tc_set() correctly returned failure when setting \"root\""),
00305        ("tc_set() returned unexpected error code %u setting non-existant node "
00306       "\"root\"", err));
00307 
00308   /* Test tc_set() rejects non-existant leaf node "foo.none.here" when nodown
00309    * not set; should return ENOENT.
00310    */
00311   tn_nodown(node) = 0;
00312   TEST(t_treeconf, tc_set_none_nodown_unset,
00313        "Test that tc_set() fails to set non-existant leaf nodes with no "
00314        "nodown set",
00315        ((err = tc_set(&ctx, "foo.none.here", "blah", 0)) == ENOENT), FATAL(0),
00316        ("tc_set() correctly returned failure when setting \"foo.none.here\""),
00317        ("tc_set() returned unexpected error code %u setting non-existant node "
00318       "\"foo.none.here\"", err));
00319 
00320   /* Test tc_set() rejects non-existant leaf node "foo.none.here" when nodown
00321    * returns false; should return ENOENT.
00322    */
00323   tn_nodown(node) = nodown_false;
00324   TEST(t_treeconf, tc_set_none_nodown_false,
00325        "Test that tc_set() fails to set non-existant leaf nodes with nodown "
00326        "returning false",
00327        ((err = tc_set(&ctx, "foo.none.here", "blah", 0)) == ENOENT), FATAL(0),
00328        ("tc_set() correctly returned failure when setting \"foo.none.here\""),
00329        ("tc_set() returned unexpected error code %u setting non-existant node "
00330       "\"foo.none.here\"", err));
00331 
00332   /* Test that tc_set() may create implicit nodes */
00333   tn_nodown(node) = nodown_true;
00334   TEST(t_treeconf, tc_set_implicit,
00335        "Test that tc_set() may create implicit nodes if nodown returns true",
00336        (!(err = tc_set(&ctx, "foo.implicit.variable", "varb", 0)) &&
00337       !(err = tc_find(&ctx, "foo.implicit", &node, 0)) &&
00338       tn_type(node) == (TC_NODETYPE_IMPLICIT | TC_NODETYPE_NODE) &&
00339       !(err = tc_find(&ctx, "foo.implicit.variable", &node, 0)) &&
00340       tn_type(node) == (TC_NODETYPE_IMPLICIT | TC_NODETYPE_VARIABLE) &&
00341       !strcmp(tn_value(node), "varb")), FATAL(0),
00342        ("tc_set() implicitly created \"foo.implicit\" and "
00343       "\"foo.implicit.variable\""),
00344        ("tc_set() failed to create \"foo.implicit.variable\" with implicit "
00345       "nodes; error code %u", err));
00346 
00347   /* Now mask foo.implicit.variable by setting foo.implicit */
00348   TEST(t_treeconf, tc_set_imploverride,
00349        "Test that tc_set() may override implicitly created tree nodes",
00350        (!(err = tc_set(&ctx, "foo.implicit", "impl", 0)) &&
00351       !(err = tc_find(&ctx, "foo.implicit", &node, 0)) &&
00352       tn_type(node) == (TC_NODETYPE_IMPLICIT | TC_NODETYPE_VARIABLE) &&
00353       !strcmp(tn_value(node), "impl") &&
00354       (err = tc_find(&ctx, "foo.implicit.variable", &node, 0)) == ENOENT),
00355        0,
00356        ("tc_set() overrode implicitly created \"foo.implicit\" tree node "
00357       "with a variable node"),
00358        ("tc_set() failed to override implicitly created \"foo.implicit\" "
00359       "tree node; error code %u", err));
00360 
00361   /* tc_set() may not override non-implicit tree nodes */
00362   TEST(t_treeconf, tc_set_nonimplicit,
00363        "Test that tc_set() may not override explicitly created tree nodes",
00364        ((err = tc_set(&ctx, "foo", "oof", 0)) == TC_ERR_MISMATCH), FATAL(0),
00365        ("tc_set() correctly refused to override explicit tree node"),
00366        ("tc_set() returned unexpected error code %u", err));
00367 
00368   /* tc_set() must call the change callback */
00369   change = 0; /* zero the change count */
00370   TEST(t_treeconf, tc_set_change,
00371        "Test that tc_set() calls change callback when appropriate",
00372        (!(err = tc_set(&ctx, "foo.bink.foo", "bar", 0)) && change == 1),
00373        FATAL(0),
00374        ("tc_set() called change callback when changing \"foo.bink.foo\""),
00375        ("tc_set() failed to call change callback; error code %u", err));
00376 
00377   if ((err = tc_find(&ctx, "foo.bink.foo", &node, 0))) /* look up a node... */
00378     FAIL(TEST_NAME(tc_find_node), FATAL(0), "tc_find() failed to find "
00379        "\"foo.bink.foo\"; error code %u", err);
00380 
00381   /* tc_set() must set to the default value if that's what is given */
00382   TEST(t_treeconf, tc_set_value_default,
00383        "Test that tc_set() uses the default value when that is what is given",
00384        (!(err = tc_set(&ctx, "foo.bink.foo", "baz", 0)) && tn_isdef(node)),
00385        FATAL(0),
00386        ("tc_set() uses default value when value is default"),
00387        ("tc_set() failed to use default when value is default; error code %u",
00388       err));
00389 
00390   if ((err = tc_set(&ctx, "foo.bink.foo", "bar", 0))) /* set non-default */
00391     FAIL(TEST_NAME(tc_set_basic), FATAL(0), "tc_set() failed to set "
00392        "non-default value for \"foo.bink.foo\"; error code %u", err);
00393 
00394   /* tc_set() must set to the default value if NULL is passed */
00395   TEST(t_treeconf, tc_set_null_default,
00396        "Test that tc_set() uses the default value when NULL is given",
00397        (!(err = tc_set(&ctx, "foo.bink.foo", 0, 0)) && tn_isdef(node)),
00398        FATAL(0),
00399        ("tc_set() uses default value when value is NULL"),
00400        ("tc_set() failed to use default value when value is NULL; error code "
00401       "%u", err));
00402 
00403   /***************************************************************************/
00404   /* Final tc_register test                                                  */
00405   /***************************************************************************/
00406 
00407   /* tc_register() must call change callback when creating formerly implicit
00408    * nodes...
00409    */
00410   change = 0; /* zero the change count... */
00411   TEST(t_treeconf, tc_register_change,
00412        "Test that tc_register() calls change callback when explicitly "
00413        "creating an implicit node",
00414        (!(err = tc_register(&ctx, "foo.implicit", "variable", 0, 0,
00415                       t_change, 0)) && change == 1), FATAL(0),
00416        ("tc_register() properly called change callback"),
00417        ("tc_register() failed to call change callback; error code %u", err));
00418 
00419   /***************************************************************************/
00420   /* Finally, test tc_destroy                                                */
00421   /***************************************************************************/
00422 
00423   /* Verify that tc_destroy() destroys a context... */
00424   TEST(t_treeconf, tc_destroy,
00425        "Test that tc_destroy() destroys a context",
00426        (!(err = tc_destroy(&ctx)) && !tx_verify(&ctx) && !tx_config(&ctx) &&
00427       !tx_count(&ctx)), FATAL(0),
00428        ("tc_destroy() properly destroyed context"),
00429        ("tc_destroy() failed to destroy context; error code %u", err));
00430 
00431   return 0;
00432 }

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