1
/* Copyright 2004-2005 The Apache Software Foundation or its licensors, as
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
17
#include "apr_file_io.h"
18
#include "apr_file_info.h"
19
#include "apr_errno.h"
20
#include "apr_general.h"
22
#include "apr_strings.h"
27
/* Only enable these tests by default on platforms which support sparse
28
* files... just Unixes? */
29
#if defined(WIN32) || defined(OS2) || defined(NETWARE)
30
static void test_nolfs(abts_case *tc, void *data)
32
ABTS_NOT_IMPL(tc, "Large Files tests require Sparse file support");
34
#elif APR_HAS_LARGE_FILES
37
/* Tests which create an 8Gb sparse file and then check it can be used
40
static apr_off_t eightGb = APR_INT64_C(2) << 32;
42
static int madefile = 0;
44
#define PRECOND if (!madefile) { ABTS_NOT_IMPL(tc, "Large file tests not enabled"); return; }
46
#define TESTDIR "lfstests"
47
#define TESTFILE "large.bin"
48
#define TESTFN "lfstests/large.bin"
50
static void test_open(abts_case *tc, void *data)
55
rv = apr_dir_make(TESTDIR, APR_OS_DEFAULT, p);
56
if (rv && !APR_STATUS_IS_EEXIST(rv)) {
57
APR_ASSERT_SUCCESS(tc, "make test directory", rv);
60
APR_ASSERT_SUCCESS(tc, "open file",
61
apr_file_open(&f, TESTFN,
62
APR_CREATE | APR_WRITE | APR_TRUNCATE,
65
rv = apr_file_trunc(f, eightGb);
67
APR_ASSERT_SUCCESS(tc, "close large file", apr_file_close(f));
69
/* 8Gb may pass rlimits or filesystem limits */
71
if (APR_STATUS_IS_EINVAL(rv)
76
ABTS_NOT_IMPL(tc, "Creation of large file (limited by rlimit or fs?)");
79
APR_ASSERT_SUCCESS(tc, "truncate file to 8gb", rv);
82
madefile = rv == APR_SUCCESS;
85
static void test_reopen(abts_case *tc, void *data)
92
APR_ASSERT_SUCCESS(tc, "re-open 8Gb file",
93
apr_file_open(&fh, TESTFN, APR_READ, APR_OS_DEFAULT, p));
95
APR_ASSERT_SUCCESS(tc, "file_info_get failed",
96
apr_file_info_get(&finfo, APR_FINFO_NORM, fh));
98
ABTS_ASSERT(tc, "file_info_get gave incorrect size",
99
finfo.size == eightGb);
101
APR_ASSERT_SUCCESS(tc, "re-close large file", apr_file_close(fh));
104
static void test_stat(abts_case *tc, void *data)
110
APR_ASSERT_SUCCESS(tc, "stat large file",
111
apr_stat(&finfo, TESTFN, APR_FINFO_NORM, p));
113
ABTS_ASSERT(tc, "stat gave incorrect size", finfo.size == eightGb);
116
static void test_readdir(abts_case *tc, void *data)
123
APR_ASSERT_SUCCESS(tc, "open test directory",
124
apr_dir_open(&dh, TESTDIR, p));
129
rv = apr_dir_read(&finfo, APR_FINFO_NORM, dh);
131
if (rv == APR_SUCCESS && strcmp(finfo.name, TESTFILE) == 0) {
132
ABTS_ASSERT(tc, "apr_dir_read gave incorrect size for large file",
133
finfo.size == eightGb);
136
} while (rv == APR_SUCCESS);
138
if (!APR_STATUS_IS_ENOENT(rv)) {
139
APR_ASSERT_SUCCESS(tc, "apr_dir_read failed", rv);
142
APR_ASSERT_SUCCESS(tc, "close test directory",
146
#define TESTSTR "Hello, world."
148
static void test_append(abts_case *tc, void *data)
155
APR_ASSERT_SUCCESS(tc, "open 8Gb file for append",
156
apr_file_open(&fh, TESTFN, APR_WRITE | APR_APPEND,
159
APR_ASSERT_SUCCESS(tc, "append to 8Gb file",
160
apr_file_write_full(fh, TESTSTR, strlen(TESTSTR), NULL));
162
APR_ASSERT_SUCCESS(tc, "file_info_get failed",
163
apr_file_info_get(&finfo, APR_FINFO_NORM, fh));
165
ABTS_ASSERT(tc, "file_info_get gave incorrect size",
166
finfo.size == eightGb + strlen(TESTSTR));
168
APR_ASSERT_SUCCESS(tc, "close 8Gb file", apr_file_close(fh));
171
static void test_seek(abts_case *tc, void *data)
178
APR_ASSERT_SUCCESS(tc, "open 8Gb file for writing",
179
apr_file_open(&fh, TESTFN, APR_WRITE,
183
APR_ASSERT_SUCCESS(tc, "relative seek to end",
184
apr_file_seek(fh, APR_END, &pos));
185
ABTS_ASSERT(tc, "seek to END gave 8Gb", pos == eightGb);
188
APR_ASSERT_SUCCESS(tc, "seek to 8Gb", apr_file_seek(fh, APR_SET, &pos));
189
ABTS_ASSERT(tc, "seek gave 8Gb offset", pos == eightGb);
192
APR_ASSERT_SUCCESS(tc, "relative seek to 0", apr_file_seek(fh, APR_CUR, &pos));
193
ABTS_ASSERT(tc, "relative seek gave 8Gb offset", pos == eightGb);
198
static void test_write(abts_case *tc, void *data)
201
apr_off_t pos = eightGb - 4;
205
APR_ASSERT_SUCCESS(tc, "re-open 8Gb file",
206
apr_file_open(&fh, TESTFN, APR_WRITE, APR_OS_DEFAULT, p));
208
APR_ASSERT_SUCCESS(tc, "seek to 8Gb - 4",
209
apr_file_seek(fh, APR_SET, &pos));
210
ABTS_ASSERT(tc, "seek gave 8Gb-4 offset", pos == eightGb - 4);
212
APR_ASSERT_SUCCESS(tc, "write magic string to 8Gb-4",
213
apr_file_write_full(fh, "FISH", 4, NULL));
215
APR_ASSERT_SUCCESS(tc, "close 8Gb file", apr_file_close(fh));
220
static void test_mmap(abts_case *tc, void *data)
224
apr_size_t len = 16384; /* hopefully a multiple of the page size */
225
apr_off_t off = eightGb - len;
230
APR_ASSERT_SUCCESS(tc, "open 8gb file for mmap",
231
apr_file_open(&fh, TESTFN, APR_READ, APR_OS_DEFAULT, p));
233
APR_ASSERT_SUCCESS(tc, "mmap 8Gb file",
234
apr_mmap_create(&map, fh, off, len, APR_MMAP_READ, p));
236
APR_ASSERT_SUCCESS(tc, "close file", apr_file_close(fh));
238
ABTS_ASSERT(tc, "mapped a 16K block", map->size == len);
240
APR_ASSERT_SUCCESS(tc, "get pointer into mmaped region",
241
apr_mmap_offset(&ptr, map, len - 4));
242
ABTS_ASSERT(tc, "pointer was not NULL", ptr != NULL);
244
ABTS_ASSERT(tc, "found the magic string", memcmp(ptr, "FISH", 4) == 0);
246
APR_ASSERT_SUCCESS(tc, "delete mmap handle", apr_mmap_delete(map));
248
#endif /* APR_HAS_MMAP */
250
static void test_format(abts_case *tc, void *data)
256
off = apr_atoi64(apr_off_t_toa(p, eightGb));
258
ABTS_ASSERT(tc, "apr_atoi64 parsed apr_off_t_toa result incorrectly",
263
static void test_nolfs(abts_case *tc, void *data)
265
ABTS_NOT_IMPL(tc, "Large Files not supported");
269
abts_suite *testlfs(abts_suite *suite)
271
suite = ADD_SUITE(suite)
274
abts_run_test(suite, test_open, NULL);
275
abts_run_test(suite, test_reopen, NULL);
276
abts_run_test(suite, test_stat, NULL);
277
abts_run_test(suite, test_readdir, NULL);
278
abts_run_test(suite, test_seek, NULL);
279
abts_run_test(suite, test_append, NULL);
280
abts_run_test(suite, test_write, NULL);
282
abts_run_test(suite, test_mmap, NULL);
284
abts_run_test(suite, test_format, NULL);
286
abts_run_test(suite, test_nolfs, NULL);