]> git.proxmox.com Git - pve-cluster.git/blob - data/src/check_memdb.c
buildsys: add sbuild convenience target
[pve-cluster.git] / data / src / check_memdb.c
1 /*
2 Copyright (C) 2010 - 2020 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 #if CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION <= 10
35 #define _TEST_TYPE TFun
36 #else
37 #define _TEST_TYPE const TTest *
38 #endif
39
40 cfs_t cfs = {
41 .debug = 0,
42 .nodename = "testnode",
43 };
44
45 #define TESTDB "/tmp/test.db"
46
47 static memdb_t *memdb;
48
49 static void
50 setup(void)
51 {
52 unlink(TESTDB);
53 memdb = memdb_open(TESTDB);
54 ck_assert (memdb != NULL);
55
56 struct statvfs stbuf;
57 ck_assert(memdb_statfs(memdb, &stbuf) == 0);
58
59 int count = stbuf.f_files - stbuf.f_ffree;
60 ck_assert(count == 1);
61 }
62
63 void
64 teardown(void)
65 {
66 ck_assert (memdb != NULL);
67
68 memdb_close(memdb);
69 }
70
71 START_TEST(test_indextest1)
72 {
73 char namebuf[100];
74
75 time_t ctime = 1234;
76 int testsize = 1024*32;
77 gchar *testdata = g_malloc0(testsize);
78
79 for (int i = 0; i < 100; i++) {
80 sprintf(namebuf, "testfile%d", i);
81
82 ck_assert(memdb_create(memdb, namebuf, 0, ctime) == 0);
83 ck_assert(memdb_write(memdb, namebuf, 0, ctime, testdata, testsize, 0, 0) == testsize);
84 }
85
86 struct statvfs stbuf;
87 ck_assert(memdb_statfs(memdb, &stbuf) == 0);
88
89 int count = stbuf.f_files - stbuf.f_ffree;
90 ck_assert(count == 101);
91
92 memdb_index_t *idx = memdb_encode_index(memdb->index, memdb->root);
93 ck_assert(idx != NULL);
94
95 ck_assert(idx->version == 201);
96 ck_assert(idx->last_inode == 200);
97 ck_assert(idx->writer == 0);
98 ck_assert(idx->size == 101);
99 ck_assert(idx->bytes == (101*40 + sizeof( memdb_index_t)));
100
101 GChecksum *sha256 = g_checksum_new(G_CHECKSUM_SHA256);
102 ck_assert(sha256 != NULL);
103 g_checksum_update(sha256, (unsigned char *)idx, idx->bytes);
104 const char *csum = g_checksum_get_string(sha256);
105 ck_assert_msg(
106 strcmp(csum, "913fd95015af9d93f10dd51ba2a7bb11351bcfe040be21e95fcba834adc3ec10") == 0,
107 "wrong idx checksum %s",
108 csum
109 );
110 g_free(idx);
111 g_free(testdata);
112
113 }
114 END_TEST
115
116 START_TEST (test_dirtest1)
117 {
118 const char *dn = "/dir1";
119 const char *sdn = "/dir1/sdir1";
120 time_t ctime = 1234;
121
122 ck_assert(memdb_mkdir(memdb, sdn, 0, ctime) == -ENOENT);
123 ck_assert(memdb_delete(memdb, dn, 0, ctime) == -ENOENT);
124
125 ck_assert(memdb_mkdir(memdb, dn, 0, ctime) == 0);
126 ck_assert(memdb_mkdir(memdb, dn, 0, ctime) == -EEXIST);
127 ck_assert(memdb_mkdir(memdb, sdn, 0, ctime) == 0);
128 ck_assert(memdb_mkdir(memdb, sdn, 0, ctime) == -EEXIST);
129 ck_assert(memdb_delete(memdb, dn, 0, ctime) == -ENOTEMPTY);
130 ck_assert(memdb_delete(memdb, sdn, 0, ctime) == 0);
131 ck_assert(memdb_delete(memdb, dn, 0, ctime) == 0);
132 }
133 END_TEST
134
135 START_TEST (test_filetest1)
136 {
137 const char *dn = "/dir1";
138 const char *fn = "/dir1/f1";
139 time_t ctime = 1234;
140 gpointer data;
141
142 char buf[1024];
143 memset(buf, 0, sizeof(buf));
144
145 ck_assert(memdb_read(memdb, fn, &data) == -ENOENT);
146
147 ck_assert(memdb_mkdir(memdb, dn, 0, ctime) == 0);
148
149 ck_assert(memdb_read(memdb, fn, &data) == -ENOENT);
150
151 ck_assert(memdb_write(memdb, fn, 0, ctime, buf, sizeof(buf), 0, 0) == -ENOENT);
152
153 ck_assert(memdb_create(memdb, fn, 0, ctime) == 0);
154
155 ck_assert(memdb_write(memdb, fn, 0, ctime, buf, sizeof(buf), 0, 0) == sizeof(buf));
156
157 ck_assert(memdb_read(memdb, fn, &data) == sizeof(buf));
158
159 ck_assert(memcmp(buf, data, sizeof(buf)) == 0);
160
161 g_free(data);
162
163 ck_assert(memdb_write(memdb, fn, 0, ctime, "0123456789", 10, 0, 1) == 10);
164
165 ck_assert(memdb_read(memdb, fn, &data) == 10);
166 g_free(data);
167
168 ck_assert(memdb_write(memdb, fn, 0, ctime, "X", 1, 3, 0) == 1);
169
170 ck_assert(memdb_write(memdb, fn, 0, ctime, "X", 1, 6, 0) == 1);
171
172 ck_assert(memdb_read(memdb, fn, &data) == 10);
173
174 ck_assert(strncmp(data, "012X45X789", 10) == 0);
175 g_free(data);
176
177 ck_assert(memdb_delete(memdb, fn, 0, ctime) == 0);
178
179 ck_assert(memdb_delete(memdb, fn, 0, ctime) == -ENOENT);
180
181 ck_assert(memdb_delete(memdb, dn, 0, ctime) == 0);
182 }
183 END_TEST
184
185 /* Nornmaly, parent inode number is always less than contained inode,
186 * but this is not allways the case. A simple move can destroy that
187 * ordering. This code test the placeholder algorithm in
188 * bdb_backend_load_index()
189 */
190 START_TEST (test_loaddb1)
191 {
192 time_t ctime = 1234;
193
194 ck_assert(memdb_mkdir(memdb, "dir1", 0, ctime) == 0);
195
196 ck_assert(memdb_create(memdb, "dir1/file1", 0, ctime) == 0);
197
198 ck_assert(memdb_create(memdb, "dir1/file2", 0, ctime) == 0);
199
200 ck_assert(memdb_mkdir(memdb, "dir2", 0, ctime) == 0);
201
202 ck_assert(memdb_rename(memdb, "dir1/file1", "dir2/file1", 0, ctime) == 0);
203
204 ck_assert(memdb_rename(memdb, "dir1/file2", "dir2/file2", 0, ctime) == 0);
205
206 ck_assert(memdb_create(memdb, "dir2/file1", 0, ctime) == -EEXIST);
207
208 ck_assert(memdb_create(memdb, "dir2/file2", 0, ctime) == -EEXIST);
209
210 //memdb_dump(memdb);
211
212 memdb_close(memdb);
213
214 memdb = memdb_open(TESTDB);
215 ck_assert (memdb != NULL);
216
217 ck_assert(memdb_create(memdb, "dir2/file1", 0, ctime) == -EEXIST);
218
219 ck_assert(memdb_create(memdb, "dir2/file2", 0, ctime) == -EEXIST);
220
221 //memdb_dump(memdb);
222
223 }
224 END_TEST
225
226 START_TEST (test_loaddb2)
227 {
228 time_t ctime = 1234;
229
230 ck_assert(memdb_mkdir(memdb, "dir1", 0, ctime) == 0);
231
232 ck_assert(memdb_mkdir(memdb, "dir1/sd1", 0, ctime) == 0);
233
234 ck_assert(memdb_create(memdb, "dir1/file1", 0, ctime) == 0);
235
236 ck_assert(memdb_create(memdb, "dir1/file2", 0, ctime) == 0);
237
238 ck_assert(memdb_mkdir(memdb, "dir2", 0, ctime) == 0);
239
240 ck_assert(memdb_rename(memdb, "dir1/sd1", "dir2/sd1", 0, ctime) == 0);
241
242 ck_assert(memdb_rename(memdb, "dir1/file1", "dir2/sd1/file1", 0, ctime) == 0);
243
244 ck_assert(memdb_rename(memdb, "dir1/file2", "dir2/sd1/file2", 0, ctime) == 0);
245
246 ck_assert(memdb_create(memdb, "dir2/file3", 0, ctime) == 0);
247
248 ck_assert(memdb_mkdir(memdb, "dir2/sd1", 0, ctime) == -EEXIST);
249
250 //memdb_dump(memdb);
251
252 memdb_close(memdb);
253
254 memdb = memdb_open(TESTDB);
255 ck_assert (memdb != NULL);
256
257 ck_assert(memdb_mkdir(memdb, "dir2/sd1", 0, ctime) == -EEXIST);
258
259 //memdb_dump(memdb);
260
261 }
262 END_TEST
263
264 static void
265 add_test(
266 Suite *s,
267 _TEST_TYPE tf,
268 const char *name)
269 {
270 TCase *tc = tcase_create (name);
271 tcase_add_checked_fixture (tc, setup, teardown);
272 tcase_add_test (tc, tf);
273 suite_add_tcase (s, tc);
274 }
275
276 static Suite *
277 memdb_suite(void)
278 {
279 Suite *s = suite_create ("memdb");
280
281 add_test(s, test_dirtest1, "dirtest1");
282
283 add_test(s, test_filetest1, "filetest1");
284
285 add_test(s, test_indextest1, "indextest1");
286
287 add_test(s, test_loaddb1, "loaddb1");
288
289 add_test(s, test_loaddb2, "loaddb2");
290
291 return s;
292 }
293
294 int
295 main(void)
296 {
297 int number_failed;
298
299 cfs_status_init();
300
301 Suite *s = memdb_suite();
302 SRunner *sr = srunner_create(s);
303 srunner_run_all(sr, CK_NORMAL);
304 number_failed = srunner_ntests_failed(sr);
305 srunner_free(sr);
306
307 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
308 }
309