2 Unix SMB/CIFS implementation.
4 local testing of registry library - registry backend
6 Copyright (C) Jelmer Vernooij 2005-2007
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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "lib/registry/registry.h"
25 #include "lib/cmdline/popt_common.h"
26 #include "torture/torture.h"
27 #include "librpc/gen_ndr/winreg.h"
28 #include "system/filesys.h"
30 NTSTATUS torture_temp_dir(struct torture_context *tctx, const char *prefix,
31 const char **tempdir);
34 * Test obtaining a predefined key.
36 static bool test_get_predefined(struct torture_context *tctx,
39 const struct registry_context *rctx = _data;
40 struct registry_key *root;
43 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
44 torture_assert_werr_ok(tctx, error,
45 "getting predefined key failed");
50 * Test obtaining a predefined key.
52 static bool test_get_predefined_unknown(struct torture_context *tctx,
55 const struct registry_context *rctx = _data;
56 struct registry_key *root;
59 error = reg_get_predefined_key(rctx, 1337, &root);
60 torture_assert_werr_equal(tctx, error, WERR_BADFILE,
61 "getting predefined key failed");
66 * Test creating a new subkey
68 static bool test_create_subkey(struct torture_context *tctx,
71 const struct registry_context *rctx = _data;
72 struct registry_key *root, *newkey;
75 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
76 torture_assert_werr_ok(tctx, error,
77 "getting predefined key failed");
79 error = reg_key_add_name(rctx, root, "Bad Bentheim", NULL, NULL, &newkey);
80 torture_assert_werr_ok(tctx, error, "Creating key return code");
81 torture_assert(tctx, newkey != NULL, "Creating new key");
87 * Test creating a new nested subkey
89 static bool test_create_nested_subkey(struct torture_context *tctx,
92 const struct registry_context *rctx = _data;
93 struct registry_key *root, *newkey1, *newkey2;
96 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
97 torture_assert_werr_ok(tctx, error,
98 "getting predefined key failed");
100 error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL,
102 torture_assert_werr_ok(tctx, error, "Creating key return code");
103 torture_assert(tctx, newkey2 != NULL, "Creating new key");
105 error = reg_key_add_name(rctx, root, "Hamburg\\Hamburg", NULL, NULL,
107 torture_assert_werr_ok(tctx, error, "Creating key return code");
108 torture_assert(tctx, newkey2 != NULL, "Creating new key");
114 * Test creating a new subkey
116 static bool test_key_add_abs_top(struct torture_context *tctx,
119 const struct registry_context *rctx = _data;
120 struct registry_key *root;
123 error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT", 0, NULL, &root);
124 torture_assert_werr_equal(tctx, error, WERR_ALREADY_EXISTS, "create top level");
130 * Test creating a new subkey
132 static bool test_key_add_abs(struct torture_context *tctx,
136 const struct registry_context *rctx = _data;
137 struct registry_key *root, *result1, *result2;
139 error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe", 0, NULL, &result1);
140 torture_assert_werr_ok(tctx, error, "create lowest");
142 error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe\\bla", 0, NULL, &result1);
143 torture_assert_werr_ok(tctx, error, "create nested");
145 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
146 torture_assert_werr_ok(tctx, error,
147 "getting predefined key failed");
149 error = reg_open_key(tctx, root, "bloe", &result2);
150 torture_assert_werr_ok(tctx, error, "opening key");
152 error = reg_open_key(tctx, root, "bloe\\bla", &result2);
153 torture_assert_werr_ok(tctx, error, "opening key");
159 static bool test_del_key(struct torture_context *tctx, const void *_data)
161 const struct registry_context *rctx = _data;
162 struct registry_key *root, *newkey;
165 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
166 torture_assert_werr_ok(tctx, error,
167 "getting predefined key failed");
169 error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL, &newkey);
171 torture_assert_werr_ok(tctx, error, "Creating key return code");
172 torture_assert(tctx, newkey != NULL, "Creating new key");
174 error = reg_key_del(root, "Hamburg");
175 torture_assert_werr_ok(tctx, error, "Delete key");
177 error = reg_key_del(root, "Hamburg");
178 torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND,
179 "Delete missing key");
185 * Convenience function for opening the HKEY_CLASSES_ROOT hive and
186 * creating a single key for testing purposes.
188 static bool create_test_key(struct torture_context *tctx,
189 const struct registry_context *rctx,
191 struct registry_key **root,
192 struct registry_key **subkey)
196 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, root);
197 torture_assert_werr_ok(tctx, error,
198 "getting predefined key failed");
200 error = reg_key_add_name(rctx, *root, name, NULL, NULL, subkey);
201 torture_assert_werr_ok(tctx, error, "Creating key return code");
207 static bool test_flush_key(struct torture_context *tctx, const void *_data)
209 const struct registry_context *rctx = _data;
210 struct registry_key *root, *subkey;
213 if (!create_test_key(tctx, rctx, "Munchen", &root, &subkey))
216 error = reg_key_flush(subkey);
217 torture_assert_werr_ok(tctx, error, "flush key");
219 torture_assert_werr_equal(tctx, reg_key_flush(NULL),
220 WERR_INVALID_PARAM, "flush key");
225 static bool test_query_key(struct torture_context *tctx, const void *_data)
227 const struct registry_context *rctx = _data;
228 struct registry_key *root, *subkey;
230 NTTIME last_changed_time;
231 uint32_t num_subkeys, num_values;
232 const char *classname;
234 if (!create_test_key(tctx, rctx, "Munchen", &root, &subkey))
237 error = reg_key_get_info(tctx, subkey, &classname,
238 &num_subkeys, &num_values,
241 torture_assert_werr_ok(tctx, error, "get info key");
242 torture_assert(tctx, classname == NULL, "classname");
243 torture_assert_int_equal(tctx, num_subkeys, 0, "num subkeys");
244 torture_assert_int_equal(tctx, num_values, 0, "num values");
249 static bool test_query_key_nums(struct torture_context *tctx, const void *_data)
251 const struct registry_context *rctx = _data;
252 struct registry_key *root, *subkey1, *subkey2;
254 uint32_t num_subkeys, num_values;
257 if (!create_test_key(tctx, rctx, "Berlin", &root, &subkey1))
260 error = reg_key_add_name(rctx, subkey1, "Bentheim", NULL, NULL, &subkey2);
261 torture_assert_werr_ok(tctx, error, "Creating key return code");
263 error = reg_val_set(subkey1, "Answer", REG_DWORD,
264 data_blob_talloc(tctx, &data, sizeof(data)));
265 torture_assert_werr_ok(tctx, error, "set value");
267 error = reg_key_get_info(tctx, subkey1, NULL, &num_subkeys,
270 torture_assert_werr_ok(tctx, error, "get info key");
271 torture_assert_int_equal(tctx, num_subkeys, 1, "num subkeys");
272 torture_assert_int_equal(tctx, num_values, 1, "num values");
278 * Test that the subkeys of a key can be enumerated, that
279 * the returned parameters for get_subkey_by_index are optional and
280 * that enumerating the parents of a non-top-level node works.
282 static bool test_list_subkeys(struct torture_context *tctx, const void *_data)
284 const struct registry_context *rctx = _data;
285 struct registry_key *subkey = NULL, *root;
287 NTTIME last_mod_time;
288 const char *classname, *name;
290 if (!create_test_key(tctx, rctx, "Goettingen", &root, &subkey))
293 error = reg_key_get_subkey_by_index(tctx, root, 0, &name, &classname,
296 torture_assert_werr_ok(tctx, error, "Enum keys return code");
297 torture_assert_str_equal(tctx, name, "Goettingen", "Enum keys data");
300 error = reg_key_get_subkey_by_index(tctx, root, 0, NULL, NULL, NULL);
302 torture_assert_werr_ok(tctx, error, "Enum keys with NULL arguments return code");
304 error = reg_key_get_subkey_by_index(tctx, root, 1, NULL, NULL, NULL);
306 torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
307 "Invalid error for no more items");
309 error = reg_key_get_subkey_by_index(tctx, subkey, 0, NULL, NULL, NULL);
311 torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
312 "Invalid error for no more items");
318 * Test setting a value
320 static bool test_set_value(struct torture_context *tctx, const void *_data)
322 const struct registry_context *rctx = _data;
323 struct registry_key *subkey = NULL, *root;
327 if (!create_test_key(tctx, rctx, "Dusseldorf", &root, &subkey))
330 error = reg_val_set(subkey, "Answer", REG_DWORD,
331 data_blob_talloc(tctx, &data, sizeof(data)));
332 torture_assert_werr_ok (tctx, error, "setting value");
338 * Test getting a value
340 static bool test_get_value(struct torture_context *tctx, const void *_data)
342 const struct registry_context *rctx = _data;
343 struct registry_key *subkey = NULL, *root;
349 if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey))
352 error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
354 torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND,
355 "getting missing value");
357 error = reg_val_set(subkey, __FUNCTION__, REG_DWORD,
358 data_blob_talloc(tctx, &value, 4));
359 torture_assert_werr_ok (tctx, error, "setting value");
361 error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
363 torture_assert_werr_ok(tctx, error, "getting value");
365 torture_assert_int_equal(tctx, 4, data.length, "value length ok");
366 torture_assert(tctx, memcmp(data.data, &value, 4) == 0, "value content ok");
367 torture_assert_int_equal(tctx, REG_DWORD, type, "value type");
373 * Test unsetting a value
375 static bool test_del_value(struct torture_context *tctx, const void *_data)
377 const struct registry_context *rctx = _data;
378 struct registry_key *subkey = NULL, *root;
384 if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey))
387 error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
389 torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND,
390 "getting missing value");
392 error = reg_val_set(subkey, __FUNCTION__, REG_DWORD,
393 data_blob_talloc(tctx, &value, 4));
394 torture_assert_werr_ok (tctx, error, "setting value");
396 error = reg_del_value(subkey, __FUNCTION__);
397 torture_assert_werr_ok (tctx, error, "unsetting value");
399 error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, &data);
400 torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND,
401 "getting missing value");
407 * Test listing values
409 static bool test_list_values(struct torture_context *tctx, const void *_data)
411 const struct registry_context *rctx = _data;
412 struct registry_key *subkey = NULL, *root;
419 if (!create_test_key(tctx, rctx, "Bonn", &root, &subkey))
422 error = reg_val_set(subkey, "bar", REG_DWORD,
423 data_blob_talloc(tctx, &value, 4));
424 torture_assert_werr_ok (tctx, error, "setting value");
426 error = reg_key_get_value_by_index(tctx, subkey, 0, &name, &type, &data);
427 torture_assert_werr_ok(tctx, error, "getting value");
429 torture_assert_str_equal(tctx, name, "bar", "value name");
430 torture_assert_int_equal(tctx, 4, data.length, "value length");
431 torture_assert(tctx, memcmp(data.data, &value, 4) == 0, "value content");
432 torture_assert_int_equal(tctx, REG_DWORD, type, "value type");
434 error = reg_key_get_value_by_index(tctx, subkey, 1, &name, &type, &data);
435 torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
436 "getting missing value");
441 static bool setup_local_registry(struct torture_context *tctx, void **data)
443 struct registry_context *rctx;
447 struct hive_key *hive_key;
449 error = reg_open_local(tctx, &rctx, NULL, NULL);
450 if (!W_ERROR_IS_OK(error))
453 status = torture_temp_dir(tctx, "registry-local", &tempdir);
454 if (!NT_STATUS_IS_OK(status))
457 error = reg_open_ldb_file(tctx,
458 talloc_asprintf(tctx, "%s/classes_root.ldb", tempdir),
462 if (!W_ERROR_IS_OK(error))
465 error = reg_mount_hive(rctx, hive_key, HKEY_CLASSES_ROOT, NULL);
466 if (!W_ERROR_IS_OK(error))
474 static void tcase_add_tests(struct torture_tcase *tcase)
476 torture_tcase_add_simple_test(tcase, "list_subkeys", test_list_subkeys);
477 torture_tcase_add_simple_test(tcase, "get_predefined_key",
478 test_get_predefined);
479 torture_tcase_add_simple_test(tcase, "get_predefined_key",
480 test_get_predefined_unknown);
481 torture_tcase_add_simple_test(tcase, "create_key", test_create_subkey);
482 torture_tcase_add_simple_test(tcase, "create_key",
483 test_create_nested_subkey);
484 torture_tcase_add_simple_test(tcase, "key_add_abs", test_key_add_abs);
485 torture_tcase_add_simple_test(tcase, "key_add_abs_top", test_key_add_abs_top);
486 torture_tcase_add_simple_test(tcase, "set_value", test_set_value);
487 torture_tcase_add_simple_test(tcase, "get_value", test_get_value);
488 torture_tcase_add_simple_test(tcase, "list_values", test_list_values);
489 torture_tcase_add_simple_test(tcase, "del_key", test_del_key);
490 torture_tcase_add_simple_test(tcase, "del_value", test_del_value);
491 torture_tcase_add_simple_test(tcase, "flush_key", test_flush_key);
492 torture_tcase_add_simple_test(tcase, "query_key", test_query_key);
493 torture_tcase_add_simple_test(tcase, "query_key_nums", test_query_key_nums);
496 struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx)
498 struct torture_tcase *tcase;
499 struct torture_suite *suite = torture_suite_create(mem_ctx,
502 tcase = torture_suite_add_tcase(suite, "local");
503 torture_tcase_set_fixture(tcase, setup_local_registry, NULL);
504 tcase_add_tests(tcase);