Merge commit 'release-4-0-0alpha15' into master4-tmp
[ira/wip.git] / source4 / lib / ldb / tools / ldbtest.c
index c912245682fa39b479e834dfc998c29119231959..4e181af9d55f03c623896ca25fc67662e645968b 100644 (file)
@@ -10,7 +10,7 @@
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
+   version 3 of the License, or (at your option) any later version.
 
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,8 +18,7 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
 
 /*
  *  Author: Andrew Tridgell
  */
 
-#include "includes.h"
-#include "ldb/include/includes.h"
-#include "ldb/tools/cmdline.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
+#include "ldb.h"
+#include "tools/cmdline.h"
 
-static struct timeval tp1,tp2;
+static struct timespec tp1,tp2;
 static struct ldb_cmdline *options;
 
 static void _start_timer(void)
 {
-       gettimeofday(&tp1,NULL);
+       if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp1) != 0) {
+               clock_gettime(CLOCK_REALTIME, &tp1);
+       }
 }
 
 static double _end_timer(void)
 {
-       gettimeofday(&tp2,NULL);
+       if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp2) != 0) {
+               clock_gettime(CLOCK_REALTIME, &tp2);
+       }
        return((tp2.tv_sec - tp1.tv_sec) + 
-              (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
+              (tp2.tv_nsec - tp1.tv_nsec)*1.0e-9);
 }
 
 static void add_records(struct ldb_context *ldb,
-                       const struct ldb_dn *basedn,
-                       int count)
+                       struct ldb_dn *basedn,
+                       unsigned int count)
 {
        struct ldb_message msg;
-       int i;
+       unsigned int i;
 
 #if 0
         if (ldb_lock(ldb, "transaction") != 0) {
                 printf("transaction lock failed\n");
-                exit(1);
+                exit(LDB_ERR_OPERATIONS_ERROR);
         }
 #endif
        for (i=0;i<count;i++) {
@@ -70,9 +75,10 @@ static void add_records(struct ldb_context *ldb,
                char *name;
                TALLOC_CTX *tmp_ctx = talloc_new(ldb);
 
-               asprintf(&name, "Test%d", i);
+               name = talloc_asprintf(tmp_ctx, "Test%d", i);
 
-               msg.dn = ldb_dn_build_child(tmp_ctx, "cn", name, basedn);
+               msg.dn = ldb_dn_copy(tmp_ctx, basedn);
+               ldb_dn_add_child_fmt(msg.dn, "cn=%s", name);
                msg.num_elements = 6;
                msg.elements = el;
 
@@ -94,7 +100,7 @@ static void add_records(struct ldb_context *ldb,
                el[2].name = talloc_strdup(tmp_ctx, "uid");
                el[2].num_values = 1;
                el[2].values = vals[2];
-               vals[2][0].data = (uint8_t *)ldb_casefold(ldb, tmp_ctx, name);
+               vals[2][0].data = (uint8_t *)ldb_casefold(ldb, tmp_ctx, name, strlen(name));
                vals[2][0].length = strlen((char *)vals[2][0].data);
 
                el[3].flags = 0;
@@ -120,9 +126,9 @@ static void add_records(struct ldb_context *ldb,
 
                ldb_delete(ldb, msg.dn);
 
-               if (ldb_add(ldb, &msg) != 0) {
+               if (ldb_add(ldb, &msg) != LDB_SUCCESS) {
                        printf("Add of %s failed - %s\n", name, ldb_errstring(ldb));
-                       exit(1);
+                       exit(LDB_ERR_OPERATIONS_ERROR);
                }
 
                printf("adding uid %s\r", name);
@@ -133,18 +139,18 @@ static void add_records(struct ldb_context *ldb,
 #if 0
         if (ldb_unlock(ldb, "transaction") != 0) {
                 printf("transaction unlock failed\n");
-                exit(1);
+                exit(LDB_ERR_OPERATIONS_ERROR);
         }
 #endif
        printf("\n");
 }
 
 static void modify_records(struct ldb_context *ldb,
-                          const struct ldb_dn *basedn,
-                          int count)
+                          struct ldb_dn *basedn,
+                          unsigned int count)
 {
        struct ldb_message msg;
-       int i;
+       unsigned int i;
 
        for (i=0;i<count;i++) {
                struct ldb_message_element el[3];
@@ -153,7 +159,8 @@ static void modify_records(struct ldb_context *ldb,
                TALLOC_CTX *tmp_ctx = talloc_new(ldb);
                
                name = talloc_asprintf(tmp_ctx, "Test%d", i);
-               msg.dn = ldb_dn_build_child(tmp_ctx, "cn", name, basedn);
+               msg.dn = ldb_dn_copy(tmp_ctx, basedn);
+               ldb_dn_add_child_fmt(msg.dn, "cn=%s", name);
 
                msg.num_elements = 3;
                msg.elements = el;
@@ -176,9 +183,9 @@ static void modify_records(struct ldb_context *ldb,
                vals[2].data = (uint8_t *)talloc_asprintf(tmp_ctx, "%s@other2.example.com", name);
                vals[2].length = strlen((char *)vals[2].data);
 
-               if (ldb_modify(ldb, &msg) != 0) {
+               if (ldb_modify(ldb, &msg) != LDB_SUCCESS) {
                        printf("Modify of %s failed - %s\n", name, ldb_errstring(ldb));
-                       exit(1);
+                       exit(LDB_ERR_OPERATIONS_ERROR);
                }
 
                printf("Modifying uid %s\r", name);
@@ -192,22 +199,23 @@ static void modify_records(struct ldb_context *ldb,
 
 
 static void delete_records(struct ldb_context *ldb,
-                          const struct ldb_dn *basedn,
-                          int count)
+                          struct ldb_dn *basedn,
+                          unsigned int count)
 {
-       int i;
+       unsigned int i;
 
        for (i=0;i<count;i++) {
                struct ldb_dn *dn;
                char *name = talloc_asprintf(ldb, "Test%d", i);
-               dn = ldb_dn_build_child(name, "cn", name, basedn);
+               dn = ldb_dn_copy(name, basedn);
+               ldb_dn_add_child_fmt(dn, "cn=%s", name);
 
                printf("Deleting uid Test%d\r", i);
                fflush(stdout);
 
-               if (ldb_delete(ldb, dn) != 0) {
-                       printf("Delete of %s failed - %s\n", ldb_dn_linearize(ldb, dn), ldb_errstring(ldb));
-                       exit(1);
+               if (ldb_delete(ldb, dn) != LDB_SUCCESS) {
+                       printf("Delete of %s failed - %s\n", ldb_dn_get_linearized(dn), ldb_errstring(ldb));
+                       exit(LDB_ERR_OPERATIONS_ERROR);
                }
                talloc_free(name);
        }
@@ -215,9 +223,10 @@ static void delete_records(struct ldb_context *ldb,
        printf("\n");
 }
 
-static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn, int nrecords, int nsearches)
+static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn,
+                      unsigned int nrecords, unsigned int nsearches)
 {
-       int i;
+       unsigned int i;
 
        for (i=0;i<nsearches;i++) {
                int uid = (i * 700 + 17) % (nrecords * 2);
@@ -225,34 +234,39 @@ static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn, int nreco
                struct ldb_result *res = NULL;
                int ret;
 
-               asprintf(&expr, "(uid=TEST%d)", uid);
-               ret = ldb_search(ldb, basedn, LDB_SCOPE_SUBTREE, expr, NULL, &res);
+               expr = talloc_asprintf(ldb, "(uid=TEST%d)", uid);
+               ret = ldb_search(ldb, ldb, &res, basedn, LDB_SCOPE_SUBTREE, NULL, "%s", expr);
 
                if (ret != LDB_SUCCESS || (uid < nrecords && res->count != 1)) {
                        printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb));
-                       exit(1);
+                       exit(LDB_ERR_OPERATIONS_ERROR);
                }
 
                if (uid >= nrecords && res->count > 0) {
                        printf("Found %s !? - %d\n", expr, ret);
-                       exit(1);
+                       exit(LDB_ERR_OPERATIONS_ERROR);
                }
 
-               printf("testing uid %d/%d - %d  \r", i, uid, res->count);
+               printf("Testing uid %d/%d - %d  \r", i, uid, res->count);
                fflush(stdout);
 
                talloc_free(res);
-               free(expr);
+               talloc_free(expr);
        }
 
        printf("\n");
 }
 
-static void start_test(struct ldb_context *ldb, int nrecords, int nsearches)
+static void start_test(struct ldb_context *ldb, unsigned int nrecords,
+                      unsigned int nsearches)
 {
        struct ldb_dn *basedn;
 
-       basedn = ldb_dn_explode(ldb, options->basedn);
+       basedn = ldb_dn_new(ldb, ldb, options->basedn);
+       if ( ! ldb_dn_validate(basedn)) {
+               printf("Invalid base DN format\n");
+               exit(LDB_ERR_INVALID_DN_SYNTAX);
+       }
 
        printf("Adding %d records\n", nrecords);
        add_records(ldb, basedn, nrecords);
@@ -290,7 +304,14 @@ static void start_test_index(struct ldb_context **ldb)
        struct ldb_dn *indexlist;
        struct ldb_dn *basedn;
        int ret;
-       int flags = 0;
+       unsigned int flags = 0;
+       const char *specials;
+
+       specials = getenv("LDB_SPECIALS");
+       if (specials && atoi(specials) == 0) {
+               printf("LDB_SPECIALS disabled - skipping index test\n");
+               return;
+       }
 
        if (options->nosync) {
                flags |= LDB_FLG_NOSYNC;
@@ -298,7 +319,7 @@ static void start_test_index(struct ldb_context **ldb)
 
        printf("Starting index test\n");
 
-       indexlist = ldb_dn_explode(NULL, "@INDEXLIST");
+       indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST");
 
        ldb_delete(*ldb, indexlist);
 
@@ -308,58 +329,65 @@ static void start_test_index(struct ldb_context **ldb)
        ldb_msg_add_string(msg, "@IDXATTR", strdup("uid"));
 
        if (ldb_add(*ldb, msg) != 0) {
-               printf("Add of %s failed - %s\n", ldb_dn_linearize(*ldb, msg->dn), ldb_errstring(*ldb));
-               exit(1);
+               printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb));
+               exit(LDB_ERR_OPERATIONS_ERROR);
        }
 
-       basedn = ldb_dn_explode(NULL, options->basedn);
+       basedn = ldb_dn_new(*ldb, *ldb, options->basedn);
 
        memset(msg, 0, sizeof(*msg));
-       msg->dn = ldb_dn_build_child(msg, "cn", "test", basedn);
+       msg->dn = ldb_dn_copy(msg, basedn);
+       ldb_dn_add_child_fmt(msg->dn, "cn=test");
        ldb_msg_add_string(msg, "cn", strdup("test"));
        ldb_msg_add_string(msg, "sn", strdup("test"));
        ldb_msg_add_string(msg, "uid", strdup("test"));
        ldb_msg_add_string(msg, "objectClass", strdup("OpenLDAPperson"));
 
-       if (ldb_add(*ldb, msg) != 0) {
-               printf("Add of %s failed - %s\n", ldb_dn_linearize(*ldb, msg->dn), ldb_errstring(*ldb));
-               exit(1);
+       if (ldb_add(*ldb, msg) != LDB_SUCCESS) {
+               printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb));
+               exit(LDB_ERR_OPERATIONS_ERROR);
        }
 
        if (talloc_free(*ldb) != 0) {
                printf("failed to free/close ldb database");
-               exit(1);
+               exit(LDB_ERR_OPERATIONS_ERROR);
        }
 
-       (*ldb) = ldb_init(options);
-       
+       (*ldb) = ldb_init(options, NULL);
+
        ret = ldb_connect(*ldb, options->url, flags, NULL);
-       if (ret != 0) {
+       if (ret != LDB_SUCCESS) {
                printf("failed to connect to %s\n", options->url);
-               exit(1);
+               exit(LDB_ERR_OPERATIONS_ERROR);
        }
 
-       ret = ldb_search(*ldb, basedn, LDB_SCOPE_SUBTREE, "uid=test", NULL, &res);
+       basedn = ldb_dn_new(*ldb, *ldb, options->basedn);
+       msg->dn = basedn;
+       ldb_dn_add_child_fmt(msg->dn, "cn=test");
+
+       ret = ldb_search(*ldb, *ldb, &res, basedn, LDB_SCOPE_SUBTREE, NULL, "uid=test");
        if (ret != LDB_SUCCESS) { 
                printf("Search with (uid=test) filter failed!\n");
-               exit(1);
+               exit(LDB_ERR_OPERATIONS_ERROR);
        }
        if(res->count != 1) {
                printf("Should have found 1 record - found %d\n", res->count);
-               exit(1);
+               exit(LDB_ERR_OPERATIONS_ERROR);
        }
 
+       indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST");
+
        if (ldb_delete(*ldb, msg->dn) != 0 ||
            ldb_delete(*ldb, indexlist) != 0) {
                printf("cleanup failed - %s\n", ldb_errstring(*ldb));
-               exit(1);
+               exit(LDB_ERR_OPERATIONS_ERROR);
        }
 
        printf("Finished index test\n");
 }
 
 
-static void usage(void)
+static void usage(struct ldb_context *ldb)
 {
        printf("Usage: ldbtest <options>\n");
        printf("Options:\n");
@@ -368,7 +396,7 @@ static void usage(void)
        printf("  --num-searches nsearches     number of searches to do\n");
        printf("\n");
        printf("tests ldb API\n\n");
-       exit(1);
+       exit(LDB_ERR_OPERATIONS_ERROR);
 }
 
 int main(int argc, const char **argv)
@@ -376,9 +404,10 @@ int main(int argc, const char **argv)
        TALLOC_CTX *mem_ctx = talloc_new(NULL);
        struct ldb_context *ldb;
 
-       ldb_global_init();
-
-       ldb = ldb_init(mem_ctx);
+       ldb = ldb_init(mem_ctx, NULL);
+       if (ldb == NULL) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
 
        options = ldb_cmdline_process(ldb, argc, argv, usage);
 
@@ -393,11 +422,13 @@ int main(int argc, const char **argv)
        printf("Testing with num-records=%d and num-searches=%d\n", 
               options->num_records, options->num_searches);
 
-       start_test(ldb, options->num_records, options->num_searches);
+       start_test(ldb,
+                  (unsigned int) options->num_records,
+                  (unsigned int) options->num_searches);
 
        start_test_index(&ldb);
 
        talloc_free(mem_ctx);
 
-       return 0;
+       return LDB_SUCCESS;
 }