774219a1ab673e32363cd05ff8c9367023895caa
[samba.git] / testprogs / ejs / ldb.js
1 #!/bin/sh
2 exec smbscript "$0" ${1+"$@"}
3 /*
4         demonstrate access to ldb databases from ejs
5 */
6
7
8 var ldb = ldb_init();
9 var sys;
10 var options = GetOptions(ARGV, 
11                 "POPT_AUTOHELP",
12                 "POPT_COMMON_SAMBA");
13 if (options == undefined) {
14    println("Failed to parse options");
15    return -1;
16 }
17
18 libinclude("base.js");
19
20 if (options.ARGV.length != 1) {
21    println("Usage: ldb.js <prefix>");
22    return -1;
23 }
24
25 prefix = options.ARGV[0];
26
27 function basic_tests(ldb)
28 {
29         println("Running basic tests");
30         ok = ldb.add("
31 dn: cn=x,cn=test
32 objectClass: foo
33 x: 3
34 ");
35         assert(ok.error == 0);
36
37         println("Testing ldb.search");
38         var res = ldb.search("(objectClass=*)");
39         assert(res.msgs[0].objectClass[0] == "foo");
40         assert(res.msgs[0].dn == "cn=x,cn=test");
41         assert(res.msgs[0].x == 3);
42
43         ok = ldb.add("
44 dn: cn=x2,cn=test
45 objectClass: foo
46 x: 4
47 ");
48         assert(ok.error == 0);
49         var attrs = new Array("x");
50         res = ldb.search("x=4", NULL, ldb.SCOPE_DEFAULT, attrs);
51         assert(res.msgs[0].x == 4);
52         assert(res.msgs[0].objectClass == undefined);
53         assert(res.msgs[0].dn == "cn=x2,cn=test");
54
55         ok = ldb.del("cn=x,cn=test");
56         assert(ok.error == 0);
57
58         ok = ldb.rename("cn=x2,cn=test", "cn=x3,cn=test");
59         assert(ok.error == 0);
60         res = ldb.search("x=4", NULL, ldb.SCOPE_DEFAULT, attrs);
61         assert(res.msgs[0].dn == "cn=x3,cn=test");
62
63         ok = ldb.modify("
64 dn: cn=x3,cn=test
65 changetype: modify
66 add: x
67 x: 7
68 ");
69
70         res = ldb.search("x=7");
71         assert(res.msgs.length == 1);
72         assert(res.msgs[0].x.length == 2);
73
74         /* Check a few things before we add modules */
75         assert(res.msgs[0].objectGUID == undefined);
76         assert(res.msgs[0].createTimestamp == undefined);
77         assert(res.msgs[0].whenCreated == undefined);
78
79 }
80         
81 function setup_modules(ldb)
82 {
83         ok = ldb.add("
84 dn: @MODULES
85 @LIST: rootdse,operational,rdn_name,partition
86
87 dn: cn=ROOTDSE
88 defaultNamingContext: cn=Test
89
90 dn: @PARTITION
91 partition: cn=SideTest:" + prefix + "/" + "testside.ldb
92 partition: cn=Sub,cn=PartTest:" + prefix + "/" + "testsub.ldb
93 partition: cn=PartTest:" + prefix + "/" + "testpartition.ldb
94 partition: cn=Sub,cn=Sub,cn=PartTest:" + prefix + "/" + "testsubsub.ldb
95 replicateEntries: @SUBCLASSES
96 replicateEntries: @ATTRIBUTES
97 replicateEntries: @INDEXLIST
98 modules: cn=PartTest:objectguid
99 ");
100 }
101
102 /* Test the basic operation of the timestamps,objectguid and name_rdn
103    modules */
104
105 function modules_test(ldb, parttestldb) 
106 {
107         println("Running modules tests");
108
109         ok = ldb.add("
110 dn: @ATTRIBUTES
111 cn: CASE_INSENSITIVE
112 caseattr: CASE_INSENSITIVE
113 ");
114         if (ok.error != 0) {
115                 println("Failed to add: " + ok.errstr);
116                 assert(ok.error == 0);
117         }
118
119         /* Confirm that the attributes were replicated */
120         var res_attrs =  parttestldb.search("cn=*", "@ATTRIBUTES",  parttestldb.SCOPE_BASE);
121         assert(res_attrs.msgs[0].cn == "CASE_INSENSITIVE");
122
123         ok = ldb.add("
124 dn: cn=x8,cn=PartTest
125 objectClass: foo
126 x: 8
127 ");
128         if (ok.error != 0) {
129                 println("Failed to add: " + ok.errstr);
130                 assert(ok.error == 0);
131         }
132
133         ok = ldb.add("
134 dn: cn=x9,cn=PartTest
135 objectClass: foo
136 x: 9
137 cn: X9
138 ");
139         if (ok.error != 0) {
140                 println("Failed to add: " + ok.errstr);
141                 assert(ok.error == 0);
142         }
143
144         ok = ldb.add("
145 dn: cn=X9,cn=PartTest
146 objectClass: foo
147 x: 9
148 cn: X9
149 ");
150         if (ok.error == 0) {
151                 println("Should have failed to add cn=X9,cn=PartTest");
152                 assert(ok.error != 0);
153         }
154
155         var res = ldb.search("x=8", "cn=PartTest", ldb.SCOPE_DEFAULT);
156         assert(res.msgs[0].objectGUID != undefined);
157         assert(res.msgs[0].uSNCreated != undefined);
158         assert(res.msgs[0].uSNChanged != undefined);
159         assert(res.msgs[0].createTimestamp == undefined);
160         assert(res.msgs[0].whenCreated != undefined);
161         assert(res.msgs[0].name == "x8");
162         assert(res.msgs[0].cn == "x8");
163
164         /* Confirm that this ended up in the correct LDB */
165         var res_otherldb =  parttestldb.search("x=8", "cn=PartTest",  parttestldb.SCOPE_DEFAULT);
166         assert(res_otherldb.msgs[0].objectGUID != undefined);
167         assert(res_otherldb.msgs[0].createTimestamp == undefined);
168         assert(res_otherldb.msgs[0].whenCreated != undefined);
169         assert(res_otherldb.msgs[0].name == "x8");
170         assert(res_otherldb.msgs[0].cn == "x8");
171
172         var attrs = new Array("*", "createTimestamp");
173         var res2 = ldb.search("x=9", "cn=PartTest", ldb.SCOPE_DEFAULT, attrs);
174         assert(res2.msgs[0].objectGUID != undefined);
175         assert(res2.msgs[0].createTimestamp != undefined);
176         assert(res2.msgs[0].whenCreated != undefined);
177         assert(res2.msgs[0].name == "x9");
178         assert(res2.msgs[0].cn == "x9");
179
180         assert(res.msgs[0].objectGUID != res2.msgs[0].objectGUID);
181
182         var attrs = new Array("*");
183         var res3 = ldb.search("", "", ldb.SCOPE_BASE, attrs);
184         assert(res3.msgs[0].cn == undefined);
185         assert(res3.msgs[0].distinguishedName == undefined);
186         assert(res3.msgs[0].name == undefined);
187         assert(res3.msgs[0].currentTime != undefined);
188         assert(res3.msgs[0].highestCommittedUSN != undefined);
189
190         assert(res3.msgs[0].namingContexts[0] == "cn=Sub,cn=Sub,cn=PartTest");
191         assert(res3.msgs[0].namingContexts[1] == "cn=Sub,cn=PartTest");
192         assert(res3.msgs[0].namingContexts[2] == "cn=PartTest");
193         assert(res3.msgs[0].namingContexts[3] == "cn=SideTest");
194         var usn = res3.msgs[0].highestCommittedUSN;
195
196         /* Start a transaction.  We are going to abort it later, to
197          * show we clean up all partitions */
198
199         ok = ldb.transaction_start()
200         if (!ok) {
201                 println("Failed to start a transaction: " + ok.errstr);
202                 assert(ok.error == 0);
203         }
204
205         
206         ok = ldb.add("
207 dn: cn=x10,cn=parttest
208 objectClass: foo
209 x: 10
210 ");
211         if (ok.error != 0) {
212                 println("Failed to add: " + ok.errstr);
213                 assert(ok.error == 0);
214         }
215
216         var attrs = new Array("highestCommittedUSN");
217         var res4 = ldb.search("", "", ldb.SCOPE_BASE, attrs);
218         var usn2 = res4.msgs[0].highestCommittedUSN;
219         assert(usn < res4.msgs[0].highestCommittedUSN);
220
221         ok = ldb.add("
222 dn: cn=x11,cn=sub,cn=parttest
223 objectClass: foo
224 x: 11
225 ");
226         if (ok.error != 0) {
227                 println("Failed to add: " + ok.errstr);
228                 assert(ok.error == 0);
229         }
230
231         var attrs = new Array("highestCommittedUSN");
232         var res5 = ldb.search("", "", ldb.SCOPE_BASE, attrs);
233         assert(usn2 < res5.msgs[0].highestCommittedUSN);
234         
235         var attrs = new Array("*", "createTimestamp");
236         var res6 = ldb.search("x=11", "cn=parttest", ldb.SCOPE_SUB, attrs);
237         assert(res6.msgs.length == 0);
238
239         var attrs = new Array("*", "createTimestamp");
240         var res7 = ldb.search("x=10", "cn=sub,cn=parttest", ldb.SCOPE_DEFAULT, attrs);
241         assert(res7.msgs.length == 0);
242
243         var res8 = ldb.search("x=11", "cn=sub,cn=parttest", ldb.SCOPE_DEFAULT, attrs);
244         
245         assert(res8.msgs[0].objectGUID == undefined); /* The objectGUID module is not loaded here */
246         assert(res8.msgs[0].uSNCreated == undefined); /* The objectGUID module is not loaded here */
247         assert(res8.msgs[0].name == "x11");
248         assert(res8.msgs[0].cn == "x11");
249
250         ok = ldb.add("
251 dn: caseattr=XY,cn=PartTest
252 objectClass: foo
253 x: Y
254 ");
255         if (ok.error != 0) {
256                 println("Failed to add: " + ok.errstr);
257                 assert(ok.error == 0);
258         }
259
260         ok = ldb.add("
261 dn: caseattr=XZ,cn=PartTest
262 objectClass: foo
263 x: Z
264 caseattr: XZ
265 ");
266         if (ok.error != 0) {
267                 println("Failed to add: " + ok.errstr);
268                 assert(ok.error == 0);
269         }
270
271         ok = ldb.add("
272 dn: caseattr=xz,cn=PartTest
273 objectClass: foo
274 x: Z
275 caseattr: xz
276 ");
277         if (ok.error == 0) {
278                 println("Should have failed to add caseattr=xz,cn=PartTest");
279                 assert(ok.error != 0);
280         }
281
282         ok = ldb.add("
283 dn: caseattr2=XZ,cn=PartTest
284 objectClass: foo
285 x: Z
286 caseattr2: XZ
287 ");
288         if (ok.error != 0) {
289                 println("Failed to add: " + ok.errstr);
290                 assert(ok.error == 0);
291         }
292
293         ok = ldb.add("
294 dn: caseattr2=Xz,cn=PartTest
295 objectClass: foo
296 x: Z
297 caseattr2: Xz
298 ");
299         if (ok.error != 0) {
300                 println("Failed to add: " + ok.errstr);
301                 assert(ok.error == 0);
302         }
303
304         var resX = ldb.search("caseattr=xz", "cn=parttest", ldb.SCOPE_DEFAULT, attrs);
305         assert(resX.msgs.length == 1); 
306         assert(resX.msgs[0].objectGUID != undefined);
307         assert(resX.msgs[0].createTimestamp != undefined);
308         assert(resX.msgs[0].whenCreated != undefined);
309         assert(resX.msgs[0].name == "XZ");
310
311         var rescount = ldb.search("(|(caseattr=*)(cn=*))", "cn=parttest", ldb.SCOPE_DEFAULT, attrs);
312         assert(rescount.msgs.length == 5); 
313
314         /* Check this attribute is *not* case sensitive */
315         var resXcount = ldb.search("caseattr=x*", "cn=parttest", ldb.SCOPE_DEFAULT, attrs);
316         assert(resXcount.msgs.length == 2); 
317         
318         /* Check that this attribute *is* case sensitive */
319         var resXcount2 = ldb.search("caseattr2=xz", "cn=parttest", ldb.SCOPE_DEFAULT, attrs);
320         assert(resXcount2.msgs.length == 0); 
321         
322
323         /* Now abort the transaction to show that even with
324          * partitions, it is aborted everywhere */
325         ok = ldb.transaction_cancel();
326         if (!ok) {
327                 println("Failed to cancel a transaction: " + ok.errstr);
328                 assert(ok);
329         }
330
331         /* now check it all went away */
332
333         var attrs = new Array("highestCommittedUSN");
334         var res9 = ldb.search("", "", ldb.SCOPE_BASE, attrs);
335         assert(usn == res9.msgs[0].highestCommittedUSN);
336         
337         var attrs = new Array("*");
338         var res10 = ldb.search("x=11", "cn=sub,cn=parttest", ldb.SCOPE_DEFAULT, attrs);
339         assert(res10.msgs.length == 0);
340
341         var attrs = new Array("*");
342         var res11 = ldb.search("x=10", "cn=parttest", ldb.SCOPE_DEFAULT, attrs);
343         assert(res11.msgs.length == 0);
344
345         var attrs = new Array("*");
346         var res12 = ldb.search("caseattr=*", "cn=parttest", ldb.SCOPE_DEFAULT, attrs);
347         assert(res12.msgs.length == 0);
348
349 }
350
351 sys = sys_init();
352 var dbfile = "test.ldb";
353
354 sys.unlink(prefix + "/" + dbfile);
355 sys.unlink(prefix + "/" + "testpartition.ldb");
356 sys.unlink(prefix + "/" + "testsub.ldb");
357 sys.unlink(prefix + "/" + "testsubsub.ldb");
358 sys.unlink(prefix + "/" + "testside.ldb");
359
360 var ok = ldb.connect("tdb://" + prefix + "/" + dbfile);
361 assert(ok);
362
363 basic_tests(ldb);
364
365 setup_modules(ldb);
366 ldb = ldb_init();
367 var ok = ldb.connect("tdb://" + prefix + "/" + dbfile);
368 assert(ok);
369
370 parttestldb = ldb_init();
371 var ok = parttestldb.connect("tdb://" + prefix + "/" + "testpartition.ldb");
372 assert(ok);
373
374 modules_test(ldb, parttestldb);
375
376 sys.unlink(prefix + "/" + dbfile);
377 sys.unlink(prefix + "/" + "testpartition.ldb");
378 sys.unlink(prefix + "/" + "testsub.ldb");
379 sys.unlink(prefix + "/" + "testsubsub.ldb");
380 sys.unlink(prefix + "/" + "testside.ldb");
381 return 0;