Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Convert config module to unit testing
[simgrid.git] / src / xbt / config.c
index f2d57d0..618ec71 100644 (file)
@@ -9,8 +9,6 @@
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
-#include <stdio.h> /* FIXME: killme */
-
 #include "xbt/misc.h"
 #include "xbt/sysdep.h"
 #include "xbt/log.h"
@@ -210,7 +208,8 @@ xbt_cfg_register(xbt_cfg_t cfg,
   xbt_assert4(type>=xbt_cfgelm_int && type<=xbt_cfgelm_host,
               "type of %s not valid (%d should be between %d and %d)",
               name,type,xbt_cfgelm_int, xbt_cfgelm_host);
-  DEBUG5("Register cfg elm %s (%d to %d %s (=%d))",name,min,max,xbt_cfgelm_type_name[type],type);
+  DEBUG5("Register cfg elm %s (%d to %d %s (=%d))",
+        name,min,max,xbt_cfgelm_type_name[type],type);
   TRY {
     res = xbt_dict_get((xbt_dict_t)cfg,name);
   } CATCH(e) {
@@ -284,7 +283,7 @@ xbt_cfg_unregister(xbt_cfg_t cfg,const char *name) {
  * with type being one of  'string','int', 'host' or 'double'.
  */
 
-xbt_error_t
+void
 xbt_cfg_register_str(xbt_cfg_t cfg,const char *entry) {
   char *entrycpy=xbt_strdup(entry);
   char *tok;
@@ -293,66 +292,42 @@ xbt_cfg_register_str(xbt_cfg_t cfg,const char *entry) {
   e_xbt_cfgelm_type_t type;
 
   tok=strchr(entrycpy, ':');
-  if (!tok) {
-    ERROR3("%s%s%s",
-         "Invalid config element descriptor: ",entry,
-         "; Should be <name>:<min nb>_to_<max nb>_<type>");
-    free(entrycpy);
-    xbt_abort();
-  }
+  xbt_assert2(tok,"Invalid config element descriptor: %s%s",
+             entry,
+             "; Should be <name>:<min nb>_to_<max nb>_<type>");
   *(tok++)='\0';
 
   min=strtol(tok, &tok, 10);
-  if (!tok) {
-    ERROR1("Invalid minimum in config element descriptor %s",entry);
-    free(entrycpy);
-    xbt_abort();
-  }
+  xbt_assert1(tok,"Invalid minimum in config element descriptor %s",entry);
 
-  if (!strcmp(tok,"_to_")){
-    ERROR3("%s%s%s",
-         "Invalid config element descriptor: ",entry,
-         "; Should be <name>:<min nb>_to_<max nb>_<type>");
-    free(entrycpy);
-    xbt_abort();
-  }
+  xbt_assert2(strcmp(tok,"_to_"),
+             "Invalid config element descriptor : %s%s",           
+             entry,
+             "; Should be <name>:<min nb>_to_<max nb>_<type>");
   tok += strlen("_to_");
 
   max=strtol(tok, &tok, 10);
-  if (!tok) {
-    ERROR1("Invalid maximum in config element descriptor %s",entry);
-    free(entrycpy);
-    xbt_abort();
-  }
+  xbt_assert1(tok,"Invalid maximum in config element descriptor %s",entry);
 
-  if (*(tok++)!='_') {
-    ERROR3("%s%s%s",
-         "Invalid config element descriptor: ",entry,
-         "; Should be <name>:<min nb>_to_<max nb>_<type>");
-    free(entrycpy);
-    xbt_abort();
-  }
+  xbt_assert2( *(tok++) =='_',
+              "Invalid config element descriptor: %s%s",entry,
+              "; Should be <name>:<min nb>_to_<max nb>_<type>");
 
   for (type=0; 
        type<xbt_cfgelm_type_count && strcmp(tok,xbt_cfgelm_type_name[type]); 
        type++);
-  if (type == xbt_cfgelm_type_count) {
-    ERROR3("%s%s%s",
-         "Invalid type in config element descriptor: ",entry,
+  xbt_assert2(type < xbt_cfgelm_type_count,
+         "Invalid type in config element descriptor: %s%s",entry,
          "; Should be one of 'string', 'int', 'host' or 'double'.");
-    free(entrycpy);
-    xbt_abort();
-  }
 
   xbt_cfg_register(cfg,entrycpy,type,min,max,NULL,NULL);
 
   free(entrycpy); /* strdup'ed by dict mechanism, but cannot be const */
-  return no_error;
 }
 
 /** @brief Check that each variable have the right amount of values */
 
-xbt_error_t
+void
 xbt_cfg_check(xbt_cfg_t cfg) {
   xbt_dict_cursor_t cursor; 
   xbt_cfgelm_t variable;
@@ -364,35 +339,33 @@ xbt_cfg_check(xbt_cfg_t cfg) {
   xbt_dict_foreach((xbt_dict_t)cfg,cursor,name,variable) {
     size = xbt_dynar_length(variable->content);
     if (variable->min > size) { 
-      ERROR4("Config elem %s needs at least %d %s, but there is only %d values.",
+      xbt_dict_cursor_free(&cursor);
+      THROW4(mismatch_error,0,
+            "Config elem %s needs at least %d %s, but there is only %d values.",
             name,
             variable->min,
             xbt_cfgelm_type_name[variable->type],
             size); 
-      xbt_dict_cursor_free(&cursor);
-      return mismatch_error;
     }
 
     if (variable->max > 0 && variable->max < size) {
-      ERROR4("Config elem %s accepts at most %d %s, but there is %d values.",
+      xbt_dict_cursor_free(&cursor);
+      THROW4(mismatch_error,0,
+            "Config elem %s accepts at most %d %s, but there is %d values.",
             name,
             variable->max,
             xbt_cfgelm_type_name[variable->type],
             size);
-      xbt_dict_cursor_free(&cursor);
-      return mismatch_error;
     }
-
   }
 
   xbt_dict_cursor_free(&cursor);
-  return no_error;
 }
 
 static xbt_cfgelm_t xbt_cfgelm_get(xbt_cfg_t  cfg,
                                   const char *name,
                                   e_xbt_cfgelm_type_t type){
-  xbt_cfgelm_t res;
+  xbt_cfgelm_t res=NULL;
   xbt_ex_t e;
 
   TRY {
@@ -459,7 +432,7 @@ xbt_cfg_set_vargs(xbt_cfg_t cfg, const char *name, va_list pa) {
   char *str;
   int i;
   double d;
-  e_xbt_cfgelm_type_t type;
+  e_xbt_cfgelm_type_t type=0; /* Set a dummy value to make gcc happy. It cannot get uninitialized */
 
   xbt_ex_t e;
   
@@ -535,7 +508,7 @@ xbt_cfg_set_parse(xbt_cfg_t cfg, const char *options) {
   double d;
   char *str;
 
-  xbt_cfgelm_t variable;
+  xbt_cfgelm_t variable=NULL;
   char *optionlist_cpy;
   char *option,  *name,*val;
 
@@ -568,8 +541,8 @@ xbt_cfg_set_parse(xbt_cfg_t cfg, const char *options) {
       option=NULL; /* don't do next iteration */
 
     } else {
-      DEBUG3("Boundary on '%c'. len=%d;option-name=%d",
-            *option,len,option-name);
+      DEBUG3("Boundary on '%c'. len=%d;option-name=%ld",
+            *option,len,(long)(option-name));
 
       /* Pass the following blank chars */
       *(option++)='\0';
@@ -592,7 +565,7 @@ xbt_cfg_set_parse(xbt_cfg_t cfg, const char *options) {
     if (!val) {
       free(optionlist_cpy);
       xbt_assert1(FALSE,
-            "Malformated option: '%s'; Should be of the form 'name:value'",
+            "Option '%s' badly formated. Should be of the form 'name:value'",
                  name);
     }
     *(val++)='\0';
@@ -602,6 +575,8 @@ xbt_cfg_set_parse(xbt_cfg_t cfg, const char *options) {
     TRY {
       variable = xbt_dict_get((xbt_dict_t)cfg,name);
     } CATCH(e) {
+      /* put it back on what won't get freed, ie within "options" and out of "optionlist_cpy" */
+      name = (char*) (optionlist_cpy-name + options); 
       free(optionlist_cpy);
       if (e.category == not_found_error) {
        xbt_ex_free(e);
@@ -967,7 +942,7 @@ void xbt_cfg_rm_at   (xbt_cfg_t cfg, const char *name, int pos) {
 
 void
 xbt_cfg_empty(xbt_cfg_t cfg,const char*name) {
-  xbt_cfgelm_t variable;
+  xbt_cfgelm_t variable=NULL;
   xbt_ex_t e;
 
   TRY {
@@ -1110,7 +1085,7 @@ void xbt_cfg_get_host  (xbt_cfg_t   cfg,  const char *name,
  * \warning the returned value is the actual content of the config set
  */
 xbt_dynar_t xbt_cfg_get_dynar (xbt_cfg_t    cfg, const char *name) {
-  xbt_cfgelm_t variable;
+  xbt_cfgelm_t variable=NULL;
   xbt_ex_t     e;
 
   TRY {
@@ -1164,3 +1139,114 @@ xbt_cfg_get_host_at(xbt_cfg_t cfg, const char *name, int pos,
   *port = val->port;
   *host = val->name;
 }
+
+
+#ifdef SIMGRID_TEST
+#include "xbt.h"
+#include "xbt/ex.h"
+
+XBT_TEST_SUITE("config","Configuration support");
+
+static xbt_cfg_t make_set(){
+  xbt_cfg_t set=NULL; 
+
+  set = xbt_cfg_new();
+  xbt_cfg_register_str(set,"speed:1_to_2_int");
+  xbt_cfg_register_str(set,"hostname:1_to_1_string");
+  xbt_cfg_register_str(set,"user:1_to_10_string");
+
+  return set;
+} /* end_of_make_set */
+
+XBT_TEST_UNIT("memuse",test_config_memuse,"Alloc and free a config set") {
+  xbt_cfg_t set=make_set();
+  xbt_test_add0("Alloc and free a config set");
+  xbt_cfg_set_parse(set, "hostname:veloce user:mquinson\nuser:oaumage\tuser:alegrand");
+  xbt_cfg_free(&set);
+  xbt_cfg_free(&set);
+}
+
+XBT_TEST_UNIT("validation",test_config_validation,"Validation tests") {
+  xbt_cfg_t set = set=make_set();
+  xbt_ex_t e;
+  
+  xbt_test_add0("Having too few elements for speed");
+  xbt_cfg_set_parse(set, "hostname:veloce user:mquinson\nuser:oaumage\tuser:alegrand");
+  TRY {
+    xbt_cfg_check(set);
+  } CATCH(e) {
+    if (e.category != mismatch_error || 
+       strncmp(e.msg,"Config elem speed needs",strlen("Config elem speed needs")))
+      xbt_test_fail1("Got an exception. msg=%s",e.msg);
+    xbt_ex_free(e);
+  }
+  xbt_cfg_free(&set);
+  xbt_cfg_free(&set);
+
+
+
+  xbt_test_add0("Having too much values of 'speed'");
+  set=make_set(); 
+  xbt_cfg_set_parse(set,"hostname:toto:42 user:alegrand");
+  TRY {
+    xbt_cfg_set_parse(set,"speed:42 speed:24 speed:34");
+  } CATCH(e) {
+    if (e.category != mismatch_error ||
+       strncmp(e.msg,"Cannot add value 34 to the config elem speed",
+               strlen("Config elem speed needs")))
+      xbt_test_fail1("Got an exception. msg=%s",e.msg);
+    xbt_ex_free(e);
+  }
+  xbt_cfg_check(set);
+  xbt_cfg_free(&set);
+  xbt_cfg_free(&set);
+
+}
+
+XBT_TEST_UNIT("use",test_config_use,"Data retrieving tests") {
+  xbt_cfg_t set = set=make_set();
+
+  xbt_test_add0("Get a single value");
+  {    
+    /* get_single_value */
+    int ival;
+    xbt_cfg_t myset=make_set();
+    
+    xbt_cfg_set_parse(myset,"hostname:toto:42 speed:42");
+    ival = xbt_cfg_get_int(myset,"speed"); 
+    if (ival != 42) 
+      xbt_test_fail1("Speed value = %d, I expected 42",ival);
+    xbt_cfg_free(&myset);
+  }
+
+  xbt_test_add0("Get multiple values");
+  {    
+    /* get_multiple_value */
+    xbt_dynar_t dyn; 
+    xbt_cfg_t myset=make_set();
+    
+    xbt_cfg_set_parse(myset, "hostname:veloce user:foo\nuser:bar\tuser:toto");
+    xbt_cfg_set_parse(myset,"speed:42");
+    xbt_cfg_check(myset); 
+    dyn = xbt_cfg_get_dynar(myset,"user");
+
+    if (xbt_dynar_length(dyn) != 3) 
+      xbt_test_fail1("Dynar length = %d, I expected 3",
+                    (int)xbt_dynar_length(dyn));
+
+    if (strcmp(xbt_dynar_get_as(dyn,0,char*),"foo"))
+      xbt_test_fail1("Dynar[0] = %s, I expected foo",
+                    xbt_dynar_get_as(dyn,0,char*));
+
+    if (strcmp(xbt_dynar_get_as(dyn,1,char*),"bar"))
+      xbt_test_fail1("Dynar[1] = %s, I expected bar",
+                    xbt_dynar_get_as(dyn,1,char*));
+
+    if (strcmp(xbt_dynar_get_as(dyn,2,char*),"toto"))
+      xbt_test_fail1("Dynar[2] = %s, I expected toto",
+                    xbt_dynar_get_as(dyn,2,char*));
+    
+  }
+}
+#endif /* SIMGRID_TEST */