s4/tort: Unit test for schemaInfo implementation
authorKamen Mazdrashki <kamenim@samba.org>
Mon, 29 Mar 2010 09:31:38 +0000 (12:31 +0300)
committerKamen Mazdrashki <kamenim@samba.org>
Fri, 9 Apr 2010 09:21:27 +0000 (12:21 +0300)
source4/torture/drs/config.mk
source4/torture/drs/drs_init.c
source4/torture/drs/unit/schemainfo_tests.c [new file with mode: 0644]

index 0ce3a3d17aa88ae2a0ff40afe4036f3ceae2833c..0fdeb97df17f6f335484e88a09ac37602924cf31 100644 (file)
@@ -19,6 +19,7 @@ PRIVATE_DEPENDENCIES = \
 TORTURE_DRS_OBJ_FILES = \
                $(torturesrcdir)/drs/drs_init.o \
                $(torturesrcdir)/drs/drs_util.o \
+               $(torturesrcdir)/drs/unit/schemainfo_tests.o \
                $(torturesrcdir)/drs/unit/prefixmap_tests.o
 
 $(eval $(call proto_header_template,$(torturesrcdir)/drs/proto.h,$(TORTURE_DRS_OBJ_FILES:.o=.c)))
index 081565fc57da5fa133c2f323e4e0954bc9a2a49c..35520ba54a757d261c71a1b80e3553fb54f2e182 100644 (file)
@@ -22,6 +22,7 @@
 #include "includes.h"
 #include "torture/smbtorture.h"
 #include "torture/rpc/drsuapi.h"
