static int ldbtest_setup(void **state)
{
struct ldbtest_ctx *test_ctx;
+ struct ldb_ldif *ldif;
+#ifdef GUID_IDX
+ const char *index_ldif = \
+ "dn: @INDEXLIST\n"
+ "@IDXGUID: objectUUID\n"
+ "@IDX_DN_GUID: GUID\n"
+ "\n";
+#else
+ const char *index_ldif = "\n";
+#endif
int ret;
ldbtest_noconn_setup((void **) &test_ctx);
ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
assert_int_equal(ret, 0);
+ while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) {
+ ret = ldb_add(test_ctx->ldb, ldif->msg);
+ assert_int_equal(ret, LDB_SUCCESS);
+ }
*state = test_ctx;
return 0;
}
ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
assert_int_equal(ret, 0);
+ ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef");
+ assert_int_equal(ret, 0);
+
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, 0);
ret = ldb_msg_add_string(msg, "cn", "test_cn_val1");
assert_int_equal(ret, 0);
+ ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde1");
+ assert_int_equal(ret, 0);
+
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, 0);
ret = ldb_msg_add_string(msg, "cn", "test_cn_val2");
assert_int_equal(ret, 0);
+ ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde2");
+ assert_int_equal(ret, 0);
+
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, 0);
static void add_dn_with_cn(struct ldbtest_ctx *test_ctx,
struct ldb_dn *dn,
- const char *cn_value)
+ const char *cn_value,
+ const char *uuid_value)
{
int ret;
TALLOC_CTX *tmp_ctx;
ret = ldb_msg_add_string(msg, "cn", cn_value);
assert_int_equal(ret, LDB_SUCCESS);
+ ret = ldb_msg_add_string(msg, "objectUUID", uuid_value);
+ assert_int_equal(ret, 0);
+
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, LDB_SUCCESS);
dn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s", basedn);
assert_non_null(dn);
- add_dn_with_cn(test_ctx, dn, "test_del_cn_val");
+ add_dn_with_cn(test_ctx, dn,
+ "test_del_cn_val",
+ "0123456789abcdef");
ret = ldb_delete(test_ctx->ldb, dn);
assert_int_equal(ret, LDB_SUCCESS);
static void add_keyval(struct ldbtest_ctx *test_ctx,
const char *key,
- const char *val)
+ const char *val,
+ const char *uuid)
{
int ret;
struct ldb_message *msg;
ret = ldb_msg_add_string(msg, key, val);
assert_int_equal(ret, 0);
+ ret = ldb_msg_add_string(msg, "objectUUID", uuid);
+ assert_int_equal(ret, 0);
+
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, 0);
ret = ldb_transaction_start(test_ctx->ldb);
assert_int_equal(ret, 0);
- add_keyval(test_ctx, "vegetable", "carrot");
+ add_keyval(test_ctx, "vegetable", "carrot",
+ "0123456789abcde0");
/* commit lev-0 transaction */
ret = ldb_transaction_commit(test_ctx->ldb);
ret = ldb_transaction_start(test_ctx->ldb);
assert_int_equal(ret, 0);
- add_keyval(test_ctx, "fruit", "apple");
+ add_keyval(test_ctx, "fruit", "apple",
+ "0123456789abcde1");
/* abort lev-1 nested transaction */
ret = ldb_transaction_cancel(test_ctx->ldb);
ret = ldb_transaction_start(test_ctx->ldb);
assert_int_equal(ret, 0);
- add_keyval(test_ctx, "vegetable", "carrot");
+ add_keyval(test_ctx, "vegetable", "carrot",
+ "0123456789abcde0");
/* start another lev-1 nested transaction */
ret = ldb_transaction_start(test_ctx->ldb);
assert_int_equal(ret, 0);
- add_keyval(test_ctx, "fruit", "apple");
+ add_keyval(test_ctx, "fruit", "apple",
+ "0123456789abcde1");
/* abort lev-1 nested transaction */
ret = ldb_transaction_cancel(test_ctx->ldb);
struct ldb_mod_test_ctx *mod_test_ctx;
struct keyval kvs[] = {
{ "cn", "test_mod_cn" },
+ { "objectUUID", "0123456789abcdef"},
{ NULL, NULL },
};
{ "cn", "test_search_cn2" },
{ "uid", "test_search_uid" },
{ "uid", "test_search_uid2" },
+ { "objectUUID", "0123456789abcde0"},
{ NULL, NULL },
};
struct keyval kvs2[] = {
{ "cn", "test_search_2_cn2" },
{ "uid", "test_search_2_uid" },
{ "uid", "test_search_2_uid2" },
+ { "objectUUID", "0123456789abcde1"},
{ NULL, NULL },
};
struct ldb_message *msg;
TALLOC_FREE(ctx->test_ctx->ldb);
TALLOC_FREE(ctx->test_ctx->ev);
+ close(pipes[0]);
ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
if (ctx->test_ctx->ev == NULL) {
exit(LDB_ERR_OPERATIONS_ERROR);
exit(LDB_ERR_OPERATIONS_ERROR);
}
+ ret = ldb_msg_add_string(msg, "objectUUID",
+ "0123456789abcdef");
+ if (ret != 0) {
+ exit(ret);
+ }
+
ret = ldb_add(ctx->test_ctx->ldb, msg);
if (ret != 0) {
exit(ret);
ret = ldb_transaction_commit(ctx->test_ctx->ldb);
exit(ret);
}
-
+ close(pipes[1]);
ret = read(pipes[0], buf, 2);
assert_int_equal(ret, 2);
struct ldb_dn *dn, *new_dn;
TALLOC_FREE(ctx->test_ctx->ldb);
TALLOC_FREE(ctx->test_ctx->ev);
+ close(pipes[0]);
ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
if (ctx->test_ctx->ev == NULL) {
exit(LDB_ERR_OPERATIONS_ERROR);
struct ldb_message_element *el;
TALLOC_FREE(ctx->test_ctx->ldb);
TALLOC_FREE(ctx->test_ctx->ev);
+ close(pipes[0]);
ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
if (ctx->test_ctx->ev == NULL) {
exit(LDB_ERR_OPERATIONS_ERROR);
* sending the "GO" as it is blocked at ldb_transaction_start().
*/
+ close(pipes[1]);
ret = read(pipes[0], buf, 2);
assert_int_equal(ret, 2);
ret = ldb_msg_add_string(msg, "@IDXATTR", "cn");
assert_int_equal(ret, LDB_SUCCESS);
-
ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb,
msg);
-
+ if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
+ msg->elements[0].flags = LDB_FLAG_MOD_ADD;
+ ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb,
+ msg);
+ }
assert_int_equal(ret, LDB_SUCCESS);
}
static void test_ldb_modify_during_indexed_search(void **state)
{
- return test_ldb_modify_during_search(state, true, false);
+ test_ldb_modify_during_search(state, true, false);
}
static void test_ldb_modify_during_unindexed_search(void **state)
{
- return test_ldb_modify_during_search(state, false, false);
+ test_ldb_modify_during_search(state, false, false);
}
static void test_ldb_rename_during_indexed_search(void **state)
{
- return test_ldb_modify_during_search(state, true, true);
+ test_ldb_modify_during_search(state, true, true);
}
static void test_ldb_rename_during_unindexed_search(void **state)
{
- return test_ldb_modify_during_search(state, false, true);
+ test_ldb_modify_during_search(state, false, true);
}
/*
struct ldb_message_element *el;
TALLOC_FREE(ctx->test_ctx->ldb);
TALLOC_FREE(ctx->test_ctx->ev);
+ close(pipes[0]);
ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
if (ctx->test_ctx->ev == NULL) {
exit(LDB_ERR_OPERATIONS_ERROR);
exit(ret);
}
+ close(pipes[1]);
ret = read(pipes[0], buf, 2);
assert_int_equal(ret, 2);
struct ldb_message_element *el;
TALLOC_FREE(search_test_ctx->ldb_test_ctx->ldb);
TALLOC_FREE(search_test_ctx->ldb_test_ctx->ev);
+ close(pipes[0]);
search_test_ctx->ldb_test_ctx->ev = tevent_context_init(search_test_ctx->ldb_test_ctx);
if (search_test_ctx->ldb_test_ctx->ev == NULL) {
exit(LDB_ERR_OPERATIONS_ERROR);
ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb);
exit(ret);
}
+ close(pipes[1]);
ret = read(pipes[0], buf, 2);
assert_int_equal(ret, 2);
struct keyval kvs[] = {
{ "cn", "CaseInsensitiveValue" },
{ "uid", "CaseSensitiveValue" },
+ { "objectUUID", "0123456789abcdef" },
{ NULL, NULL },
};
/* Add the index (actually any modify will do) */
while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
+ if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
+ ldif->msg->elements[0].flags = LDB_FLAG_MOD_ADD;
+ ret = ldb_modify(ldb_test_ctx->ldb,
+ ldif->msg);
+ }
assert_int_equal(ret, LDB_SUCCESS);
}
add_dn_with_cn(ldb_test_ctx,
rename_test_ctx->basedn,
- "test_rename_cn_val");
+ "test_rename_cn_val",
+ "0123456789abcde0");
*state = rename_test_ctx;
return 0;
add_dn_with_cn(rename_test_ctx->ldb_test_ctx,
new_dn,
- "test_rename_cn_val");
+ "test_rename_cn_val",
+ "0123456789abcde1");
ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
rename_test_ctx->basedn,
ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
assert_int_equal(ret, 0);
+ ret = ldb_msg_add_string(msg, "objectUUID",
+ "0123456789abcde1");
+ assert_int_equal(ret, LDB_SUCCESS);
+
ret = ldb_add(ro_ldb, msg);
assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
TALLOC_FREE(msg);
msg = ldb_msg_new(tmp_ctx);
assert_non_null(msg);
- msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
+ msg->dn = ldb_dn_new_fmt(msg, rw_ldb, "dc=test");
assert_non_null(msg->dn);
ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
assert_int_equal(ret, 0);
+ ret = ldb_msg_add_string(msg, "objectUUID",
+ "0123456789abcde2");
+ assert_int_equal(ret, LDB_SUCCESS);
+
ret = ldb_add(rw_ldb, msg);
assert_int_equal(ret, LDB_SUCCESS);
TALLOC_FREE(msg);
const char *index_ldif = \
"dn: @INDEXLIST\n"
"@IDXATTR: cn\n"
+#ifdef GUID_IDX
+ "@IDXGUID: objectUUID\n"
+ "@IDX_DN_GUID: GUID\n"
+#endif
"\n";
- const char *options[] = {"modules:unique_index_test"};
+ const char *options[] = {"modules:unique_index_test", NULL};
ret = ldb_register_module(&ldb_unique_index_test_module_ops);
ret = ldb_msg_add_string(msg, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
+ ret = ldb_msg_add_string(msg, "objectUUID",
+ "0123456789abcde1");
+ assert_int_equal(ret, LDB_SUCCESS);
+
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, LDB_SUCCESS);
const char *index_ldif = \
"dn: @INDEXLIST\n"
"@IDXATTR: cn\n"
+#ifdef GUID_IDX
+ "@IDXGUID: objectUUID\n"
+ "@IDX_DN_GUID: GUID\n"
+#endif
"\n";
- const char *options[] = {"modules:unique_index_test"};
+ const char *options[] = {"modules:unique_index_test", NULL};
ret = ldb_register_module(&ldb_unique_index_test_module_ops);
ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
+ ret = ldb_msg_add_string(msg01, "objectUUID",
+ "0123456789abcde1");
+ assert_int_equal(ret, LDB_SUCCESS);
+
ret = ldb_add(test_ctx->ldb, msg01);
assert_int_equal(ret, LDB_SUCCESS);
ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
+ ret = ldb_msg_add_string(msg02, "objectUUID",
+ "0123456789abcde2");
+ assert_int_equal(ret, LDB_SUCCESS);
+
ret = ldb_add(test_ctx->ldb, msg02);
assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
talloc_free(tmp_ctx);
ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
+ ret = ldb_msg_add_string(msg01, "objectUUID",
+ "0123456789abcde1");
+
ret = ldb_add(test_ctx->ldb, msg01);
assert_int_equal(ret, LDB_SUCCESS);
ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
+ ret = ldb_msg_add_string(msg02, "objectUUID",
+ "0123456789abcde2");
+
ret = ldb_add(test_ctx->ldb, msg02);
assert_int_equal(ret, LDB_SUCCESS);
talloc_free(tmp_ctx);
ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
+ ret = ldb_msg_add_string(msg01, "objectUUID",
+ "0123456789abcde1");
+
ret = ldb_add(test_ctx->ldb, msg01);
assert_int_equal(ret, LDB_SUCCESS);
ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
+ ret = ldb_msg_add_string(msg02, "objectUUID",
+ "0123456789abcde2");
+
ret = ldb_add(test_ctx->ldb, msg02);
assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
talloc_free(tmp_ctx);
char *debug_string = NULL;
char *p = NULL;
+ /* The GUID mode is not compatible with this test */
+#ifdef GUID_IDX
+ return;
+#endif
+
ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
tmp_ctx = talloc_new(test_ctx);
assert_non_null(tmp_ctx);
ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
+ ret = ldb_msg_add_string(msg01, "objectUUID",
+ "0123456789abcde1");
+
ret = ldb_add(test_ctx->ldb, msg01);
assert_int_equal(ret, LDB_SUCCESS);
ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
+ ret = ldb_msg_add_string(msg02, "objectUUID",
+ "0123456789abcde2");
+
ret = ldb_add(test_ctx->ldb, msg02);
assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
TALLOC_CTX *tmp_ctx;
char *debug_string = NULL;
+ /* The GUID mode is not compatible with this test */
+#ifdef GUID_IDX
+ return;
+#endif
+
ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
tmp_ctx = talloc_new(test_ctx);
assert_non_null(tmp_ctx);
ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
assert_int_equal(ret, LDB_SUCCESS);
+ ret = ldb_msg_add_string(msg01, "objectUUID",
+ "0123456789abcde1");
+
ret = ldb_add(test_ctx->ldb, msg01);
assert_int_equal(ret, LDB_SUCCESS);
ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
assert_int_equal(ret, LDB_SUCCESS);
+ ret = ldb_msg_add_string(msg02, "objectUUID",
+ "0123456789abcde2");
+
ret = ldb_add(test_ctx->ldb, msg02);
assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
}
}
+static void test_transaction_start_across_fork(void **state)
+{
+ struct ldb_context *ldb1 = NULL;
+ int ret;
+ struct ldbtest_ctx *test_ctx = NULL;
+ int pipes[2];
+ char buf[2];
+ int wstatus;
+ pid_t pid, child_pid;
+
+ test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
+
+ /*
+ * Open the database
+ */
+ ldb1 = ldb_init(test_ctx, test_ctx->ev);
+ ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL);
+ assert_int_equal(ret, 0);
+
+ ret = pipe(pipes);
+ assert_int_equal(ret, 0);
+
+ child_pid = fork();
+ if (child_pid == 0) {
+ close(pipes[0]);
+ ret = ldb_transaction_start(ldb1);
+ if (ret != LDB_ERR_PROTOCOL_ERROR) {
+ print_error(__location__": ldb_transaction_start "
+ "returned (%d) %s\n",
+ ret,
+ ldb1->err_string);
+ exit(LDB_ERR_OTHER);
+ }
+
+ ret = write(pipes[1], "GO", 2);
+ if (ret != 2) {
+ print_error(__location__
+ " write returned (%d)",
+ ret);
+ exit(LDB_ERR_OPERATIONS_ERROR);
+ }
+ exit(LDB_SUCCESS);
+ }
+ close(pipes[1]);
+ ret = read(pipes[0], buf, 2);
+ assert_int_equal(ret, 2);
+
+ pid = waitpid(child_pid, &wstatus, 0);
+ assert_int_equal(pid, child_pid);
+
+ assert_true(WIFEXITED(wstatus));
+
+ assert_int_equal(WEXITSTATUS(wstatus), 0);
+}
+
+static void test_transaction_commit_across_fork(void **state)
+{
+ struct ldb_context *ldb1 = NULL;
+ int ret;
+ struct ldbtest_ctx *test_ctx = NULL;
+ int pipes[2];
+ char buf[2];
+ int wstatus;
+ pid_t pid, child_pid;
+
+ test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
+
+ /*
+ * Open the database
+ */
+ ldb1 = ldb_init(test_ctx, test_ctx->ev);
+ ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL);
+ assert_int_equal(ret, 0);
+
+ ret = ldb_transaction_start(ldb1);
+ assert_int_equal(ret, 0);
+
+ ret = pipe(pipes);
+ assert_int_equal(ret, 0);
+
+ child_pid = fork();
+ if (child_pid == 0) {
+ close(pipes[0]);
+ ret = ldb_transaction_commit(ldb1);
+
+ if (ret != LDB_ERR_PROTOCOL_ERROR) {
+ print_error(__location__": ldb_transaction_commit "
+ "returned (%d) %s\n",
+ ret,
+ ldb1->err_string);
+ exit(LDB_ERR_OTHER);
+ }
+
+ ret = write(pipes[1], "GO", 2);
+ if (ret != 2) {
+ print_error(__location__
+ " write returned (%d)",
+ ret);
+ exit(LDB_ERR_OPERATIONS_ERROR);
+ }
+ exit(LDB_SUCCESS);
+ }
+ close(pipes[1]);
+ ret = read(pipes[0], buf, 2);
+ assert_int_equal(ret, 2);
+
+ pid = waitpid(child_pid, &wstatus, 0);
+ assert_int_equal(pid, child_pid);
+
+ assert_true(WIFEXITED(wstatus));
+
+ assert_int_equal(WEXITSTATUS(wstatus), 0);
+}
+
+static void test_lock_read_across_fork(void **state)
+{
+ struct ldb_context *ldb1 = NULL;
+ int ret;
+ struct ldbtest_ctx *test_ctx = NULL;
+ int pipes[2];
+ char buf[2];
+ int wstatus;
+ pid_t pid, child_pid;
+
+ test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
+
+ /*
+ * Open the database
+ */
+ ldb1 = ldb_init(test_ctx, test_ctx->ev);
+ ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL);
+ assert_int_equal(ret, 0);
+
+ ret = pipe(pipes);
+ assert_int_equal(ret, 0);
+
+ child_pid = fork();
+ if (child_pid == 0) {
+ struct ldb_dn *basedn;
+ struct ldb_result *result = NULL;
+
+ close(pipes[0]);
+
+ basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "dc=test");
+ assert_non_null(basedn);
+
+ ret = ldb_search(test_ctx->ldb,
+ test_ctx,
+ &result,
+ basedn,
+ LDB_SCOPE_BASE,
+ NULL,
+ NULL);
+ if (ret != LDB_ERR_PROTOCOL_ERROR) {
+ print_error(__location__": ldb_search "
+ "returned (%d) %s\n",
+ ret,
+ ldb1->err_string);
+ exit(LDB_ERR_OTHER);
+ }
+
+ ret = write(pipes[1], "GO", 2);
+ if (ret != 2) {
+ print_error(__location__
+ " write returned (%d)",
+ ret);
+ exit(LDB_ERR_OPERATIONS_ERROR);
+ }
+ exit(LDB_SUCCESS);
+ }
+ close(pipes[1]);
+ ret = read(pipes[0], buf, 2);
+ assert_int_equal(ret, 2);
+
+ pid = waitpid(child_pid, &wstatus, 0);
+ assert_int_equal(pid, child_pid);
+
+ assert_true(WIFEXITED(wstatus));
+
+ assert_int_equal(WEXITSTATUS(wstatus), 0);
+
+ {
+ /*
+ * Ensure that the search actually succeeds on the opening
+ * pid
+ */
+ struct ldb_dn *basedn;
+ struct ldb_result *result = NULL;
+
+ close(pipes[0]);
+
+ basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "dc=test");
+ assert_non_null(basedn);
+
+ ret = ldb_search(test_ctx->ldb,
+ test_ctx,
+ &result,
+ basedn,
+ LDB_SCOPE_BASE,
+ NULL,
+ NULL);
+ assert_int_equal(0, ret);
+ }
+}
+
+static void test_multiple_opens_across_fork(void **state)
+{
+ struct ldb_context *ldb1 = NULL;
+ struct ldb_context *ldb2 = NULL;
+ int ret;
+ struct ldbtest_ctx *test_ctx = NULL;
+ int pipes[2];
+ char buf[2];
+ int wstatus;
+ pid_t pid, child_pid;
+
+ test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
+
+ /*
+ * Open the database again
+ */
+ ldb1 = ldb_init(test_ctx, test_ctx->ev);
+ ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
+ assert_int_equal(ret, 0);
+
+ ldb2 = ldb_init(test_ctx, test_ctx->ev);
+ ret = ldb_connect(ldb2, test_ctx->dbpath, 0, NULL);
+ assert_int_equal(ret, 0);
+
+ ret = pipe(pipes);
+ assert_int_equal(ret, 0);
+
+ child_pid = fork();
+ if (child_pid == 0) {
+ struct ldb_context *ldb3 = NULL;
+
+ close(pipes[0]);
+ ldb3 = ldb_init(test_ctx, test_ctx->ev);
+ ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL);
+ if (ret != 0) {
+ print_error(__location__": ldb_connect returned (%d)\n",
+ ret);
+ exit(ret);
+ }
+ ret = write(pipes[1], "GO", 2);
+ if (ret != 2) {
+ print_error(__location__
+ " write returned (%d)",
+ ret);
+ exit(LDB_ERR_OPERATIONS_ERROR);
+ }
+ exit(LDB_SUCCESS);
+ }
+ close(pipes[1]);
+ ret = read(pipes[0], buf, 2);
+ assert_int_equal(ret, 2);
+
+ pid = waitpid(child_pid, &wstatus, 0);
+ assert_int_equal(pid, child_pid);
+
+ assert_true(WIFEXITED(wstatus));
+
+ assert_int_equal(WEXITSTATUS(wstatus), 0);
+}
int main(int argc, const char **argv)
{
test_ldb_add_to_index_unique_values_required,
ldb_non_unique_index_test_setup,
ldb_non_unique_index_test_teardown),
+ /* These tests are not compatible with mdb */
cmocka_unit_test_setup_teardown(
test_ldb_unique_index_duplicate_logging,
ldb_unique_index_test_setup,
test_ldb_talloc_destructor_transaction_cleanup,
ldbtest_setup,
ldbtest_teardown),
+ cmocka_unit_test_setup_teardown(
+ test_transaction_start_across_fork,
+ ldbtest_setup,
+ ldbtest_teardown),
+ cmocka_unit_test_setup_teardown(
+ test_transaction_commit_across_fork,
+ ldbtest_setup,
+ ldbtest_teardown),
+ cmocka_unit_test_setup_teardown(
+ test_lock_read_across_fork,
+ ldbtest_setup,
+ ldbtest_teardown),
+ cmocka_unit_test_setup_teardown(
+ test_multiple_opens_across_fork,
+ ldbtest_setup,
+ ldbtest_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);