source: mainline/uspace/lib/fmgt/test/newfile.c@ d101368

Last change on this file since d101368 was d101368, checked in by Jiri Svoboda <jiri@…>, 4 weeks ago

Split new file creation into a separate fmgt module.

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/*
2 * Copyright (c) 2025 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <fmgt.h>
30#include <pcut/pcut.h>
31#include <stdio.h>
32#include <str.h>
33#include <vfs/vfs.h>
34
35PCUT_INIT;
36
37PCUT_TEST_SUITE(newfile);
38
39#define TEMP_DIR "/tmp"
40
41static void test_fmgt_progress(void *, fmgt_progress_t *);
42
43static fmgt_cb_t test_fmgt_cb = {
44 .progress = test_fmgt_progress
45};
46
47typedef struct {
48 unsigned nupdates;
49} test_resp_t;
50
51/** Suggesting new file name succeeds and returns unique name. */
52PCUT_TEST(new_file_suggest)
53{
54 FILE *f = NULL;
55 char *fname1 = NULL;
56 char *fname2 = NULL;
57 errno_t rc;
58 int rv;
59
60 rc = vfs_cwd_set(TEMP_DIR);
61 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
62
63 /* Suggest unique file name. */
64 rc = fmgt_new_file_suggest(&fname1);
65 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
66
67 /* See if we can actually create the file. */
68 f = fopen(fname1, "wx");
69 PCUT_ASSERT_NOT_NULL(f);
70 (void) fclose(f);
71
72 /* Now suggest another unique file name. */
73 rc = fmgt_new_file_suggest(&fname2);
74 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
75
76 /* They should be different. */
77 PCUT_ASSERT_FALSE(str_cmp(fname1, fname2) == 0);
78
79 /* Remove the file. */
80 rv = remove(fname1);
81 PCUT_ASSERT_INT_EQUALS(0, rv);
82
83 free(fname1);
84 free(fname2);
85}
86
87/** New empty file can be created. */
88PCUT_TEST(new_file_empty)
89{
90 fmgt_t *fmgt = NULL;
91 char *fname = NULL;
92 errno_t rc;
93 int rv;
94
95 rc = vfs_cwd_set(TEMP_DIR);
96 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
97
98 rc = fmgt_create(&fmgt);
99 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
100
101 /* Suggest unique file name. */
102 rc = fmgt_new_file_suggest(&fname);
103 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
104
105 rc = fmgt_new_file(fmgt, fname, 0, nf_none);
106 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
107
108 /* Remove the file [this also verifies the file exists]. */
109 rv = remove(fname);
110 PCUT_ASSERT_INT_EQUALS(0, rv);
111
112 free(fname);
113 fmgt_destroy(fmgt);
114}
115
116/** New zero-filled file can be created. */
117PCUT_TEST(new_file_zerofill)
118{
119 FILE *f = NULL;
120 fmgt_t *fmgt = NULL;
121 char *fname = NULL;
122 char buf[128];
123 errno_t rc;
124 size_t nr;
125 size_t total_rd;
126 size_t i;
127 int rv;
128
129 rc = vfs_cwd_set(TEMP_DIR);
130 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
131
132 rc = fmgt_create(&fmgt);
133 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
134
135 /* Suggest unique file name. */
136 rc = fmgt_new_file_suggest(&fname);
137 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
138
139 rc = fmgt_new_file(fmgt, fname, 20000, nf_none);
140 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
141
142 /* Verify the file. */
143 f = fopen(fname, "rb");
144 PCUT_ASSERT_NOT_NULL(f);
145 total_rd = 0;
146 do {
147 nr = fread(buf, 1, sizeof(buf), f);
148 for (i = 0; i < nr; i++)
149 PCUT_ASSERT_INT_EQUALS(0, buf[i]);
150
151 total_rd += nr;
152 } while (nr > 0);
153
154 PCUT_ASSERT_INT_EQUALS(20000, total_rd);
155
156 (void)fclose(f);
157
158 /* Remove the file. */
159 rv = remove(fname);
160 PCUT_ASSERT_INT_EQUALS(0, rv);
161
162 free(fname);
163 fmgt_destroy(fmgt);
164}
165
166/** New sparse file can be created. */
167PCUT_TEST(new_file_sparse)
168{
169 FILE *f = NULL;
170 fmgt_t *fmgt = NULL;
171 char *fname = NULL;
172 char buf[128];
173 errno_t rc;
174 size_t nr;
175 size_t total_rd;
176 size_t i;
177 int rv;
178
179 rc = vfs_cwd_set(TEMP_DIR);
180 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
181
182 rc = fmgt_create(&fmgt);
183 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
184
185 /* Suggest unique file name. */
186 rc = fmgt_new_file_suggest(&fname);
187 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
188
189 rc = fmgt_new_file(fmgt, fname, 20000, nf_sparse);
190 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
191
192 /* Verify the file. */
193 f = fopen(fname, "rb");
194 PCUT_ASSERT_NOT_NULL(f);
195 total_rd = 0;
196 do {
197 nr = fread(buf, 1, sizeof(buf), f);
198 for (i = 0; i < nr; i++)
199 PCUT_ASSERT_INT_EQUALS(0, buf[i]);
200
201 total_rd += nr;
202 } while (nr > 0);
203
204 PCUT_ASSERT_INT_EQUALS(20000, total_rd);
205
206 (void)fclose(f);
207
208 /* Remove the file. */
209 rv = remove(fname);
210 PCUT_ASSERT_INT_EQUALS(0, rv);
211
212 free(fname);
213 fmgt_destroy(fmgt);
214}
215
216/** Initial update provided when requested while creating new file. */
217PCUT_TEST(new_file_init_upd)
218{
219 FILE *f = NULL;
220 fmgt_t *fmgt = NULL;
221 char *fname = NULL;
222 char buf[128];
223 errno_t rc;
224 size_t nr;
225 size_t total_rd;
226 size_t i;
227 test_resp_t resp;
228 int rv;
229
230 rc = vfs_cwd_set(TEMP_DIR);
231 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
232
233 rc = fmgt_create(&fmgt);
234 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
235
236 fmgt_set_cb(fmgt, &test_fmgt_cb, (void *)&resp);
237 resp.nupdates = 0;
238
239 fmgt_set_init_update(fmgt, true);
240
241 /* Suggest unique file name. */
242 rc = fmgt_new_file_suggest(&fname);
243 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
244
245 rc = fmgt_new_file(fmgt, fname, 20000, nf_none);
246 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
247
248 /* Verify the file. */
249 f = fopen(fname, "rb");
250 PCUT_ASSERT_NOT_NULL(f);
251 total_rd = 0;
252 do {
253 nr = fread(buf, 1, sizeof(buf), f);
254 for (i = 0; i < nr; i++)
255 PCUT_ASSERT_INT_EQUALS(0, buf[i]);
256
257 total_rd += nr;
258 } while (nr > 0);
259
260 PCUT_ASSERT_INT_EQUALS(20000, total_rd);
261
262 (void)fclose(f);
263
264 PCUT_ASSERT_TRUE(resp.nupdates > 0);
265
266 /* Remove the file. */
267 rv = remove(fname);
268 PCUT_ASSERT_INT_EQUALS(0, rv);
269
270 free(fname);
271 fmgt_destroy(fmgt);
272}
273
274static void test_fmgt_progress(void *arg, fmgt_progress_t *progress)
275{
276 test_resp_t *resp = (test_resp_t *)arg;
277
278 (void)progress;
279 ++resp->nupdates;
280}
281
282PCUT_EXPORT(newfile);
Note: See TracBrowser for help on using the repository browser.