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