src/server/test/vfs.c

branch
webdav
changeset 219
dd6c155c082a
child 220
2915b6c11aec
equal deleted inserted replaced
218:2ba512b284b9 219:dd6c155c082a
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2019 Olaf Wintermann. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include <ucx/string.h>
33 #include <ucx/list.h>
34 #include <ucx/map.h>
35
36 #include "../daemon/session.h"
37
38 #include "testutils.h"
39
40 #include "vfs.h"
41
42 typedef struct TestVFS {
43 UcxMap *files;
44 } TestVFS;
45
46 typedef struct TestVFSFile {
47 VFSFile file;
48 sstr_t path;
49 int isdir;
50 } TestVFSFile;
51
52 typedef struct TestVFSDir {
53 VFSDir dir;
54 TestVFSFile *file;
55 UcxMapIterator i;
56 sstr_t name;
57 } TestVFSDir;
58
59 /* dir io */
60
61 static char* test_resource_name(char *url) {
62 sstr_t urlstr = sstr(url);
63 if(urlstr.ptr[urlstr.length-1] == '/') {
64 urlstr.length--;
65 }
66 sstr_t resname = sstrrchr(urlstr, '/');
67 if(resname.length > 1) {
68 return resname.ptr+1;
69 } else {
70 return url;
71 }
72 }
73
74 int testvfs_readdir(VFS_DIR dir, VFS_ENTRY *entry, int getstat) {
75 TestVFS *vfs = dir->ctx->vfs->instance;
76 TestVFSDir *vfsdir = (TestVFSDir*)dir;
77
78 sstr_t prefix = sstrcat(2, vfsdir->file->path, S("/"));
79
80 TestVFSFile *file = NULL;
81 UCX_MAP_FOREACH(key, file, vfsdir->i) {
82 if(sstrprefix(file->path, prefix)) {
83 break;
84 } else {
85 file = NULL;
86 }
87 }
88 free(prefix.ptr);
89
90 if(file) {
91 vfsdir->name = sstrdup_a(
92 session_get_allocator(dir->ctx->sn),
93 sstr(test_resource_name(file->path.ptr)));
94 entry->name = vfsdir->name.ptr;
95 return 1;
96 } else {
97 return 0;
98 }
99 }
100
101 void testvfs_dir_close(VFS_DIR dir) {
102 TestVFSDir *testdir = (TestVFSDir*)dir;
103 pool_free(testdir->dir.ctx->sn->pool, dir);
104
105 }
106
107 VFS_DIRIO test_dir_io = {
108 testvfs_readdir,
109 testvfs_dir_close
110 };
111
112
113 /* vfs funcs */
114
115 SYS_FILE testvfs_open(VFSContext *ctx, char *path, int oflags) {
116 TestVFS *vfs = ctx->vfs->instance;
117 TestVFSFile *file = NULL;
118
119 sstr_t s_path = sstr(path);
120 if(sstrsuffix(s_path, S("/"))) {
121 s_path.length--;
122 }
123
124 file = ucx_map_sstr_get(vfs->files, s_path);
125 if(!file) {
126 if((oflags & O_CREAT) == O_CREAT) {
127 file = pool_malloc(ctx->sn->pool, sizeof(TestVFSFile));
128 ZERO(file, sizeof(TestVFSFile));
129 file->path = sstrdup_a(session_get_allocator(ctx->sn), s_path);
130
131 ucx_map_sstr_put(vfs->files, s_path, file);
132 }
133 }
134
135 return (SYS_FILE)file;
136 }
137
138 int testvfs_stat(VFSContext *ctx, char *path, struct stat *buf) {
139 TestVFS *vfs = ctx->vfs->instance;
140 TestVFSFile *file = NULL;
141
142 sstr_t s_path = sstr(path);
143 if(sstrsuffix(s_path, S("/"))) {
144 s_path.length--;
145 }
146
147 file = ucx_map_sstr_get(vfs->files, s_path);
148 if(!file) {
149 return 1;
150 }
151 return 0;
152 }
153
154 int testvfs_fstat(VFSContext *ctx, SYS_FILE fd, struct stat *buf) {
155 return 0;
156 }
157
158 VFS_DIR testvfs_opendir(VFSContext *ctx, char *path) {
159 TestVFS *vfs = ctx->vfs->instance;
160 TestVFSFile *file = NULL;
161
162 sstr_t s_path = sstr(path);
163 if(sstrsuffix(s_path, S("/"))) {
164 s_path.length--;
165 }
166
167 file = ucx_map_sstr_get(vfs->files, s_path);
168 if(!file) {
169 return NULL;
170 }
171
172 if(!file->isdir) {
173 return NULL;
174 }
175
176 TestVFSDir *dir = pool_malloc(ctx->sn->pool, sizeof(TestVFSDir));
177 ZERO(dir, sizeof(TestVFSDir));
178 dir->file = file;
179 dir->i = ucx_map_iterator(vfs->files);
180
181 dir->dir.ctx = ctx;
182 dir->dir.io = &test_dir_io;
183
184 return (VFS_DIR)dir;
185 }
186
187 VFS_DIR testvfs_fdopendir(VFSContext *ctx, SYS_FILE fd) {
188 TestVFS *vfs = ctx->vfs->instance;
189 TestVFSFile *file = (TestVFSFile*)fd;
190 if(!file->isdir) {
191 return NULL;
192 }
193
194 TestVFSDir *dir = pool_malloc(ctx->sn->pool, sizeof(TestVFSDir));
195 ZERO(dir, sizeof(TestVFSDir));
196 dir->file = file;
197 dir->i = ucx_map_iterator(vfs->files);
198
199 dir->dir.ctx = ctx;
200 dir->dir.io = &test_dir_io;
201
202 return (VFS_DIR)dir;
203 }
204
205 int testvfs_mkdir(VFSContext *ctx, char *path) {
206 SYS_FILE fd = testvfs_open(ctx, path, O_CREAT);
207 if(!fd) {
208 return 1;
209 }
210
211 TestVFSFile *file = (TestVFSFile*)fd;
212 file->isdir = 1;
213
214 return 0;
215 }
216
217 int testvfs_unlink(VFSContext *ctx, char *path) {
218 return 0;
219 }
220
221 static VFS testVFSClass = {
222 testvfs_open,
223 testvfs_stat,
224 testvfs_fstat,
225 testvfs_opendir,
226 testvfs_fdopendir,
227 testvfs_mkdir,
228 testvfs_unlink,
229 0,
230 NULL
231 };
232
233
234 VFS* testvfs_create(Session *sn) {
235 TestVFS *vfs = pool_malloc(sn->pool, sizeof(TestVFS));
236 vfs->files = ucx_map_new_a(session_get_allocator(sn), 64);
237
238 testVFSClass.instance = vfs;
239 return &testVFSClass;
240 }
241
242
243 /* ------------------------------------------------------------------------- */
244 //
245 // VFS Tests
246 //
247 /* ------------------------------------------------------------------------- */
248
249 UCX_TEST(test_vfs_open) {
250 Session *sn = testutil_session();
251 Request *rq = testutil_request(sn->pool, "PUT", "/");
252 rq->vfs = testvfs_create(sn);
253
254 VFSContext *vfs = vfs_request_context(sn, rq);
255
256 UCX_TEST_BEGIN;
257
258 UCX_TEST_ASSERT(vfs, "vfs is NULL");
259
260 SYS_FILE f1 = vfs_open(vfs, "/file1", O_CREAT);
261 UCX_TEST_ASSERT(f1, "f1 not opened");
262
263 SYS_FILE f2 = vfs_open(vfs, "/file1", 0);
264 UCX_TEST_ASSERT(f2, "f2 not opened");
265
266 UCX_TEST_END;
267
268 testutil_destroy_session(sn);
269 }
270
271 UCX_TEST(test_vfs_mkdir) {
272 Session *sn = testutil_session();
273 Request *rq = testutil_request(sn->pool, "PUT", "/");
274 rq->vfs = testvfs_create(sn);
275
276 VFSContext *vfs = vfs_request_context(sn, rq);
277
278 UCX_TEST_BEGIN;
279
280 int err = vfs_mkdir(vfs, "/dir");
281 UCX_TEST_ASSERT(err == 0, "error not 0");
282
283 SYS_FILE fd = vfs_open(vfs, "/dir", 0);
284 UCX_TEST_ASSERT(fd, "no fd");
285
286 UCX_TEST_END;
287
288 testutil_destroy_session(sn);
289 }
290
291 UCX_TEST(test_vfs_opendir) {
292 Session *sn = testutil_session();
293 Request *rq = testutil_request(sn->pool, "PUT", "/");
294 rq->vfs = testvfs_create(sn);
295
296 VFSContext *vfs = vfs_request_context(sn, rq);
297
298 UCX_TEST_BEGIN;
299
300 int err = vfs_mkdir(vfs, "/dir");
301 UCX_TEST_ASSERT(err == 0, "error not 0");
302
303 VFSDir *dir = vfs_opendir(vfs, "/dir");
304 UCX_TEST_ASSERT(dir, "no dir");
305
306 UCX_TEST_END;
307
308 testutil_destroy_session(sn);
309 }
310
311 UCX_TEST(test_readdir) {
312 Session *sn = testutil_session();
313 Request *rq = testutil_request(sn->pool, "PUT", "/");
314 rq->vfs = testvfs_create(sn);
315
316 VFSContext *vfs = vfs_request_context(sn, rq);
317
318 UCX_TEST_BEGIN;
319
320 int err = vfs_mkdir(vfs, "/dir");
321 UCX_TEST_ASSERT(err == 0, "error not 0");
322
323 // add some test file to /dir
324 UCX_TEST_ASSERT(vfs_open(vfs, "/dir/file1", O_CREAT), "creation of file1 failed");
325 UCX_TEST_ASSERT(vfs_open(vfs, "/dir/file2", O_CREAT), "creation of file2 failed");
326 UCX_TEST_ASSERT(vfs_open(vfs, "/dir/file3", O_CREAT), "creation of file3 failed");
327 UCX_TEST_ASSERT(vfs_open(vfs, "/dir/file4", O_CREAT), "creation of file4 failed");
328
329 VFSDir *dir = vfs_opendir(vfs, "/dir");
330 UCX_TEST_ASSERT(dir, "dir not opened");
331
332 UcxMap *files = ucx_map_new(8);
333
334 VFSEntry entry;
335 while(vfs_readdir(dir, &entry)) {
336 ucx_map_cstr_put(files, entry.name, dir);
337 }
338
339 UCX_TEST_ASSERT(files->count == 4, "wrong files count");
340 UCX_TEST_ASSERT(ucx_map_cstr_get(files, "file1"), "file1 missing");
341 UCX_TEST_ASSERT(ucx_map_cstr_get(files, "file2"), "file2 missing");
342 UCX_TEST_ASSERT(ucx_map_cstr_get(files, "file3"), "file3 missing");
343 UCX_TEST_ASSERT(ucx_map_cstr_get(files, "file4"), "file4 missing");
344
345 ucx_map_free(files);
346
347 UCX_TEST_END;
348
349 testutil_destroy_session(sn);
350 }

mercurial