a6d1929fb51c0e9f3273fe209e8a46ae219f9aad
[samba.git] / lib / util / tests / file.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    util_file testing
5
6    Copyright (C) Jelmer Vernooij 2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "lib/util/util_file.h"
24 #include "system/filesys.h"
25 #include "torture/torture.h"
26 #include "torture/local/proto.h"
27
28 #define TEST_FILENAME "utilfile.test"
29 #define TEST_LINE1 "This is list line 1..."
30 #define TEST_LINE2 ".. and this is line 2"
31 #define TEST_LINE3 "and end of the file"
32
33 #define TEST_DATA TEST_LINE1 "\n" TEST_LINE2 "\n" TEST_LINE3
34
35 static bool test_file_load_save(struct torture_context *tctx)
36 {
37         size_t len;
38         char *data;
39         TALLOC_CTX *mem_ctx = tctx;
40         
41         torture_assert(tctx, file_save(TEST_FILENAME, TEST_DATA, strlen(TEST_DATA)),
42                                    "saving file");
43
44         torture_assert_file_contains_text(tctx, TEST_FILENAME, TEST_DATA, 
45                                                                       "file contents");
46
47         data = file_load(TEST_FILENAME, &len, 0, mem_ctx);
48         torture_assert(tctx, data, "loading file");
49
50         torture_assert_int_equal(tctx, len, strlen(TEST_DATA), "Length");
51         
52         torture_assert_mem_equal(tctx, data, TEST_DATA, len, "Contents");
53
54         data = file_load(TEST_FILENAME, &len, 5, mem_ctx);
55
56         torture_assert_int_equal(tctx, len, 5, "Length");
57
58         torture_assert_mem_equal(tctx, data, TEST_DATA, len, "Contents");
59
60         unlink(TEST_FILENAME);
61         return true;
62 }
63
64 #define TEST_DATA_WITH_NEWLINE TEST_DATA "\n"
65 #define TEST_DATA_NO_NEWLINE TEST_DATA
66 #define TEST_DATA_EMPTY ""
67 #define TEST_DATA_BLANKS_ONLY "\n\n\n\n\n"
68 #define TEST_DATA_WITH_TRAILING_BLANKS TEST_DATA TEST_DATA_BLANKS_ONLY
69
70 static bool test_file_lines_load(struct torture_context *tctx)
71 {
72         char **lines;
73         int numlines;
74         TALLOC_CTX *mem_ctx = tctx;
75
76         /*
77          * Last line has trailing whitespace
78          */
79
80         torture_assert(tctx,
81                        file_save(TEST_FILENAME,
82                                  TEST_DATA_WITH_NEWLINE,
83                                  strlen(TEST_DATA_WITH_NEWLINE)),
84                        "saving file");
85
86         lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
87
88         torture_assert_int_equal(tctx, numlines, 3, "Lines");
89
90         torture_assert_mem_equal(tctx,
91                                  lines[0],
92                                  TEST_LINE1,
93                                  strlen(TEST_LINE1),
94                                  "Line 1");
95
96         torture_assert_mem_equal(tctx,
97                                  lines[1],
98                                  TEST_LINE2,
99                                  strlen(TEST_LINE2),
100                                  "Line 2");
101
102         torture_assert_mem_equal(tctx,
103                                  lines[2],
104                                  TEST_LINE3,
105                                  strlen(TEST_LINE3),
106                                  "Line 3");
107
108         unlink(TEST_FILENAME);
109
110         /*
111          * Last line has NO trailing whitespace
112          */
113
114         torture_assert(tctx,
115                        file_save(TEST_FILENAME,
116                                  TEST_DATA_NO_NEWLINE,
117                                  strlen(TEST_DATA_NO_NEWLINE)),
118                        "saving file");
119
120         lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
121
122         torture_assert_int_equal(tctx, numlines, 3, "Lines");
123
124         torture_assert_mem_equal(tctx,
125                                  lines[0],
126                                  TEST_LINE1,
127                                  strlen(TEST_LINE1),
128                                  "Line 1");
129
130         torture_assert_mem_equal(tctx,
131                                  lines[1],
132                                  TEST_LINE2,
133                                  strlen(TEST_LINE2),
134                                  "Line 2");
135
136         torture_assert_mem_equal(tctx,
137                                  lines[2],
138                                  TEST_LINE3,
139                                  strlen(TEST_LINE3),
140                                  "Line 3");
141
142         unlink(TEST_FILENAME);
143
144         /*
145          * Empty file
146          */
147
148         torture_assert(tctx,
149                        file_save(TEST_FILENAME,
150                                  TEST_DATA_EMPTY,
151                                  strlen(TEST_DATA_EMPTY)),
152                        "saving file");
153
154         (void)file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
155
156         torture_assert_int_equal(tctx, numlines, 0, "Lines");
157
158         unlink(TEST_FILENAME);
159
160         /*
161          * Just blank lines
162          */
163
164         torture_assert(tctx,
165                        file_save(TEST_FILENAME,
166                                  TEST_DATA_BLANKS_ONLY,
167                                  strlen(TEST_DATA_BLANKS_ONLY)),
168                        "saving file");
169
170         lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
171
172         torture_assert_int_equal(tctx, numlines, 0, "Lines");
173
174         unlink(TEST_FILENAME);
175
176         /*
177          * Several trailing blank lines
178          */
179
180         torture_assert(tctx,
181                        file_save(TEST_FILENAME,
182                                  TEST_DATA_WITH_TRAILING_BLANKS,
183                                  strlen(TEST_DATA_WITH_TRAILING_BLANKS)),
184                        "saving file");
185
186         lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
187
188         torture_assert_int_equal(tctx, numlines, 3, "Lines");
189
190         torture_assert_mem_equal(tctx,
191                                  lines[0],
192                                  TEST_LINE1,
193                                  strlen(TEST_LINE1),
194                                  "Line 1");
195
196         torture_assert_mem_equal(tctx,
197                                  lines[1],
198                                  TEST_LINE2,
199                                  strlen(TEST_LINE2),
200                                  "Line 2");
201
202         torture_assert_mem_equal(tctx,
203                                  lines[2],
204                                  TEST_LINE3,
205                                  strlen(TEST_LINE3),
206                                  "Line 3");
207
208         unlink(TEST_FILENAME);
209
210         return true;
211 }
212
213 static bool test_afdgets(struct torture_context *tctx)
214 {
215         int fd;
216         char *line;
217         TALLOC_CTX *mem_ctx = tctx;
218         bool ret = false;
219         
220         torture_assert(tctx, file_save(TEST_FILENAME, (const void *)TEST_DATA, 
221                                                          strlen(TEST_DATA)),
222                                    "saving file");
223
224         fd = open(TEST_FILENAME, O_RDONLY);
225         
226         torture_assert(tctx, fd != -1, "opening file");
227
228         line = afdgets(fd, mem_ctx, 8);
229         torture_assert_goto(tctx, strcmp(line, TEST_LINE1) == 0, ret, done,
230                             "line 1 mismatch");
231
232         line = afdgets(fd, mem_ctx, 8);
233         torture_assert_goto(tctx, strcmp(line, TEST_LINE2) == 0, ret, done,
234                             "line 2 mismatch");
235
236         line = afdgets(fd, mem_ctx, 8);
237         torture_assert_goto(tctx, strcmp(line, TEST_LINE3) == 0, ret, done,
238                             "line 3 mismatch");
239         ret = true;
240 done:
241         close(fd);
242
243         unlink(TEST_FILENAME);
244         return ret;
245 }
246
247 static bool test_file_lines_parse(struct torture_context *tctx)
248 {
249         char **lines;
250         int numlines;
251         TALLOC_CTX *mem_ctx = tctx;
252         char *buf;
253         size_t size;
254
255         torture_assert(tctx, file_save(TEST_FILENAME,
256                                        (const void *)TEST_DATA,
257                                        strlen(TEST_DATA)),
258                         "saving file");
259
260         buf = file_load(TEST_FILENAME, &size, 0, mem_ctx);
261         torture_assert(tctx, buf, "failed to load file");
262         unlink(TEST_FILENAME);
263
264         lines = file_lines_parse(buf,
265                                  size,
266                                  &numlines,
267                                  mem_ctx);
268         torture_assert(tctx, lines, "failed to parse lines");
269
270         TALLOC_FREE(lines);
271         TALLOC_FREE(buf);
272         return true;
273 }
274
275 struct torture_suite *torture_local_util_file(TALLOC_CTX *mem_ctx)
276 {
277         struct torture_suite *suite = torture_suite_create(mem_ctx, "file");
278
279         torture_suite_add_simple_test(suite, "file_load_save", 
280                                       test_file_load_save);
281
282         torture_suite_add_simple_test(suite,
283                                       "file_lines_load",
284                                       test_file_lines_load);
285
286         torture_suite_add_simple_test(suite, "afdgets", test_afdgets);
287
288         torture_suite_add_simple_test(suite, "file_lines_parse",
289                         test_file_lines_parse);
290
291         return suite;
292 }