ldb: Add tests for read only behaviour
authorGary Lockyer <gary@catalyst.net.nz>
Wed, 13 Sep 2017 23:37:41 +0000 (11:37 +1200)
committerDouglas Bagnall <dbagnall@samba.org>
Wed, 20 Sep 2017 00:25:30 +0000 (02:25 +0200)
As the kernel is no longer enforcing the read-only DB
add some tests.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13033

Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
lib/ldb/tests/ldb_mod_op_test.c

index 5e439f8d151b2c82530ef9a424ec58218f013775..48ad20c7662bab6d49cb8ed6244158aa2c047aa6 100644 (file)
@@ -2861,6 +2861,155 @@ static void test_ldb_rename_dn_case_change(void **state)
        /* FIXME - test the values didn't change */
 }
 
+static int ldb_read_only_setup(void **state)
+{
+       struct ldbtest_ctx *test_ctx;
+
+       ldbtest_setup((void **) &test_ctx);
+
+       *state = test_ctx;
+       return 0;
+}
+
+static int ldb_read_only_teardown(void **state)
+{
+       struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
+                                                       struct ldbtest_ctx);
+       ldbtest_teardown((void **) &test_ctx);
+       return 0;
+}
+
+static void test_read_only(void **state)
+{
+       struct ldb_context *ro_ldb = NULL;
+       struct ldb_context *rw_ldb = NULL;
+       int ret;
+       TALLOC_CTX *tmp_ctx = NULL;
+
+       struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
+                                                       struct ldbtest_ctx);
+       /*
+        * Close the ldb context freeing it this will ensure it exists on
+        * disk and can be opened in read only mode
+        */
+       TALLOC_FREE(test_ctx->ldb);
+
+       /*
+        * Open the database in read only and read write mode,
+        * ensure it's opend in read only mode first
+        */
+       ro_ldb = ldb_init(test_ctx, test_ctx->ev);
+       ret = ldb_connect(ro_ldb, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
+       assert_int_equal(ret, 0);
+
+       rw_ldb = ldb_init(test_ctx, test_ctx->ev);
+       ret = ldb_connect(rw_ldb, test_ctx->dbpath, 0, NULL);
+       assert_int_equal(ret, 0);
+
+
+       /*
+        * Set up a context for the temporary variables
+        */
+       tmp_ctx = talloc_new(test_ctx);
+       assert_non_null(tmp_ctx);
+
+       /*
+        * Ensure that we can search the read write database
+        */
+       {
+               struct ldb_result *result = NULL;
+               struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb,
+                                                      "dc=test");
+               assert_non_null(dn);
+
+               ret = ldb_search(rw_ldb, tmp_ctx, &result, dn,
+                                LDB_SCOPE_BASE, NULL, NULL);
+               assert_int_equal(ret, LDB_SUCCESS);
+               TALLOC_FREE(result);
+               TALLOC_FREE(dn);
+       }
+
+       /*
+        * Ensure that we can search the read only database
+        */
+       {
+               struct ldb_result *result = NULL;
+               struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb,
+                                                      "dc=test");
+               assert_non_null(dn);
+
+               ret = ldb_search(ro_ldb, tmp_ctx, &result, dn,
+                                LDB_SCOPE_BASE, NULL, NULL);
+               assert_int_equal(ret, LDB_SUCCESS);
+               TALLOC_FREE(result);
+               TALLOC_FREE(dn);
+       }
+       /*
+        * Ensure that a write to the read only database fails
+        */
+       {
+               struct ldb_message *msg = NULL;
+               msg = ldb_msg_new(tmp_ctx);
+               assert_non_null(msg);
+
+               msg->dn = ldb_dn_new_fmt(msg, ro_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_add(ro_ldb, msg);
+               assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
+               TALLOC_FREE(msg);
+       }
+
+       /*
+        * Ensure that a write to the read write database succeeds
+        */
+       {
+               struct ldb_message *msg = NULL;
+               msg = ldb_msg_new(tmp_ctx);
+               assert_non_null(msg);
+
+               msg->dn = ldb_dn_new_fmt(msg, ro_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_add(rw_ldb, msg);
+               assert_int_equal(ret, LDB_SUCCESS);
+               TALLOC_FREE(msg);
+       }
+
+       /*
+        * Ensure that a delete from a read only database fails
+        */
+       {
+               struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test");
+               assert_non_null(dn);
+
+               ret = ldb_delete(ro_ldb, dn);
+               assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
+               TALLOC_FREE(dn);
+       }
+
+
+       /*
+        * Ensure that a delete from a read write succeeds
+        */
+       {
+               struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test");
+               assert_non_null(dn);
+
+               ret = ldb_delete(rw_ldb, dn);
+               assert_int_equal(ret, LDB_SUCCESS);
+               TALLOC_FREE(dn);
+       }
+       TALLOC_FREE(tmp_ctx);
+}
+
+
 int main(int argc, const char **argv)
 {
        const struct CMUnitTest tests[] = {
@@ -2981,6 +3130,9 @@ int main(int argc, const char **argv)
                cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change,
                                                ldb_rename_test_setup,
                                                ldb_rename_test_teardown),
+               cmocka_unit_test_setup_teardown(test_read_only,
+                                               ldb_read_only_setup,
+                                               ldb_read_only_teardown),
        };
 
        return cmocka_run_group_tests(tests, NULL, NULL);