+#include "dsdb/samdb/samdb.h"
 #include "torture/drs/proto.h"
 
 /**
@@ -46,6 +47,7 @@ static struct torture_suite * torture_drs_unit_suite(TALLOC_CTX *mem_ctx)
                "UNIT");
 
        torture_drs_unit_prefixmap(suite);
+       torture_drs_unit_schemainfo(suite);
 
        return suite;
 }
diff --git a/source4/torture/drs/unit/schemainfo_tests.c b/source4/torture/drs/unit/schemainfo_tests.c
new file mode 100644 (file)
index 0000000..ab9de87
--- /dev/null
@@ -0,0 +1,579 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   DRSUAPI schemaInfo unit tests
+
+   Copyright (C) Kamen Mazdrashki <kamenim@samba.org> 2010
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "system/filesys.h"
+#include "torture/smbtorture.h"
+#include "dsdb/samdb/samdb.h"
+#include "dsdb/samdb/ldb_modules/util.h"
+#include "lib/ldb_wrap.h"
+#include "lib/ldb/include/ldb_module.h"
+#include "torture/rpc/drsuapi.h"
+#include "librpc/ndr/libndr.h"
+#include "param/param.h"
+
+
+/**
+ * schemaInfo to init ldb context with
+ *   Rev:  01
+ *   GUID: 071c82fd-45c7-4351-a3db-51f75a630a7f
+ */
+#define SCHEMA_INFO_INIT_STR           "FF0000000100000000000000000000000000000000"
+
+/**
+ * Default schema_info string to be used for testing
+ *   Rev:  01
+ *   GUID: 071c82fd-45c7-4351-a3db-51f75a630a7f
+ */
+#define SCHEMA_INFO_DEFAULT_STR        "FF00000001FD821C07C7455143A3DB51F75A630A7F"
+
+/**
+ * Schema info data to test with
+ */
+struct schemainfo_data {
+       DATA_BLOB       ndr_blob;
+       struct dsdb_schema_info schi;
+       WERROR          werr_expected;
+       bool            test_both_ways;
+};
+
+/**
+ * Schema info test data in human-readable format (... kind of)
+ */
+static const struct {
+       const char      *schema_info_str;
+       uint32_t        revision;
+       const char      *guid_str;
+       WERROR          werr_expected;
+       bool            test_both_ways;
+} _schemainfo_test_data[] = {
+       {
+               .schema_info_str = "FF00000001FD821C07C7455143A3DB51F75A630A7F",
+               .revision = 1,
+               .guid_str = "071c82fd-45c7-4351-a3db-51f75a630a7f",
+               .werr_expected = WERR_OK,
+               .test_both_ways = true
+       },
+       {
+               .schema_info_str = "FFFFFFFFFFFD821C07C7455143A3DB51F75A630A7F",
+               .revision = 0xFFFFFFFF,
+               .guid_str = "071c82fd-45c7-4351-a3db-51f75a630a7f",
+               .werr_expected = WERR_OK,
+               .test_both_ways = true
+       },
+       { /* revision > 0 */
+               .schema_info_str = "FF00000000FD821C07C7455143A3DB51F75A630A7F",
+               .revision = 0,
+               .guid_str = "071c82fd-45c7-4351-a3db-51f75a630a7f",
+               .werr_expected = WERR_INVALID_PARAMETER,
+               .test_both_ways = true
+       },
+       { /* len == 21 */
+               .schema_info_str = "FF00000001FD821C07C7455143A3DB51F75A630A7F00",
+               .revision = 1,
+               .guid_str = "071c82fd-45c7-4351-a3db-51f75a630a7f",
+               .werr_expected = WERR_INVALID_PARAMETER,
+               .test_both_ways = false
+       },
+       { /* marker == FF */
+               .schema_info_str = "AA00000001FD821C07C7455143A3DB51F75A630A7F",
+               .revision = 1,
+               .guid_str = "071c82fd-45c7-4351-a3db-51f75a630a7f",
+               .werr_expected = WERR_INVALID_PARAMETER,
+               .test_both_ways = false
+       }
+};
+
+/**
+ * Private data to be shared among all test in Test case
+ */
+struct drsut_schemainfo_data {
+       struct ldb_context *ldb;
+       struct ldb_module  *ldb_module;
+       struct dsdb_schema *schema;
+
+       /* Initial schemaInfo set in ldb to test with */
+       struct dsdb_schema_info *schema_info;
+
+       uint32_t test_data_count;
+       struct schemainfo_data *test_data;
+};
+
+/**
+ * torture macro to assert for equal dsdb_schema_info's
+ */
+#define torture_assert_schema_info_equal(torture_ctx,got,expected,cmt)\
+       do { const struct dsdb_schema_info *__got = (got), *__expected = (expected); \
+       if (__got->revision != __expected->revision) { \
+               torture_result(torture_ctx, TORTURE_FAIL, \
+                              __location__": "#got".revision %d did not match "#expected".revision %d: %s", \
+                              (int)__got->revision, (int)__expected->revision, cmt); \
+               return false; \
+       } \
+       if (!GUID_equal(&__got->invocation_id, &__expected->invocation_id)) { \
+               torture_result(torture_ctx, TORTURE_FAIL, \
+                              __location__": "#got".invocation_id did not match "#expected".invocation_id: %s", cmt); \
+               return false; \
+       } \
+       } while(0)
+
+/*
+ * forward declaration for internal functions
+ */
+static bool _drsut_ldb_schema_info_reset(struct torture_context *tctx,
+                                        struct ldb_context *ldb,
+                                        const char *schema_info_str,
+                                        bool in_setup);
+
+
+/**
+ * Creates dsdb_schema_info object based on NDR data
+ * passed as hex string
+ */
+static bool _drsut_schemainfo_new(struct torture_context *tctx,
+                                 const char *schema_info_str, struct dsdb_schema_info **_si)
+{
+       WERROR werr;
+       DATA_BLOB blob;
+
+       blob = strhex_to_data_blob(tctx, schema_info_str);
+       if (!blob.data) {
+               torture_comment(tctx, "Not enough memory!\n");
+               return false;
+       }
+
+       werr = dsdb_schema_info_from_blob(&blob, tctx, _si);
+       if (!W_ERROR_IS_OK(werr)) {
+               torture_comment(tctx,
+                               "Failed to create dsdb_schema_info object for %s: %s",
+                               schema_info_str,
+                               win_errstr(werr));
+               return false;
+       }
+
+       data_blob_free(&blob);
+
+       return true;
+}
+
+/**
+ * Creates dsdb_schema_info object based on predefined data
+ * Function is public as it is intended to be used by other
+ * tests (e.g. prefixMap tests)
+ */
+bool drsut_schemainfo_new(struct torture_context *tctx, struct dsdb_schema_info **_si)
+{
+       return _drsut_schemainfo_new(tctx, SCHEMA_INFO_DEFAULT_STR, _si);
+}
+
+
+/*
+ * Tests dsdb_schema_info_from_blob()
+ */
+static bool test_dsdb_schema_info_from_blob(struct torture_context *tctx,
+                                           struct drsut_schemainfo_data *priv)
+{
+       int i;
+       WERROR werr;
+       char *msg;
+       struct dsdb_schema_info *schema_info;
+       TALLOC_CTX *mem_ctx;
+
+       mem_ctx = talloc_new(priv);
+       torture_assert(tctx, mem_ctx, "Not enough memory!");
+
+       for (i = 0; i < priv->test_data_count; i++) {
+               struct schemainfo_data *data = &priv->test_data[i];
+
+               msg = talloc_asprintf(tctx, "dsdb_schema_info_from_blob() [%d]-[%s]",
+                                     i, _schemainfo_test_data[i].schema_info_str);
+
+               werr = dsdb_schema_info_from_blob(&data->ndr_blob, mem_ctx, &schema_info);
+               torture_assert_werr_equal(tctx, werr, data->werr_expected, msg);
+
+               /* test returned data */
+               if (W_ERROR_IS_OK(werr)) {
+                       torture_assert_schema_info_equal(tctx,
+                                                        schema_info, &data->schi,
+                                                        "after dsdb_schema_info_from_blob() call");
+               }
+       }
+
+       talloc_free(mem_ctx);
+
+       return true;
+}
+
+/*
+ * Tests dsdb_blob_from_schema_info()
+ */
+static bool test_dsdb_blob_from_schema_info(struct torture_context *tctx,
+                                           struct drsut_schemainfo_data *priv)
+{
+       int i;
+       WERROR werr;
+       char *msg;
+       DATA_BLOB ndr_blob;
+       TALLOC_CTX *mem_ctx;
+
+       mem_ctx = talloc_new(priv);
+       torture_assert(tctx, mem_ctx, "Not enough memory!");
+
+       for (i = 0; i < priv->test_data_count; i++) {
+               struct schemainfo_data *data = &priv->test_data[i];
+
+               /* not all test are valid reverse type of conversion */
+               if (!data->test_both_ways) {
+                       continue;
+               }
+
+               msg = talloc_asprintf(tctx, "dsdb_blob_from_schema_info() [%d]-[%s]",
+                                     i, _schemainfo_test_data[i].schema_info_str);
+
+               werr = dsdb_blob_from_schema_info(&data->schi, mem_ctx, &ndr_blob);
+               torture_assert_werr_equal(tctx, werr, data->werr_expected, msg);
+
+               /* test returned data */
+               if (W_ERROR_IS_OK(werr)) {
+                       torture_assert_data_blob_equal(tctx,
+                                                      ndr_blob, data->ndr_blob,
+                                                      "dsdb_blob_from_schema_info()");
+               }
+       }
+
+       talloc_free(mem_ctx);
+
+       return true;
+}
+
+/*
+ * Tests dsdb_module_schema_info_blob_read()
+ *   and dsdb_module_schema_info_blob_write()
+ */
+static bool test_dsdb_module_schema_info_blob_rw(struct torture_context *tctx,
+                                               struct drsut_schemainfo_data *priv)
+{
+       WERROR werr;
+       DATA_BLOB blob_write;
+       DATA_BLOB blob_read;
+
+       /* reset schmeInfo to know value */
+       torture_assert(tctx,
+                      _drsut_ldb_schema_info_reset(tctx, priv->ldb, SCHEMA_INFO_INIT_STR, false),
+                      "_drsut_ldb_schema_info_reset() failed");
+
+       /* write tests' default schemaInfo */
+       blob_write = strhex_to_data_blob(priv, SCHEMA_INFO_DEFAULT_STR);
+       torture_assert(tctx, blob_write.data, "Not enough memory!");
+
+       werr = dsdb_module_schema_info_blob_write(priv->ldb_module,
+                                                 DSDB_FLAG_TOP_MODULE,
+                                                 &blob_write);
+       torture_assert_werr_ok(tctx, werr, "dsdb_module_schema_info_blob_write() failed");
+
+       werr = dsdb_module_schema_info_blob_read(priv->ldb_module, DSDB_FLAG_TOP_MODULE,
+                                                priv, &blob_read);
+       torture_assert_werr_ok(tctx, werr, "dsdb_module_schema_info_blob_read() failed");
+
+       /* check if we get what we wrote */
+       torture_assert_data_blob_equal(tctx, blob_read, blob_write,
+                                      "Write/Read of schemeInfo blob failed");
+
+       return true;
+}
+
+/*
+ * Tests dsdb_schema_update_schema_info()
+ */
+static bool test_dsdb_module_schema_info_update(struct torture_context *tctx,
+                                               struct drsut_schemainfo_data *priv)
+{
+       WERROR werr;
+       DATA_BLOB blob;
+       struct dsdb_schema_info *schema_info;
+
+       /* reset schmeInfo to know value */
+       torture_assert(tctx,
+                      _drsut_ldb_schema_info_reset(tctx, priv->ldb, SCHEMA_INFO_INIT_STR, false),
+                      "_drsut_ldb_schema_info_reset() failed");
+
+       werr = dsdb_module_schema_info_update(priv->ldb_module,
+                                             priv->schema,
+                                             DSDB_FLAG_TOP_MODULE | DSDB_FLAG_AS_SYSTEM);
+       torture_assert_werr_ok(tctx, werr, "dsdb_module_schema_info_update() failed");
+
+       /* get updated schemaInfo */
+       werr = dsdb_module_schema_info_blob_read(priv->ldb_module, DSDB_FLAG_TOP_MODULE,
+                                                priv, &blob);
+       torture_assert_werr_ok(tctx, werr, "dsdb_module_schema_info_blob_read() failed");
+
+       werr = dsdb_schema_info_from_blob(&blob, priv, &schema_info);
+       torture_assert_werr_ok(tctx, werr, "dsdb_schema_info_from_blob() failed");
+
+       /* decrement revision to be able to compare
+        * against default schemaInfo later */
+       schema_info->revision--;
+
+       /* check against default schema_info */
+       torture_assert_schema_info_equal(tctx, schema_info, priv->schema_info,
+                                         "schemaInfo attribute no updated correctly");
+
+       return true;
+}
+
+/*
+ * Tests dsdb_schema_info_create()
+ */
+static bool test_dsdb_schema_info_create(struct torture_context *tctx,
+                                        struct drsut_schemainfo_data *priv)
+{
+       WERROR werr;
+       struct dsdb_schema_info *schema_info = NULL;
+
+       werr = dsdb_schema_info_create(priv->ldb, priv, &schema_info);
+       torture_assert_werr_ok(tctx, werr, "dsdb_schema_info_create() failed");
+
+       torture_assert(tctx, schema_info, "schema_info is NULL after dsdb_schema_info_create()");
+       torture_assert_int_equal(tctx, schema_info->revision, 1, "Invalid schemaInfo revision");
+       torture_assert(tctx,
+                      GUID_equal(&schema_info->invocation_id, &priv->schema_info->invocation_id),
+                      "Invalid invocationId returned");
+
+       talloc_free(schema_info);
+
+       return true;
+}
+
+
+/**
+ * Reset schemaInfo record to know value
+ */
+static bool _drsut_ldb_schema_info_reset(struct torture_context *tctx,
+                                        struct ldb_context *ldb,
+                                        const char *schema_info_str,
+                                        bool in_setup)
+{
+       bool bret = true;
+       int ldb_err;
+       DATA_BLOB blob;
+       struct ldb_message *msg;
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+
+       blob = strhex_to_data_blob(mem_ctx, schema_info_str);
+       torture_assert_goto(tctx, blob.data, bret, DONE, "Not enough memory!");
+
+       msg = ldb_msg_new(mem_ctx);
+       torture_assert_goto(tctx, msg, bret, DONE, "Not enough memory!");
+
+       msg->dn = samdb_schema_dn(ldb);
+       ldb_err = ldb_msg_add_value(msg, "schemaInfo", &blob, NULL);
+       torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE,
+                                     "ldb_msg_add_value() failed");
+
+       if (in_setup) {
+               ldb_err = ldb_add(ldb, msg);
+       } else {
+               ldb_err = dsdb_replace(ldb, msg, DSDB_MODIFY_PERMISSIVE);
+       }
+       torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE,
+                                     "dsdb_replace() failed");
+
+DONE:
+       talloc_free(mem_ctx);
+       return bret;
+}
+
+/**
+ * Prepare temporary LDB and opens it
+ */
+static bool _drsut_ldb_setup(struct torture_context *tctx, struct drsut_schemainfo_data *priv)
+{
+       int ldb_err;
+       char *ldb_url;
+       bool bret = true;
+       char *tempdir = NULL;
+       NTSTATUS status;
+       TALLOC_CTX* mem_ctx;
+
+       mem_ctx = talloc_new(priv);
+       torture_assert(tctx, mem_ctx, "Not enough memory!");
+
+       status = torture_temp_dir(tctx, "drs_", &tempdir);
+       torture_assert_ntstatus_ok_goto(tctx, status, bret, DONE, "creating temp dir");
+
+       ldb_url = talloc_asprintf(priv, "%s/drs_schemainfo.ldb", tempdir);
+       torture_assert_goto(tctx, ldb_url, bret, DONE, "Not enough memory!");
+
+       /* create LDB */
+       priv->ldb = ldb_wrap_connect(priv, tctx->ev, tctx->lp_ctx,
+                                    ldb_url, NULL, NULL, 0);
+       torture_assert_goto(tctx, priv->ldb, bret, DONE,  "ldb_wrap_connect() failed");
+
+       /* set some schemaNamingContext */
+       ldb_err = ldb_set_opaque(priv->ldb,
+                                "schemaNamingContext",
+                                ldb_dn_new(priv->ldb, priv->ldb, "CN=Schema,CN=Config"));
+       torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE,
+                                     "ldb_set_opaque() failed");
+
+       /* add schemaInfo attribute so tested layer could work properly */
+       torture_assert_goto(tctx,
+                           _drsut_ldb_schema_info_reset(tctx, priv->ldb, SCHEMA_INFO_INIT_STR, true),
+                           bret, DONE,
+                           "_drsut_ldb_schema_info_reset() failed");
+
+DONE:
+       talloc_free(tempdir);
+       talloc_free(mem_ctx);
+       return bret;
+}
+
+/*
+ * Setup/Teardown for test case
+ */
+static bool torture_drs_unit_schemainfo_setup(struct torture_context *tctx,
+                                             struct drsut_schemainfo_data **_priv)
+{
+       int i;
+       int ldb_err;
+       NTSTATUS status;
+       DATA_BLOB ndr_blob;
+       struct GUID guid;
+       struct drsut_schemainfo_data *priv;
+
+       priv = talloc_zero(tctx, struct drsut_schemainfo_data);
+       torture_assert(tctx, priv, "Not enough memory!");
+
+       /* returned allocated pointer here
+        * teardown() will be called even in case of failure,
+        * so we'll get a changes to clean up  */
+       *_priv = priv;
+
+       /* create initial schemaInfo */
+       torture_assert(tctx,
+                      _drsut_schemainfo_new(tctx, SCHEMA_INFO_DEFAULT_STR, &priv->schema_info),
+                      "Failed to create schema_info test object");
+
+       /* create data to test with */
+       priv->test_data_count = ARRAY_SIZE(_schemainfo_test_data);
+       priv->test_data = talloc_array(tctx, struct schemainfo_data, priv->test_data_count);
+
+       for (i = 0; i < ARRAY_SIZE(_schemainfo_test_data); i++) {
+               struct schemainfo_data *data = &priv->test_data[i];
+
+               ndr_blob = strhex_to_data_blob(priv,
+                                              _schemainfo_test_data[i].schema_info_str);
+               torture_assert(tctx, ndr_blob.data, "Not enough memory!");
+
+               status = GUID_from_string(_schemainfo_test_data[i].guid_str, &guid);
+               torture_assert_ntstatus_ok(tctx, status,
+                                          talloc_asprintf(tctx,
+                                                          "GUID_from_string() failed for %s",
+                                                          _schemainfo_test_data[i].guid_str));
+
+               data->ndr_blob           = ndr_blob;
+               data->schi.invocation_id = guid;
+               data->schi.revision      = _schemainfo_test_data[i].revision;
+               data->werr_expected      = _schemainfo_test_data[i].werr_expected;
+               data->test_both_ways     = _schemainfo_test_data[i].test_both_ways;
+
+       }
+
+       /* create temporary LDB and populate with data */
+       if (!_drsut_ldb_setup(tctx, priv)) {
+               return false;
+       }
+
+       /* create ldb_module mockup object */
+       priv->ldb_module = ldb_module_new(priv, priv->ldb, "schemaInfo_test_module", NULL);
+       torture_assert(tctx, priv->ldb_module, "Not enough memory!");
+
+       /* create schema mockup object */
+       priv->schema = dsdb_new_schema(priv, lp_iconv_convenience(tctx->lp_ctx));
+
+       /* pre-cache invocationId for samdb_ntds_invocation_id()
+        * to work with our mock ldb */
+       ldb_err = ldb_set_opaque(priv->ldb, "cache.invocation_id",
+                                &priv->schema_info->invocation_id);
+       torture_assert_int_equal(tctx, ldb_err, LDB_SUCCESS, "ldb_set_opaque() failed");
+
+       /* Perform all tests in transactions so that
+        * underlying modify calls not to fail */
+       ldb_err = ldb_transaction_start(priv->ldb);
+       torture_assert_int_equal(tctx,
+                                ldb_err,
+                                LDB_SUCCESS,
+                                "ldb_transaction_start() failed");
+
+       return true;
+}
+
+static bool torture_drs_unit_schemainfo_teardown(struct torture_context *tctx,
+                                                struct drsut_schemainfo_data *priv)
+{
+       int ldb_err;
+
+       /* commit pending transaction so we will
+        * be able to check what LDB state is */
+       ldb_err = ldb_transaction_commit(priv->ldb);
+       if (ldb_err != LDB_SUCCESS) {
+               torture_comment(tctx, "ldb_transaction_commit() - %s (%s)",
+                               ldb_strerror(ldb_err),
+                               ldb_errstring(priv->ldb));
+       }
+
+       talloc_free(priv);
+
+       return true;
+}
+
+/**
+ * Test case initialization for
+ * DRS-UNIT.schemaInfo
+ */
+struct torture_tcase * torture_drs_unit_schemainfo(struct torture_suite *suite)
+{
+       typedef bool (*pfn_setup)(struct torture_context *, void **);
+       typedef bool (*pfn_teardown)(struct torture_context *, void *);
+       typedef bool (*pfn_run)(struct torture_context *, void *);
+
+       struct torture_tcase * tc = torture_suite_add_tcase(suite, "schemaInfo");
+
+       torture_tcase_set_fixture(tc,
+                                 (pfn_setup)torture_drs_unit_schemainfo_setup,
+                                 (pfn_teardown)torture_drs_unit_schemainfo_teardown);
+
+       tc->description = talloc_strdup(tc, "Unit tests for DRSUAPI::schemaInfo implementation");
+
+       torture_tcase_add_simple_test(tc, "dsdb_schema_info_from_blob",
+                                     (pfn_run)test_dsdb_schema_info_from_blob);
+       torture_tcase_add_simple_test(tc, "dsdb_blob_from_schema_info",
+                                     (pfn_run)test_dsdb_blob_from_schema_info);
+       torture_tcase_add_simple_test(tc, "dsdb_module_schema_info_blob read|write",
+                                     (pfn_run)test_dsdb_module_schema_info_blob_rw);
+       torture_tcase_add_simple_test(tc, "dsdb_schema_info_create",
+                                     (pfn_run)test_dsdb_schema_info_create);
+       torture_tcase_add_simple_test(tc, "dsdb_module_schema_info_update",
+                                     (pfn_run)test_dsdb_module_schema_info_update);
+
+
+       return tc;
+}