2 from unittest
import TestCase
4 from subprocess
import check_output
13 dir_prefix
= os
.path
.join(os
.environ
["SELFTEST_PREFIX"], "tmp")
16 return tempfile
.mkdtemp(dir=dir_prefix
)
19 # Check enabling and disabling GUID indexing works and that the database is
20 # repacked at version 2 if GUID indexing is enabled, or version 1 if disabled.
21 class GUIDIndexAndPackFormatTests(TestCase
):
24 def setup_newdb(self
):
25 self
.testdir
= tempdir()
26 self
.filename
= os
.path
.join(self
.testdir
,
27 "guidpackformattest.ldb")
28 url
= self
.prefix
+ self
.filename
29 self
.l
= ldb
.Ldb(url
, options
=["modules:"])
31 self
.num_recs_added
= 0
33 #guidindexpackv1.ldb is a pre-made database packed with version 1 format
34 #but with GUID indexing enabled, which is not allowed, so Samba should
35 #repack the database on the first transaction.
36 def setup_premade_v1_db(self
):
37 db_name
= "guidindexpackv1.ldb"
38 this_file_dir
= os
.path
.dirname(os
.path
.abspath(__file__
))
39 db_path
= os
.path
.join(this_file_dir
, "../", db_name
)
40 self
.testdir
= tempdir()
41 self
.filename
= os
.path
.join(self
.testdir
, db_name
)
43 shutil
.copy(db_path
, self
.filename
)
45 url
= self
.prefix
+ self
.filename
46 self
.l
= ldb
.Ldb(url
, options
=["modules:"])
47 self
.num_recs_added
= 10
50 if hasattr(self
, 'testdir'):
51 shutil
.rmtree(self
.testdir
)
53 def add_one_rec(self
):
54 ouuid
= 0x0123456789abcdef + self
.num_recs_added
55 ouuid_s
= '0' + hex(ouuid
)[2:]
56 dn
= "OU=GUIDPFTEST{},DC=SAMBA,DC=ORG".format(self
.num_recs_added
)
57 rec
= {"dn": dn
, "objectUUID": ouuid_s
, "distinguishedName": dn
}
59 self
.num_recs_added
+= 1
61 # Turn GUID back into a str for easier comparisons
64 def set_guid_indexing(self
, enable
=True):
65 modmsg
= ldb
.Message()
66 modmsg
.dn
= ldb
.Dn(self
.l
, '@INDEXLIST')
68 attrs
= {"@IDXGUID": [b
"objectUUID"],
69 "@IDX_DN_GUID": [b
"GUID"]}
70 for attr
, val
in attrs
.items():
71 replace
= ldb
.FLAG_MOD_REPLACE
72 el
= val
if enable
else []
73 el
= ldb
.MessageElement(elements
=el
, flags
=replace
, name
=attr
)
78 # Parse out the comments above each record that ldbdump produces
79 # containing pack format version and KV level key for each record.
80 # Return all GUID index keys and the set of all unique pack formats.
81 def ldbdump_guid_keys_pack_formats(self
):
82 dump
= check_output(["bin/ldbdump", "-i", self
.filename
])
83 dump
= dump
.decode("utf-8")
84 dump
= dump
.split("\n")
86 comments
= [s
for s
in dump
if s
.startswith("#")]
88 guid_key_tag
= "# key: GUID="
89 guid_keys
= {c
[len(guid_key_tag
):] for c
in comments
90 if c
.startswith(guid_key_tag
)}
92 pack_format_tag
= "# pack format: "
93 pack_formats
= {c
[len(pack_format_tag
):] for c
in comments
94 if c
.startswith(pack_format_tag
)}
95 pack_formats
= [int(s
, 16) for s
in pack_formats
]
97 return guid_keys
, pack_formats
99 # Put the whole database in a dict so we can easily check the database
101 def get_database(self
):
102 recs
= self
.l
.search(base
="", scope
=ldb
.SCOPE_SUBTREE
, expression
="")
106 self
.assertNotIn(dn
, db
)
110 db
[dn
][k
] = str(r
.get(k
))
113 # Toggle GUID indexing on and off a few times, and check that when GUID
114 # indexing is enabled, the database is repacked to pack format V2, and
115 # when GUID indexing is disabled again, the database is repacked with
117 def toggle_guidindex_check_pack(self
):
118 expect_db
= self
.get_database()
120 for enable
in [False, False, True, False, True, True, False]:
121 pf
= ldb
.PACKING_FORMAT_V2
if enable
else ldb
.PACKING_FORMAT
123 self
.set_guid_indexing(enable
=enable
)
125 guid_keys
, pack_formats
= self
.ldbdump_guid_keys_pack_formats()
126 num_guid_keys
= self
.num_recs_added
if enable
else 0
127 self
.assertEqual(len(guid_keys
), num_guid_keys
)
128 self
.assertEqual(pack_formats
, [pf
])
129 self
.assertEqual(self
.get_database(), expect_db
)
131 rec
= self
.add_one_rec()
132 expect_db
[rec
['dn']] = rec
134 guid_keys
, pack_formats
= self
.ldbdump_guid_keys_pack_formats()
135 num_guid_keys
= self
.num_recs_added
if enable
else 0
136 self
.assertEqual(len(guid_keys
), num_guid_keys
)
137 self
.assertEqual(pack_formats
, [pf
])
138 self
.assertEqual(self
.get_database(), expect_db
)
140 # Check a newly created database is initially packed at V1, then is
141 # repacked at V2 when GUID indexing is enabled.
142 def test_repack(self
):
145 guid_keys
, pack_formats
= self
.ldbdump_guid_keys_pack_formats()
146 self
.assertEqual(len(guid_keys
), 0)
147 self
.assertEqual(pack_formats
, [ldb
.PACKING_FORMAT
])
148 self
.assertEqual(self
.get_database(), {})
150 self
.l
.add({"dn": "@ATTRIBUTES"})
152 guid_keys
, pack_formats
= self
.ldbdump_guid_keys_pack_formats()
153 self
.assertEqual(len(guid_keys
), 0)
154 self
.assertEqual(pack_formats
, [ldb
.PACKING_FORMAT
])
155 self
.assertEqual(self
.get_database(), {})
157 self
.l
.add({"dn": "@INDEXLIST",
159 "@IDXGUID": [b
"objectUUID"],
160 "@IDX_DN_GUID": [b
"GUID"]})
162 guid_keys
, pack_formats
= self
.ldbdump_guid_keys_pack_formats()
163 self
.assertEqual(len(guid_keys
), 0)
164 self
.assertEqual(pack_formats
, [ldb
.PACKING_FORMAT_V2
])
165 self
.assertEqual(self
.get_database(), {})
167 rec
= self
.add_one_rec()
168 expect_db
= {rec
["dn"]: rec
}
170 guid_keys
, pack_formats
= self
.ldbdump_guid_keys_pack_formats()
171 self
.assertEqual(len(guid_keys
), 1)
172 self
.assertEqual(pack_formats
, [ldb
.PACKING_FORMAT_V2
])
173 self
.assertEqual(self
.get_database(), expect_db
)
175 self
.toggle_guidindex_check_pack()
177 # Check a database with V1 format with GUID indexing enabled is repacked
178 # with version 2 format.
179 def test_guid_indexed_v1_db(self
):
180 self
.setup_premade_v1_db()
182 expect_db
= self
.get_database()
184 guid_keys
, pack_formats
= self
.ldbdump_guid_keys_pack_formats()
185 self
.assertEqual(len(guid_keys
), self
.num_recs_added
)
186 self
.assertEqual(pack_formats
, [ldb
.PACKING_FORMAT
])
187 self
.assertEqual(self
.get_database(), expect_db
)
189 rec
= self
.add_one_rec()
190 expect_db
[rec
['dn']] = rec
192 guid_keys
, pack_formats
= self
.ldbdump_guid_keys_pack_formats()
193 self
.assertEqual(len(guid_keys
), self
.num_recs_added
)
194 self
.assertEqual(pack_formats
, [ldb
.PACKING_FORMAT_V2
])
195 self
.assertEqual(self
.get_database(), expect_db
)
197 self
.toggle_guidindex_check_pack()
200 if __name__
== '__main__':
204 unittest
.TestProgram()