• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 /**************************************************************************************************
3  * IOWOW library
4  *
5  * MIT License
6  *
7  * Copyright (c) 2012-2020 Softmotions Ltd <info@softmotions.com>
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  *  copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in all
17  * copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  *************************************************************************************************/
27 
28 
29 #include "iowow.h"
30 #include "log/iwlog.h"
31 #include "fs/iwexfile.h"
32 #include "utils/iwutils.h"
33 
34 #include "iwcfg.h"
35 #include <CUnit/Basic.h>
36 #include <unistd.h>
37 
38 #define UNLINK() \
39   unlink("iwfs_exfile_test1.dat"); \
40   unlink("iwfs_exfile_test1_2.dat"); \
41   unlink("test_mmap1.dat"); \
42   unlink("test_fibo_inc.dat")
43 
44 
init_suite()45 int init_suite() {
46   int rc = iw_init();
47   UNLINK();
48   return rc;
49 }
50 
clean_suite()51 int clean_suite() {
52   UNLINK();
53   return 0;
54 }
55 
iwfs_exfile_test1()56 void iwfs_exfile_test1() {
57   iwrc rc = 0;
58   IWFS_EXT ef;
59 
60   const char *path = "iwfs_exfile_test1.dat";
61   IWFS_EXT_OPTS opts = {
62     .file = {
63       .path = path,
64       .lock_mode = IWP_WLOCK,
65       .omode = IWFS_DEFAULT_OMODE | IWFS_OTRUNC
66     },
67     .use_locks = 1
68   };
69   IWRC(iwfs_exfile_open(&ef, &opts), rc);
70   CU_ASSERT_EQUAL_FATAL(rc, 0);
71 
72   char data[] = "b069a540-bc92-49ba-95e9-d1a2ee9e8c8f";
73   size_t sp, sp2;
74 
75   // iwrc(*write)(struct IWFS_EXT* f, off_t off, const void *buf, size_t siz,
76   // size_t *sp);
77   IWRC(ef.write(&ef, 0, 0, 0, &sp), rc);
78   CU_ASSERT_EQUAL_FATAL(rc, 0);
79   CU_ASSERT_EQUAL(sp, 0);
80 
81   IWRC(ef.write(&ef, 1, 0, 0, &sp), rc);
82   CU_ASSERT_EQUAL_FATAL(rc, 0);
83 
84   IWP_FILE_STAT fstat;
85   IWRC(iwp_fstat(path, &fstat), rc);
86   CU_ASSERT_EQUAL_FATAL(rc, 0);
87   CU_ASSERT_EQUAL(sp, 0);
88   CU_ASSERT_EQUAL(fstat.size, iwp_alloc_unit());
89 
90   IWRC(ef.write(&ef, 1, data, sizeof(data), &sp), rc);
91   CU_ASSERT_EQUAL_FATAL(rc, 0);
92   CU_ASSERT_EQUAL(sp, 37);
93 
94   IWRC(ef.close(&ef), rc);
95   CU_ASSERT_EQUAL(rc, 0);
96 
97   // Now reopen the file
98 
99   opts.file.omode = IWFS_OREAD;
100   IWRC(iwfs_exfile_open(&ef, &opts), rc);
101   CU_ASSERT_EQUAL_FATAL(rc, 0);
102 
103   char rdata[37];
104   // iwrc(*read)(struct IWFS_EXT* f, off_t off, void *buf, size_t siz, size_t
105   // *sp);
106   IWRC(ef.read(&ef, 1, rdata, sp, &sp2), rc);
107   CU_ASSERT_EQUAL_FATAL(rc, 0);
108   CU_ASSERT_EQUAL(sp, sp2);
109   CU_ASSERT_FALSE(strncmp(rdata, data, sizeof(data)));
110 
111   rc = ef.write(&ef, 1, data, sizeof(data), &sp);
112   CU_ASSERT_EQUAL(IW_ERROR_READONLY, rc);
113 
114   size_t ps = iwp_alloc_unit();
115   rc = 0;
116   IWRC(ef.read(&ef, ps - 1, rdata, 2, &sp2), rc);
117   CU_ASSERT_EQUAL_FATAL(rc, 0);
118   CU_ASSERT_EQUAL(sp2, 1);
119 
120   IWRC(ef.close(&ef), rc);
121   CU_ASSERT_EQUAL(rc, 0);
122 }
123 
iwfs_exfile_test1_2()124 void iwfs_exfile_test1_2() {
125   iwrc rc = 0;
126   IWFS_EXT f;
127   const char *path = "exfile_test1_2-"; // Temp file prefix
128   IWFS_EXT_OPTS opts = {
129     .file = {
130       .path = path,
131       .omode = IWFS_OTMP | IWFS_OUNLINK
132     }
133   };
134   rc = iwfs_exfile_open(&f, &opts);
135   CU_ASSERT_EQUAL_FATAL(rc, 0);
136 
137   IWFS_EXT_STATE state;
138   rc = f.state(&f, &state);
139   CU_ASSERT_EQUAL_FATAL(rc, 0);
140 
141   char *tpath = strdup(state.file.opts.path);
142   fprintf(stderr, "\nTmp file: %s\n", tpath);
143 
144   IWP_FILE_STAT fstat;
145   rc = iwp_fstat(tpath, &fstat);
146   CU_ASSERT_EQUAL_FATAL(rc, 0);
147 
148   rc = f.close(&f);
149   CU_ASSERT_EQUAL_FATAL(rc, 0);
150 
151   memset(&fstat, 0, sizeof(fstat));
152   rc = iwp_fstat(tpath, &fstat);
153   CU_ASSERT_EQUAL_FATAL(rc, IW_ERROR_NOT_EXISTS);
154 
155   free(tpath);
156 }
157 
test_fibo_inc(void)158 void test_fibo_inc(void) {
159   const char *path = "test_fibo_inc.dat";
160   IWFS_EXT ef;
161   IWFS_EXT_OPTS opts = {
162     .file = {
163       .path = path,
164       .lock_mode = IWP_WLOCK,
165       .omode = IWFS_DEFAULT_OMODE | IWFS_OTRUNC
166     },
167     .use_locks = 0,
168     .rspolicy = iw_exfile_szpolicy_fibo
169   };
170   iwrc rc = 0;
171   size_t sp;
172   uint64_t wd = (uint64_t)(-1);
173 
174   IWRC(iwfs_exfile_open(&ef, &opts), rc);
175   CU_ASSERT_EQUAL_FATAL(rc, 0);
176 
177   // iwrc(*write)(struct IWFS_EXT* f, off_t off, const void *buf, size_t siz,
178   // size_t *sp);
179   IWRC(ef.write(&ef, 0, &wd, 1, &sp), rc);
180   CU_ASSERT_EQUAL_FATAL(rc, 0);
181 
182   size_t psize = iwp_alloc_unit();
183   IWP_FILE_STAT fstat;
184   IWRC(iwp_fstat(path, &fstat), rc);
185   CU_ASSERT_EQUAL_FATAL(rc, 0);
186   CU_ASSERT_EQUAL_FATAL(fstat.size, psize);
187 
188   IWRC(ef.write(&ef, fstat.size, &wd, 1, &sp), rc);
189   CU_ASSERT_EQUAL_FATAL(rc, 0);
190 
191   IWRC(iwp_fstat(path, &fstat), rc);
192   CU_ASSERT_EQUAL_FATAL(rc, 0);
193   CU_ASSERT_EQUAL_FATAL(fstat.size, 2 * psize);
194 
195   IWRC(ef.write(&ef, fstat.size, &wd, 1, &sp), rc);
196   CU_ASSERT_EQUAL_FATAL(rc, 0);
197 
198   IWRC(iwp_fstat(path, &fstat), rc);
199   CU_ASSERT_EQUAL_FATAL(rc, 0);
200   CU_ASSERT_EQUAL_FATAL(fstat.size, 3 * psize);
201 
202   IWRC(ef.write(&ef, fstat.size, &wd, 1, &sp), rc);
203   CU_ASSERT_EQUAL_FATAL(rc, 0);
204 
205   IWRC(iwp_fstat(path, &fstat), rc);
206   CU_ASSERT_EQUAL_FATAL(rc, 0);
207   CU_ASSERT_EQUAL_FATAL(fstat.size, 5 * psize);
208 
209   IWRC(ef.close(&ef), rc);
210   CU_ASSERT_EQUAL(rc, 0);
211 }
212 
test_mmap1(void)213 void test_mmap1(void) {
214   iwrc rc = 0;
215   size_t psize = iwp_alloc_unit();
216   size_t sp;
217   const int dsize = psize * 4;
218   uint8_t *data = malloc(dsize);
219   uint8_t *cdata = malloc(dsize);
220 
221   const char *path = "test_mmap1.dat";
222   IWFS_EXT ef;
223   IWFS_EXT_OPTS opts = {.file = {.path = path, .omode = IWFS_OTRUNC}, .use_locks = 0};
224 
225   for (int i = 0; i < dsize; ++i) {
226     data[i] = iwu_rand_range(256);
227   }
228   rc = iwfs_exfile_open(&ef, &opts);
229   CU_ASSERT_EQUAL_FATAL(rc, 0);
230 
231   rc = ef.add_mmap(&ef, 2 * psize, psize, 0);
232   CU_ASSERT_EQUAL_FATAL(rc, 0);
233 
234   rc = ef.add_mmap(&ef, psize, psize, 0);
235   CU_ASSERT_EQUAL_FATAL(rc, 0);
236 
237   rc = ef.add_mmap(&ef, 0, psize, 0);
238   CU_ASSERT_EQUAL_FATAL(rc, 0);
239 
240   rc = ef.add_mmap(&ef, psize, 2 * psize, 0);
241   CU_ASSERT_EQUAL_FATAL(rc, IWFS_ERROR_MMAP_OVERLAP);
242 
243 #ifndef IW_32
244   rc = ef.add_mmap(&ef, 3 * psize, UINT64_MAX, 0);
245   CU_ASSERT_EQUAL_FATAL(rc, 0);
246 #else
247   rc = ef.add_mmap(&ef, 3 * psize, UINT32_MAX >> 1, 0);
248   CU_ASSERT_EQUAL_FATAL(rc, 0);
249 #endif
250 
251   rc = ef.write(&ef, psize / 2, data, psize, &sp);
252   CU_ASSERT_EQUAL_FATAL(rc, 0);
253   CU_ASSERT_EQUAL_FATAL(sp, psize);
254 
255   rc = ef.read(&ef, psize / 2, cdata, psize, &sp);
256   CU_ASSERT_EQUAL_FATAL(rc, 0);
257   CU_ASSERT_EQUAL_FATAL(sp, psize);
258   CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0);
259 
260   for (int i = 0; i < dsize; ++i) {
261     data[i] = iwu_rand_range(256);
262   }
263 
264   // iwrc(*remove_mmap)(struct IWFS_EXT* f, off_t off);
265   rc = ef.remove_mmap(&ef, psize);
266   CU_ASSERT_EQUAL_FATAL(rc, 0);
267   rc = ef.write(&ef, psize / 2, data, psize, &sp);
268   CU_ASSERT_EQUAL_FATAL(rc, 0);
269   CU_ASSERT_EQUAL_FATAL(psize, sp);
270 
271   rc = ef.read(&ef, psize / 2, cdata, psize, &sp);
272   CU_ASSERT_EQUAL_FATAL(rc, 0);
273   CU_ASSERT_EQUAL_FATAL(psize, sp);
274   CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0);
275 
276   for (int i = 0; i < 10; ++i) {
277     rc = ef.write(&ef, psize * i, data, dsize, &sp);
278     CU_ASSERT_EQUAL_FATAL(rc, 0);
279     CU_ASSERT_EQUAL_FATAL(dsize, sp);
280 
281     rc = ef.read(&ef, psize * i, cdata, dsize, &sp);
282     CU_ASSERT_EQUAL_FATAL(rc, 0);
283     CU_ASSERT_EQUAL_FATAL(dsize, sp);
284     CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0);
285   }
286 
287   for (int i = 0; i < dsize; ++i) {
288     data[i] = iwu_rand_range(256);
289   }
290 
291   rc = ef.remove_mmap(&ef, 0);
292   CU_ASSERT_EQUAL_FATAL(rc, 0);
293   for (int i = 0; i < 10; ++i) {
294     rc = ef.write(&ef, psize * i, data, dsize, &sp);
295     CU_ASSERT_EQUAL_FATAL(rc, 0);
296     CU_ASSERT_EQUAL_FATAL(dsize, sp);
297 
298     rc = ef.read(&ef, psize * i, cdata, dsize, &sp);
299     CU_ASSERT_EQUAL_FATAL(rc, 0);
300     CU_ASSERT_EQUAL_FATAL(dsize, sp);
301     CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0);
302   }
303 
304   for (int i = 0; i < dsize; ++i) {
305     data[i] = iwu_rand_range(256);
306   }
307   rc = ef.remove_mmap(&ef, 2 * psize);
308   CU_ASSERT_EQUAL_FATAL(rc, 0);
309   for (int i = 0; i < 10; ++i) {
310     rc = ef.write(&ef, psize * i, data, dsize, &sp);
311     CU_ASSERT_EQUAL_FATAL(rc, 0);
312     CU_ASSERT_EQUAL_FATAL(dsize, sp);
313 
314     rc = ef.read(&ef, psize * i, cdata, dsize, &sp);
315     CU_ASSERT_EQUAL_FATAL(rc, 0);
316     CU_ASSERT_EQUAL_FATAL(dsize, sp);
317     CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0);
318   }
319 
320   for (int i = 0; i < dsize; ++i) {
321     data[i] = iwu_rand_range(256);
322   }
323   rc = ef.remove_mmap(&ef, 3 * psize);
324   CU_ASSERT_EQUAL_FATAL(rc, 0);
325   for (int i = 0; i < 10; ++i) {
326     rc = ef.write(&ef, psize * i, data, dsize, &sp);
327     CU_ASSERT_EQUAL_FATAL(rc, 0);
328     CU_ASSERT_EQUAL_FATAL(dsize, sp);
329 
330     rc = ef.read(&ef, psize * i, cdata, dsize, &sp);
331     CU_ASSERT_EQUAL_FATAL(rc, 0);
332     CU_ASSERT_EQUAL_FATAL(dsize, sp);
333     CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0);
334   }
335 
336   IWRC(ef.close(&ef), rc);
337   CU_ASSERT_EQUAL(rc, 0);
338 
339   free(data);
340   free(cdata);
341 }
342 
main()343 int main() {
344   CU_pSuite pSuite = NULL;
345 
346   /* Initialize the CUnit test registry */
347   if (CUE_SUCCESS != CU_initialize_registry()) return CU_get_error();
348 
349   /* Add a suite to the registry */
350   pSuite = CU_add_suite("iwfs_test1", init_suite, clean_suite);
351 
352   if (NULL == pSuite) {
353     CU_cleanup_registry();
354     return CU_get_error();
355   }
356 
357   /* Add the tests to the suite */
358   if ((NULL == CU_add_test(pSuite, "iwfs_exfile_test1", iwfs_exfile_test1)) ||
359       (NULL == CU_add_test(pSuite, "iwfs_exfile_test1_2", iwfs_exfile_test1_2)) ||
360       (NULL == CU_add_test(pSuite, "test_fibo_inc", test_fibo_inc)) ||
361       (NULL == CU_add_test(pSuite, "test_mmap1", test_mmap1))) {
362     CU_cleanup_registry();
363     return CU_get_error();
364   }
365 
366   /* Run all tests using the CUnit Basic interface */
367   CU_basic_set_mode(CU_BRM_VERBOSE);
368   CU_basic_run_tests();
369   int ret = CU_get_error() || CU_get_number_of_failures();
370   CU_cleanup_registry();
371   return ret;
372 }
373