2 Unix SMB/CIFS implementation.
4 DRSUAPI schemaInfo unit tests
6 Copyright (C) Kamen Mazdrashki <kamenim@samba.org> 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "system/filesys.h"
24 #include "torture/smbtorture.h"
25 #include "dsdb/samdb/samdb.h"
26 #include "dsdb/samdb/ldb_modules/util.h"
28 #include "lib/ldb/include/ldb_module.h"
29 #include "torture/rpc/drsuapi.h"
30 #include "librpc/ndr/libndr.h"
31 #include "param/param.h"
35 * schemaInfo to init ldb context with
37 * GUID: 00000000-0000-0000-0000-000000000000
39 #define SCHEMA_INFO_INIT_STR "FF0000000000000000000000000000000000000000"
42 * Default schema_info string to be used for testing
44 * GUID: 071c82fd-45c7-4351-a3db-51f75a630a7f
46 #define SCHEMA_INFO_DEFAULT_STR "FF00000001FD821C07C7455143A3DB51F75A630A7F"
49 * Schema info data to test with
51 struct schemainfo_data
{
53 struct dsdb_schema_info schi
;
59 * Schema info test data in human-readable format (... kind of)
62 const char *schema_info_str
;
67 } _schemainfo_test_data
[] = {
69 .schema_info_str
= "FF0000000000000000000000000000000000000000",
71 .guid_str
= "00000000-0000-0000-0000-000000000000",
72 .werr_expected
= WERR_OK
,
73 .test_both_ways
= true
76 .schema_info_str
= "FF00000001FD821C07C7455143A3DB51F75A630A7F",
78 .guid_str
= "071c82fd-45c7-4351-a3db-51f75a630a7f",
79 .werr_expected
= WERR_OK
,
80 .test_both_ways
= true
83 .schema_info_str
= "FFFFFFFFFFFD821C07C7455143A3DB51F75A630A7F",
84 .revision
= 0xFFFFFFFF,
85 .guid_str
= "071c82fd-45c7-4351-a3db-51f75a630a7f",
86 .werr_expected
= WERR_OK
,
87 .test_both_ways
= true
90 .schema_info_str
= "FF00000001FD821C07C7455143A3DB51F75A630A7F00",
92 .guid_str
= "071c82fd-45c7-4351-a3db-51f75a630a7f",
93 .werr_expected
= WERR_INVALID_PARAMETER
,
94 .test_both_ways
= false
97 .schema_info_str
= "AA00000001FD821C07C7455143A3DB51F75A630A7F",
99 .guid_str
= "071c82fd-45c7-4351-a3db-51f75a630a7f",
100 .werr_expected
= WERR_INVALID_PARAMETER
,
101 .test_both_ways
= false
106 * Private data to be shared among all test in Test case
108 struct drsut_schemainfo_data
{
109 struct ldb_context
*ldb
;
110 struct ldb_module
*ldb_module
;
111 struct dsdb_schema
*schema
;
113 /* Initial schemaInfo set in ldb to test with */
114 struct dsdb_schema_info
*schema_info
;
116 uint32_t test_data_count
;
117 struct schemainfo_data
*test_data
;
121 * torture macro to assert for equal dsdb_schema_info's
123 #define torture_assert_schema_info_equal(torture_ctx,got,expected,cmt)\
124 do { const struct dsdb_schema_info *__got = (got), *__expected = (expected); \
125 if (__got->revision != __expected->revision) { \
126 torture_result(torture_ctx, TORTURE_FAIL, \
127 __location__": "#got".revision %d did not match "#expected".revision %d: %s", \
128 (int)__got->revision, (int)__expected->revision, cmt); \
131 if (!GUID_equal(&__got->invocation_id, &__expected->invocation_id)) { \
132 torture_result(torture_ctx, TORTURE_FAIL, \
133 __location__": "#got".invocation_id did not match "#expected".invocation_id: %s", cmt); \
139 * forward declaration for internal functions
141 static bool _drsut_ldb_schema_info_reset(struct torture_context
*tctx
,
142 struct ldb_context
*ldb
,
143 const char *schema_info_str
,
148 * Creates dsdb_schema_info object based on NDR data
149 * passed as hex string
151 static bool _drsut_schemainfo_new(struct torture_context
*tctx
,
152 const char *schema_info_str
, struct dsdb_schema_info
**_si
)
157 blob
= strhex_to_data_blob(tctx
, schema_info_str
);
159 torture_comment(tctx
, "Not enough memory!\n");
163 werr
= dsdb_schema_info_from_blob(&blob
, tctx
, _si
);
164 if (!W_ERROR_IS_OK(werr
)) {
165 torture_comment(tctx
,
166 "Failed to create dsdb_schema_info object for %s: %s",
172 data_blob_free(&blob
);
178 * Creates dsdb_schema_info object based on predefined data
179 * Function is public as it is intended to be used by other
180 * tests (e.g. prefixMap tests)
182 bool drsut_schemainfo_new(struct torture_context
*tctx
, struct dsdb_schema_info
**_si
)
184 return _drsut_schemainfo_new(tctx
, SCHEMA_INFO_DEFAULT_STR
, _si
);
189 * Tests dsdb_schema_info_new() and dsdb_schema_info_blob_new()
191 static bool test_dsdb_schema_info_new(struct torture_context
*tctx
,
192 struct drsut_schemainfo_data
*priv
)
196 DATA_BLOB ndr_blob_expected
;
197 struct dsdb_schema_info
*schi
;
200 mem_ctx
= talloc_new(priv
);
201 torture_assert(tctx
, mem_ctx
, "Not enough memory!");
202 ndr_blob_expected
= strhex_to_data_blob(mem_ctx
, SCHEMA_INFO_INIT_STR
);
203 torture_assert(tctx
, ndr_blob_expected
.data
, "Not enough memory!");
205 werr
= dsdb_schema_info_new(mem_ctx
, &schi
);
206 torture_assert_werr_ok(tctx
, werr
, "dsdb_schema_info_new() failed");
207 torture_assert_int_equal(tctx
, schi
->revision
, 0,
208 "dsdb_schema_info_new() creates schemaInfo with invalid revision");
209 torture_assert(tctx
, GUID_all_zero(&schi
->invocation_id
),
210 "dsdb_schema_info_new() creates schemaInfo with not ZERO GUID");
212 werr
= dsdb_schema_info_blob_new(mem_ctx
, &ndr_blob
);
213 torture_assert_werr_ok(tctx
, werr
, "dsdb_schema_info_blob_new() failed");
214 torture_assert_data_blob_equal(tctx
, ndr_blob
, ndr_blob_expected
,
215 "dsdb_schema_info_blob_new() returned invalid blob");
217 talloc_free(mem_ctx
);
222 * Tests dsdb_schema_info_from_blob()
224 static bool test_dsdb_schema_info_from_blob(struct torture_context
*tctx
,
225 struct drsut_schemainfo_data
*priv
)
230 struct dsdb_schema_info
*schema_info
;
233 mem_ctx
= talloc_new(priv
);
234 torture_assert(tctx
, mem_ctx
, "Not enough memory!");
236 for (i
= 0; i
< priv
->test_data_count
; i
++) {
237 struct schemainfo_data
*data
= &priv
->test_data
[i
];
239 msg
= talloc_asprintf(tctx
, "dsdb_schema_info_from_blob() [%d]-[%s]",
240 i
, _schemainfo_test_data
[i
].schema_info_str
);
242 werr
= dsdb_schema_info_from_blob(&data
->ndr_blob
, mem_ctx
, &schema_info
);
243 torture_assert_werr_equal(tctx
, werr
, data
->werr_expected
, msg
);
245 /* test returned data */
246 if (W_ERROR_IS_OK(werr
)) {
247 torture_assert_schema_info_equal(tctx
,
248 schema_info
, &data
->schi
,
249 "after dsdb_schema_info_from_blob() call");
253 talloc_free(mem_ctx
);
259 * Tests dsdb_blob_from_schema_info()
261 static bool test_dsdb_blob_from_schema_info(struct torture_context
*tctx
,
262 struct drsut_schemainfo_data
*priv
)
270 mem_ctx
= talloc_new(priv
);
271 torture_assert(tctx
, mem_ctx
, "Not enough memory!");
273 for (i
= 0; i
< priv
->test_data_count
; i
++) {
274 struct schemainfo_data
*data
= &priv
->test_data
[i
];
276 /* not all test are valid reverse type of conversion */
277 if (!data
->test_both_ways
) {
281 msg
= talloc_asprintf(tctx
, "dsdb_blob_from_schema_info() [%d]-[%s]",
282 i
, _schemainfo_test_data
[i
].schema_info_str
);
284 werr
= dsdb_blob_from_schema_info(&data
->schi
, mem_ctx
, &ndr_blob
);
285 torture_assert_werr_equal(tctx
, werr
, data
->werr_expected
, msg
);
287 /* test returned data */
288 if (W_ERROR_IS_OK(werr
)) {
289 torture_assert_data_blob_equal(tctx
,
290 ndr_blob
, data
->ndr_blob
,
291 "dsdb_blob_from_schema_info()");
295 talloc_free(mem_ctx
);
300 static bool test_dsdb_schema_info_cmp(struct torture_context
*tctx
,
301 struct drsut_schemainfo_data
*priv
)
304 struct drsuapi_DsReplicaOIDMapping_Ctr
*ctr
;
306 ctr
= talloc_zero(priv
, struct drsuapi_DsReplicaOIDMapping_Ctr
);
307 torture_assert(tctx
, ctr
, "Not enough memory!");
309 /* not enough elements */
310 torture_assert_werr_equal(tctx
,
311 dsdb_schema_info_cmp(priv
->schema
, ctr
),
312 WERR_INVALID_PARAMETER
,
313 "dsdb_schema_info_cmp(): unexpected result");
315 /* an empty element for schemaInfo */
316 ctr
->num_mappings
= 1;
317 ctr
->mappings
= talloc_zero_array(ctr
, struct drsuapi_DsReplicaOIDMapping
, 1);
318 torture_assert(tctx
, ctr
->mappings
, "Not enough memory!");
319 torture_assert_werr_equal(tctx
,
320 dsdb_schema_info_cmp(priv
->schema
, ctr
),
321 WERR_INVALID_PARAMETER
,
322 "dsdb_schema_info_cmp(): unexpected result");
324 /* test with invalid schemaInfo - length != 21 */
325 blob
= strhex_to_data_blob(ctr
, "FF00000001FD821C07C7455143A3DB51F75A630A7F00");
326 torture_assert(tctx
, blob
.data
, "Not enough memory!");
327 ctr
->mappings
[0].oid
.length
= blob
.length
;
328 ctr
->mappings
[0].oid
.binary_oid
= blob
.data
;
329 torture_assert_werr_equal(tctx
,
330 dsdb_schema_info_cmp(priv
->schema
, ctr
),
331 WERR_INVALID_PARAMETER
,
332 "dsdb_schema_info_cmp(): unexpected result");
334 /* test with invalid schemaInfo - marker != 0xFF */
335 blob
= strhex_to_data_blob(ctr
, "AA00000001FD821C07C7455143A3DB51F75A630A7F");
336 torture_assert(tctx
, blob
.data
, "Not enough memory!");
337 ctr
->mappings
[0].oid
.length
= blob
.length
;
338 ctr
->mappings
[0].oid
.binary_oid
= blob
.data
;
339 torture_assert_werr_equal(tctx
,
340 dsdb_schema_info_cmp(priv
->schema
, ctr
),
341 WERR_INVALID_PARAMETER
,
342 "dsdb_schema_info_cmp(): unexpected result");
344 /* test with valid schemaInfo, but not correct one */
345 blob
= strhex_to_data_blob(ctr
, "FF0000000000000000000000000000000000000000");
346 torture_assert(tctx
, blob
.data
, "Not enough memory!");
347 ctr
->mappings
[0].oid
.length
= blob
.length
;
348 ctr
->mappings
[0].oid
.binary_oid
= blob
.data
;
349 torture_assert_werr_equal(tctx
,
350 dsdb_schema_info_cmp(priv
->schema
, ctr
),
351 WERR_DS_DRA_SCHEMA_MISMATCH
,
352 "dsdb_schema_info_cmp(): unexpected result");
354 /* test with correct schemaInfo, but invalid ATTID */
355 blob
= strhex_to_data_blob(ctr
, priv
->schema
->schema_info
);
356 torture_assert(tctx
, blob
.data
, "Not enough memory!");
357 ctr
->mappings
[0].id_prefix
= 1;
358 ctr
->mappings
[0].oid
.length
= blob
.length
;
359 ctr
->mappings
[0].oid
.binary_oid
= blob
.data
;
360 torture_assert_werr_equal(tctx
,
361 dsdb_schema_info_cmp(priv
->schema
, ctr
),
362 WERR_INVALID_PARAMETER
,
363 "dsdb_schema_info_cmp(): unexpected result");
365 /* test with valid schemaInfo */
366 blob
= strhex_to_data_blob(ctr
, priv
->schema
->schema_info
);
367 ctr
->mappings
[0].id_prefix
= 0;
368 torture_assert_werr_ok(tctx
,
369 dsdb_schema_info_cmp(priv
->schema
, ctr
),
370 "dsdb_schema_info_cmp(): unexpected result");
377 * Tests dsdb_module_schema_info_blob_read()
378 * and dsdb_module_schema_info_blob_write()
380 static bool test_dsdb_module_schema_info_blob_rw(struct torture_context
*tctx
,
381 struct drsut_schemainfo_data
*priv
)
384 DATA_BLOB blob_write
;
387 /* reset schmeInfo to know value */
389 _drsut_ldb_schema_info_reset(tctx
, priv
->ldb
, SCHEMA_INFO_INIT_STR
, false),
390 "_drsut_ldb_schema_info_reset() failed");
392 /* write tests' default schemaInfo */
393 blob_write
= strhex_to_data_blob(priv
, SCHEMA_INFO_DEFAULT_STR
);
394 torture_assert(tctx
, blob_write
.data
, "Not enough memory!");
396 ldb_err
= dsdb_module_schema_info_blob_write(priv
->ldb_module
,
397 DSDB_FLAG_TOP_MODULE
,
399 torture_assert_int_equal(tctx
, ldb_err
, LDB_SUCCESS
, "dsdb_module_schema_info_blob_write() failed");
401 ldb_err
= dsdb_module_schema_info_blob_read(priv
->ldb_module
, DSDB_FLAG_TOP_MODULE
,
403 torture_assert_int_equal(tctx
, ldb_err
, LDB_SUCCESS
, "dsdb_module_schema_info_blob_read() failed");
405 /* check if we get what we wrote */
406 torture_assert_data_blob_equal(tctx
, blob_read
, blob_write
,
407 "Write/Read of schemeInfo blob failed");
413 * Tests dsdb_schema_update_schema_info()
415 static bool test_dsdb_module_schema_info_update(struct torture_context
*tctx
,
416 struct drsut_schemainfo_data
*priv
)
421 struct dsdb_schema_info
*schema_info
;
423 /* reset schmeInfo to know value */
425 _drsut_ldb_schema_info_reset(tctx
, priv
->ldb
, SCHEMA_INFO_INIT_STR
, false),
426 "_drsut_ldb_schema_info_reset() failed");
428 ldb_err
= dsdb_module_schema_info_update(priv
->ldb_module
,
430 DSDB_FLAG_TOP_MODULE
| DSDB_FLAG_AS_SYSTEM
);
431 torture_assert_int_equal(tctx
, ldb_err
, LDB_SUCCESS
, "dsdb_module_schema_info_update() failed");
433 /* get updated schemaInfo */
434 ldb_err
= dsdb_module_schema_info_blob_read(priv
->ldb_module
, DSDB_FLAG_TOP_MODULE
,
436 torture_assert_int_equal(tctx
, ldb_err
, LDB_SUCCESS
, "dsdb_module_schema_info_blob_read() failed");
438 werr
= dsdb_schema_info_from_blob(&blob
, priv
, &schema_info
);
439 torture_assert_werr_ok(tctx
, werr
, "dsdb_schema_info_from_blob() failed");
441 /* check against default schema_info */
442 torture_assert_schema_info_equal(tctx
, schema_info
, priv
->schema_info
,
443 "schemaInfo attribute no updated correctly");
450 * Reset schemaInfo record to know value
452 static bool _drsut_ldb_schema_info_reset(struct torture_context
*tctx
,
453 struct ldb_context
*ldb
,
454 const char *schema_info_str
,
460 struct ldb_message
*msg
;
461 TALLOC_CTX
*mem_ctx
= talloc_new(tctx
);
463 blob
= strhex_to_data_blob(mem_ctx
, schema_info_str
);
464 torture_assert_goto(tctx
, blob
.data
, bret
, DONE
, "Not enough memory!");
466 msg
= ldb_msg_new(mem_ctx
);
467 torture_assert_goto(tctx
, msg
, bret
, DONE
, "Not enough memory!");
469 msg
->dn
= ldb_get_schema_basedn(ldb
);
470 ldb_err
= ldb_msg_add_value(msg
, "schemaInfo", &blob
, NULL
);
471 torture_assert_int_equal_goto(tctx
, ldb_err
, LDB_SUCCESS
, bret
, DONE
,
472 "ldb_msg_add_value() failed");
475 ldb_err
= ldb_add(ldb
, msg
);
477 ldb_err
= dsdb_replace(ldb
, msg
, DSDB_MODIFY_PERMISSIVE
);
479 torture_assert_int_equal_goto(tctx
, ldb_err
, LDB_SUCCESS
, bret
, DONE
,
480 "dsdb_replace() failed");
483 talloc_free(mem_ctx
);
488 * Prepare temporary LDB and opens it
490 static bool _drsut_ldb_setup(struct torture_context
*tctx
, struct drsut_schemainfo_data
*priv
)
495 char *tempdir
= NULL
;
499 mem_ctx
= talloc_new(priv
);
500 torture_assert(tctx
, mem_ctx
, "Not enough memory!");
502 status
= torture_temp_dir(tctx
, "drs_", &tempdir
);
503 torture_assert_ntstatus_ok_goto(tctx
, status
, bret
, DONE
, "creating temp dir");
505 ldb_url
= talloc_asprintf(priv
, "%s/drs_schemainfo.ldb", tempdir
);
506 torture_assert_goto(tctx
, ldb_url
, bret
, DONE
, "Not enough memory!");
509 priv
->ldb
= ldb_wrap_connect(priv
, tctx
->ev
, tctx
->lp_ctx
,
510 ldb_url
, NULL
, NULL
, 0);
511 torture_assert_goto(tctx
, priv
->ldb
, bret
, DONE
, "ldb_wrap_connect() failed");
513 /* set some schemaNamingContext */
514 ldb_err
= ldb_set_opaque(priv
->ldb
,
515 "schemaNamingContext",
516 ldb_dn_new(priv
->ldb
, priv
->ldb
, "CN=Schema,CN=Config"));
517 torture_assert_int_equal_goto(tctx
, ldb_err
, LDB_SUCCESS
, bret
, DONE
,
518 "ldb_set_opaque() failed");
520 /* add schemaInfo attribute so tested layer could work properly */
521 torture_assert_goto(tctx
,
522 _drsut_ldb_schema_info_reset(tctx
, priv
->ldb
, SCHEMA_INFO_INIT_STR
, true),
524 "_drsut_ldb_schema_info_reset() failed");
527 talloc_free(tempdir
);
528 talloc_free(mem_ctx
);
533 * Setup/Teardown for test case
535 static bool torture_drs_unit_schemainfo_setup(struct torture_context
*tctx
,
536 struct drsut_schemainfo_data
**_priv
)
543 struct drsut_schemainfo_data
*priv
;
545 priv
= talloc_zero(tctx
, struct drsut_schemainfo_data
);
546 torture_assert(tctx
, priv
, "Not enough memory!");
548 /* returned allocated pointer here
549 * teardown() will be called even in case of failure,
550 * so we'll get a changes to clean up */
553 /* create initial schemaInfo */
555 _drsut_schemainfo_new(tctx
, SCHEMA_INFO_DEFAULT_STR
, &priv
->schema_info
),
556 "Failed to create schema_info test object");
558 /* create data to test with */
559 priv
->test_data_count
= ARRAY_SIZE(_schemainfo_test_data
);
560 priv
->test_data
= talloc_array(tctx
, struct schemainfo_data
, priv
->test_data_count
);
562 for (i
= 0; i
< ARRAY_SIZE(_schemainfo_test_data
); i
++) {
563 struct schemainfo_data
*data
= &priv
->test_data
[i
];
565 ndr_blob
= strhex_to_data_blob(priv
,
566 _schemainfo_test_data
[i
].schema_info_str
);
567 torture_assert(tctx
, ndr_blob
.data
, "Not enough memory!");
569 status
= GUID_from_string(_schemainfo_test_data
[i
].guid_str
, &guid
);
570 torture_assert_ntstatus_ok(tctx
, status
,
571 talloc_asprintf(tctx
,
572 "GUID_from_string() failed for %s",
573 _schemainfo_test_data
[i
].guid_str
));
575 data
->ndr_blob
= ndr_blob
;
576 data
->schi
.invocation_id
= guid
;
577 data
->schi
.revision
= _schemainfo_test_data
[i
].revision
;
578 data
->werr_expected
= _schemainfo_test_data
[i
].werr_expected
;
579 data
->test_both_ways
= _schemainfo_test_data
[i
].test_both_ways
;
583 /* create temporary LDB and populate with data */
584 if (!_drsut_ldb_setup(tctx
, priv
)) {
588 /* create ldb_module mockup object */
589 priv
->ldb_module
= ldb_module_new(priv
, priv
->ldb
, "schemaInfo_test_module", NULL
);
590 torture_assert(tctx
, priv
->ldb_module
, "Not enough memory!");
592 /* create schema mockup object */
593 priv
->schema
= dsdb_new_schema(priv
);
595 /* set schema_info in dsdb_schema for testing */
596 priv
->schema
->schema_info
= talloc_strdup(priv
->schema
, SCHEMA_INFO_DEFAULT_STR
);
598 /* pre-cache invocationId for samdb_ntds_invocation_id()
599 * to work with our mock ldb */
600 ldb_err
= ldb_set_opaque(priv
->ldb
, "cache.invocation_id",
601 &priv
->schema_info
->invocation_id
);
602 torture_assert_int_equal(tctx
, ldb_err
, LDB_SUCCESS
, "ldb_set_opaque() failed");
604 /* Perform all tests in transactions so that
605 * underlying modify calls not to fail */
606 ldb_err
= ldb_transaction_start(priv
->ldb
);
607 torture_assert_int_equal(tctx
,
610 "ldb_transaction_start() failed");
615 static bool torture_drs_unit_schemainfo_teardown(struct torture_context
*tctx
,
616 struct drsut_schemainfo_data
*priv
)
620 /* commit pending transaction so we will
621 * be able to check what LDB state is */
622 ldb_err
= ldb_transaction_commit(priv
->ldb
);
623 if (ldb_err
!= LDB_SUCCESS
) {
624 torture_comment(tctx
, "ldb_transaction_commit() - %s (%s)",
625 ldb_strerror(ldb_err
),
626 ldb_errstring(priv
->ldb
));
635 * Test case initialization for
636 * drs.unit.schemaInfo
638 struct torture_tcase
* torture_drs_unit_schemainfo(struct torture_suite
*suite
)
640 typedef bool (*pfn_setup
)(struct torture_context
*, void **);
641 typedef bool (*pfn_teardown
)(struct torture_context
*, void *);
642 typedef bool (*pfn_run
)(struct torture_context
*, void *);
644 struct torture_tcase
* tc
= torture_suite_add_tcase(suite
, "schemaInfo");
646 torture_tcase_set_fixture(tc
,
647 (pfn_setup
)torture_drs_unit_schemainfo_setup
,
648 (pfn_teardown
)torture_drs_unit_schemainfo_teardown
);
650 tc
->description
= talloc_strdup(tc
, "Unit tests for DRSUAPI::schemaInfo implementation");
652 torture_tcase_add_simple_test(tc
, "dsdb_schema_info_new",
653 (pfn_run
)test_dsdb_schema_info_new
);
654 torture_tcase_add_simple_test(tc
, "dsdb_schema_info_from_blob",
655 (pfn_run
)test_dsdb_schema_info_from_blob
);
656 torture_tcase_add_simple_test(tc
, "dsdb_blob_from_schema_info",
657 (pfn_run
)test_dsdb_blob_from_schema_info
);
658 torture_tcase_add_simple_test(tc
, "dsdb_schema_info_cmp",
659 (pfn_run
)test_dsdb_schema_info_cmp
);
660 torture_tcase_add_simple_test(tc
, "dsdb_module_schema_info_blob read|write",
661 (pfn_run
)test_dsdb_module_schema_info_blob_rw
);
662 torture_tcase_add_simple_test(tc
, "dsdb_module_schema_info_update",
663 (pfn_run
)test_dsdb_module_schema_info_update
);