]> git.proxmox.com Git - pve-cluster.git/blob - data/src/check_memdb.c
4a5ea344c61dd47f5f090900b20e0e49f0ab2392
[pve-cluster.git] / data / src / check_memdb.c
1 /*
2 Copyright (C) 2010-2012 Proxmox Server Solutions GmbH
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Affero General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Affero General Public License for more details.
13
14 You should have received a copy of the GNU Affero General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 Author: Dietmar Maurer <dietmar@proxmox.com>
18
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <glib.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <check.h>
27 #include <errno.h>
28 #include <unistd.h>
29
30 #include "cfs-utils.h"
31 #include "status.h"
32 #include "memdb.h"
33
34 cfs_t cfs = {
35 .debug = 0,
36 .nodename = "testnode",
37 .print_to_console = 1,
38 };
39
40 #define TESTDB "/tmp/test.db"
41
42 static memdb_t *memdb;
43
44 static void
45 setup(void)
46 {
47 unlink(TESTDB);
48 memdb = memdb_open(TESTDB);
49 fail_unless (memdb != NULL);
50
51 struct statvfs stbuf;
52 fail_unless(memdb_statfs(memdb, &stbuf) == 0);
53
54 int count = stbuf.f_files - stbuf.f_ffree;
55 fail_unless(count == 1);
56 }
57
58 void
59 teardown(void)
60 {
61 fail_unless (memdb != NULL);
62
63 memdb_close(memdb);
64 }
65
66 START_TEST(test_indextest1)
67 {
68 char namebuf[100];
69
70 time_t ctime = 1234;
71 int testsize = 1024*32;
72 gchar *testdata = g_malloc0(testsize);
73
74 for (int i = 0; i < 100; i++) {
75 sprintf(namebuf, "testfile%d", i);
76
77 fail_unless(memdb_create(memdb, namebuf, 0, ctime) == 0);
78 fail_unless(memdb_write(memdb, namebuf, 0, ctime, testdata, testsize, 0, 0) == testsize);
79 }
80
81 struct statvfs stbuf;
82 fail_unless(memdb_statfs(memdb, &stbuf) == 0);
83
84 int count = stbuf.f_files - stbuf.f_ffree;
85 fail_unless(count == 101);
86
87 memdb_index_t *idx = memdb_encode_index(memdb->index, memdb->root);
88 fail_unless(idx != NULL);
89
90 fail_unless(idx->version == 201);
91 fail_unless(idx->last_inode == 200);
92 fail_unless(idx->writer == 0);
93 fail_unless(idx->size == 101);
94 fail_unless(idx->bytes == (101*40 + sizeof( memdb_index_t)));
95
96 GChecksum *sha256 = g_checksum_new(G_CHECKSUM_SHA256);
97 fail_unless(sha256 != NULL);
98 g_checksum_update(sha256, (unsigned char *)idx, idx->bytes);
99 const char *csum = g_checksum_get_string(sha256);
100 fail_unless(strcmp(csum, "913fd95015af9d93f10dd51ba2a7bb11351bcfe040be21e95fcba834adc3ec10") == 0, "wrong idx checksum %s", csum);
101
102 }
103 END_TEST
104
105 START_TEST (test_dirtest1)
106 {
107 const char *dn = "/dir1";
108 const char *sdn = "/dir1/sdir1";
109 time_t ctime = 1234;
110
111 fail_unless(memdb_mkdir(memdb, sdn, 0, ctime) == -ENOENT);
112 fail_unless(memdb_delete(memdb, dn, 0, ctime) == -ENOENT);
113
114 fail_unless(memdb_mkdir(memdb, dn, 0, ctime) == 0);
115 fail_unless(memdb_mkdir(memdb, dn, 0, ctime) == -EEXIST);
116 fail_unless(memdb_mkdir(memdb, sdn, 0, ctime) == 0);
117 fail_unless(memdb_mkdir(memdb, sdn, 0, ctime) == -EEXIST);
118 fail_unless(memdb_delete(memdb, dn, 0, ctime) == -ENOTEMPTY);
119 fail_unless(memdb_delete(memdb, sdn, 0, ctime) == 0);
120 fail_unless(memdb_delete(memdb, dn, 0, ctime) == 0);
121 }
122 END_TEST
123
124 START_TEST (test_filetest1)
125 {
126 const char *dn = "/dir1";
127 const char *fn = "/dir1/f1";
128 time_t ctime = 1234;
129 gpointer data;
130
131 char buf[1024];
132 memset(buf, 0, sizeof(buf));
133
134 fail_unless(memdb_read(memdb, fn, &data) == -ENOENT);
135
136 fail_unless(memdb_mkdir(memdb, dn, 0, ctime) == 0);
137
138 fail_unless(memdb_read(memdb, fn, &data) == -ENOENT);
139
140 fail_unless(memdb_write(memdb, fn, 0, ctime, buf, sizeof(buf), 0, 0) == -ENOENT);
141
142 fail_unless(memdb_create(memdb, fn, 0, ctime) == 0);
143
144 fail_unless(memdb_write(memdb, fn, 0, ctime, buf, sizeof(buf), 0, 0) == sizeof(buf));
145
146 fail_unless(memdb_read(memdb, fn, &data) == sizeof(buf));
147
148 fail_unless(memcmp(buf, data, sizeof(buf)) == 0);
149
150 g_free(data);
151
152 fail_unless(memdb_write(memdb, fn, 0, ctime, "0123456789", 10, 0, 1) == 10);
153
154 fail_unless(memdb_read(memdb, fn, &data) == 10);
155 g_free(data);
156
157 fail_unless(memdb_write(memdb, fn, 0, ctime, "X", 1, 3, 0) == 1);
158
159 fail_unless(memdb_write(memdb, fn, 0, ctime, "X", 1, 6, 0) == 1);
160
161 fail_unless(memdb_read(memdb, fn, &data) == 10);
162
163 fail_unless(strncmp(data, "012X45X789", 10) == 0);
164
165 fail_unless(memdb_delete(memdb, fn, 0, ctime) == 0);
166
167 fail_unless(memdb_delete(memdb, fn, 0, ctime) == -ENOENT);
168
169 fail_unless(memdb_delete(memdb, dn, 0, ctime) == 0);
170 }
171 END_TEST
172
173 /* Nornmaly, parent inode number is always less than contained inode,
174 * but this is not allways the case. A simple move can destroy that
175 * ordering. This code test the placeholder algorithm in
176 * bdb_backend_load_index()
177 */
178 START_TEST (test_loaddb1)
179 {
180 time_t ctime = 1234;
181
182 fail_unless(memdb_mkdir(memdb, "dir1", 0, ctime) == 0);
183
184 fail_unless(memdb_create(memdb, "dir1/file1", 0, ctime) == 0);
185
186 fail_unless(memdb_create(memdb, "dir1/file2", 0, ctime) == 0);
187
188 fail_unless(memdb_mkdir(memdb, "dir2", 0, ctime) == 0);
189
190 fail_unless(memdb_rename(memdb, "dir1/file1", "dir2/file1", 0, ctime) == 0);
191
192 fail_unless(memdb_rename(memdb, "dir1/file2", "dir2/file2", 0, ctime) == 0);
193
194 fail_unless(memdb_create(memdb, "dir2/file1", 0, ctime) == -EEXIST);
195
196 fail_unless(memdb_create(memdb, "dir2/file2", 0, ctime) == -EEXIST);
197
198 //memdb_dump(memdb);
199
200 memdb_close(memdb);
201
202 memdb = memdb_open(TESTDB);
203 fail_unless (memdb != NULL);
204
205 fail_unless(memdb_create(memdb, "dir2/file1", 0, ctime) == -EEXIST);
206
207 fail_unless(memdb_create(memdb, "dir2/file2", 0, ctime) == -EEXIST);
208
209 //memdb_dump(memdb);
210
211 }
212 END_TEST
213
214 START_TEST (test_loaddb2)
215 {
216 time_t ctime = 1234;
217
218 fail_unless(memdb_mkdir(memdb, "dir1", 0, ctime) == 0);
219
220 fail_unless(memdb_mkdir(memdb, "dir1/sd1", 0, ctime) == 0);
221
222 fail_unless(memdb_create(memdb, "dir1/file1", 0, ctime) == 0);
223
224 fail_unless(memdb_create(memdb, "dir1/file2", 0, ctime) == 0);
225
226 fail_unless(memdb_mkdir(memdb, "dir2", 0, ctime) == 0);
227
228 fail_unless(memdb_rename(memdb, "dir1/sd1", "dir2/sd1", 0, ctime) == 0);
229
230 fail_unless(memdb_rename(memdb, "dir1/file1", "dir2/sd1/file1", 0, ctime) == 0);
231
232 fail_unless(memdb_rename(memdb, "dir1/file2", "dir2/sd1/file2", 0, ctime) == 0);
233
234 fail_unless(memdb_create(memdb, "dir2/file3", 0, ctime) == 0);
235
236 fail_unless(memdb_mkdir(memdb, "dir2/sd1", 0, ctime) == -EEXIST);
237
238 //memdb_dump(memdb);
239
240 memdb_close(memdb);
241
242 memdb = memdb_open(TESTDB);
243 fail_unless (memdb != NULL);
244
245 fail_unless(memdb_mkdir(memdb, "dir2/sd1", 0, ctime) == -EEXIST);
246
247 //memdb_dump(memdb);
248
249 }
250 END_TEST
251
252 static void
253 add_test(
254 Suite *s,
255 TFun tf,
256 const char *name)
257 {
258 TCase *tc = tcase_create (name);
259 tcase_add_checked_fixture (tc, setup, teardown);
260 tcase_add_test (tc, tf);
261 suite_add_tcase (s, tc);
262 }
263
264 static Suite *
265 memdb_suite(void)
266 {
267 Suite *s = suite_create ("memdb");
268
269 add_test(s, test_dirtest1, "dirtest1");
270
271 add_test(s, test_filetest1, "filetest1");
272
273 add_test(s, test_indextest1, "indextest1");
274
275 add_test(s, test_loaddb1, "loaddb1");
276
277 add_test(s, test_loaddb2, "loaddb2");
278
279 return s;
280 }
281
282 int
283 main(void)
284 {
285 int number_failed;
286
287 g_thread_init(NULL);
288
289 cfs_status_init();
290
291 Suite *s = memdb_suite();
292 SRunner *sr = srunner_create(s);
293 srunner_run_all(sr, CK_NORMAL);
294 number_failed = srunner_ntests_failed(sr);
295 srunner_free(sr);
296
297 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
298 }
299