~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to srclib/apr/test/testfileinfo.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 
2
 * applicable.
 
3
 *
 
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
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
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.
 
15
 */
 
16
 
 
17
#include "apr_file_io.h"
 
18
#include "apr_file_info.h"
 
19
#include "apr_strings.h"
 
20
#include "apr_errno.h"
 
21
#include "apr_general.h"
 
22
#include "apr_poll.h"
 
23
#include "apr_lib.h"
 
24
#include "testutil.h"
 
25
 
 
26
#define FILENAME "data/file_datafile.txt"
 
27
#define NEWFILENAME "data/new_datafile.txt"
 
28
#define NEWFILEDATA "This is new text in a new file."
 
29
 
 
30
static const struct view_fileinfo
 
31
{
 
32
    apr_int32_t bits;
 
33
    char *description;
 
34
} vfi[] = {
 
35
    {APR_FINFO_MTIME,  "MTIME"},
 
36
    {APR_FINFO_CTIME,  "CTIME"},
 
37
    {APR_FINFO_ATIME,  "ATIME"},
 
38
    {APR_FINFO_SIZE,   "SIZE"},
 
39
    {APR_FINFO_DEV,    "DEV"},
 
40
    {APR_FINFO_INODE,  "INODE"},
 
41
    {APR_FINFO_NLINK,  "NLINK"},
 
42
    {APR_FINFO_TYPE,   "TYPE"},
 
43
    {APR_FINFO_USER,   "USER"}, 
 
44
    {APR_FINFO_GROUP,  "GROUP"}, 
 
45
    {APR_FINFO_UPROT,  "UPROT"}, 
 
46
    {APR_FINFO_GPROT,  "GPROT"},
 
47
    {APR_FINFO_WPROT,  "WPROT"},
 
48
    {0,                NULL}
 
49
}; 
 
50
 
 
51
static void finfo_equal(abts_case *tc, apr_finfo_t *f1, apr_finfo_t *f2)
 
52
{
 
53
    /* Minimum supported flags across all platforms (APR_FINFO_MIN) */
 
54
    ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo must return APR_FINFO_TYPE",
 
55
             (f1->valid & f2->valid & APR_FINFO_TYPE));
 
56
    ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in filetype",
 
57
             f1->filetype == f2->filetype);
 
58
    ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo must return APR_FINFO_SIZE",
 
59
             (f1->valid & f2->valid & APR_FINFO_SIZE));
 
60
    ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in size",
 
61
             f1->size == f2->size);
 
62
    ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo must return APR_FINFO_ATIME",
 
63
             (f1->valid & f2->valid & APR_FINFO_ATIME));
 
64
    ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in atime",
 
65
             f1->atime == f2->atime);
 
66
    ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo must return APR_FINFO_MTIME",
 
67
             (f1->valid & f2->valid & APR_FINFO_MTIME));
 
68
    ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in mtime",
 
69
             f1->mtime == f2->mtime);
 
70
    ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo must return APR_FINFO_CTIME",
 
71
             (f1->valid & f2->valid & APR_FINFO_CTIME));
 
72
    ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in ctime",
 
73
             f1->ctime == f2->ctime);
 
74
 
 
75
    if (f1->valid & f2->valid & APR_FINFO_NAME)
 
76
        ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in name",
 
77
                 !strcmp(f1->name, f2->name));
 
78
    if (f1->fname && f2->fname)
 
79
        ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in fname",
 
80
                 !strcmp(f1->fname, f2->fname));
 
81
 
 
82
    /* Additional supported flags not supported on all platforms */
 
83
    if (f1->valid & f2->valid & APR_FINFO_USER)
 
84
        ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in user",
 
85
                 !apr_uid_compare(f1->user, f2->user));
 
86
    if (f1->valid & f2->valid & APR_FINFO_GROUP)
 
87
        ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in group",
 
88
                 !apr_gid_compare(f1->group, f2->group));
 
89
    if (f1->valid & f2->valid & APR_FINFO_INODE)
 
90
        ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in inode",
 
91
                 f1->inode == f2->inode);
 
92
    if (f1->valid & f2->valid & APR_FINFO_DEV)
 
93
        ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in device",
 
94
                 f1->device == f2->device);
 
95
    if (f1->valid & f2->valid & APR_FINFO_NLINK)
 
96
        ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in nlink",
 
97
                 f1->nlink == f2->nlink);
 
98
    if (f1->valid & f2->valid & APR_FINFO_CSIZE)
 
99
        ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in csize",
 
100
                 f1->csize == f2->csize);
 
101
    if (f1->valid & f2->valid & APR_FINFO_PROT)
 
102
        ABTS_ASSERT(tc, "apr_stat and apr_getfileinfo differ in protection",
 
103
                 f1->protection == f2->protection);
 
104
}
 
105
 
 
106
static void test_info_get(abts_case *tc, void *data)
 
107
{
 
108
    apr_file_t *thefile;
 
109
    apr_finfo_t finfo;
 
110
    apr_status_t rv;
 
111
 
 
112
    rv = apr_file_open(&thefile, FILENAME, APR_READ, APR_OS_DEFAULT, p);
 
113
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
114
 
 
115
    rv = apr_file_info_get(&finfo, APR_FINFO_NORM, thefile);
 
116
    if (rv  == APR_INCOMPLETE) {
 
117
        char *str;
 
118
        int i;
 
119
        str = apr_pstrdup(p, "APR_INCOMPLETE:  Missing ");
 
120
        for (i = 0; vfi[i].bits; ++i) {
 
121
            if (vfi[i].bits & ~finfo.valid) {
 
122
                str = apr_pstrcat(p, str, vfi[i].description, " ", NULL);
 
123
            }
 
124
        }
 
125
        ABTS_FAIL(tc, str);
 
126
    }
 
127
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
128
    apr_file_close(thefile);
 
129
}
 
130
 
 
131
static void test_stat(abts_case *tc, void *data)
 
132
{
 
133
    apr_finfo_t finfo;
 
134
    apr_status_t rv;
 
135
 
 
136
    rv = apr_stat(&finfo, FILENAME, APR_FINFO_NORM, p);
 
137
    if (rv  == APR_INCOMPLETE) {
 
138
        char *str;
 
139
        int i;
 
140
        str = apr_pstrdup(p, "APR_INCOMPLETE:  Missing ");
 
141
        for (i = 0; vfi[i].bits; ++i) {
 
142
            if (vfi[i].bits & ~finfo.valid) {
 
143
                str = apr_pstrcat(p, str, vfi[i].description, " ", NULL);
 
144
            }
 
145
        }
 
146
        ABTS_FAIL(tc, str);
 
147
    }
 
148
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
149
}
 
150
 
 
151
static void test_stat_eq_finfo(abts_case *tc, void *data)
 
152
{
 
153
    apr_file_t *thefile;
 
154
    apr_finfo_t finfo;
 
155
    apr_finfo_t stat_finfo;
 
156
    apr_status_t rv;
 
157
 
 
158
    rv = apr_file_open(&thefile, FILENAME, APR_READ, APR_OS_DEFAULT, p);
 
159
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
160
    rv = apr_file_info_get(&finfo, APR_FINFO_NORM, thefile);
 
161
 
 
162
    /* Opening the file may have toggled the atime member (time last
 
163
     * accessed), so fetch our apr_stat() after getting the fileinfo 
 
164
     * of the open file...
 
165
     */
 
166
    rv = apr_stat(&stat_finfo, FILENAME, APR_FINFO_NORM, p);
 
167
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
168
 
 
169
    apr_file_close(thefile);
 
170
 
 
171
    finfo_equal(tc, &stat_finfo, &finfo);
 
172
}
 
173
 
 
174
static void test_buffered_write_size(abts_case *tc, void *data)
 
175
{
 
176
    const apr_size_t data_len = strlen(NEWFILEDATA);
 
177
    apr_file_t *thefile;
 
178
    apr_finfo_t finfo;
 
179
    apr_status_t rv;
 
180
    apr_size_t bytes;
 
181
 
 
182
    rv = apr_file_open(&thefile, NEWFILENAME,
 
183
                       APR_READ | APR_WRITE | APR_CREATE | APR_TRUNCATE
 
184
                       | APR_BUFFERED | APR_DELONCLOSE,
 
185
                       APR_OS_DEFAULT, p);
 
186
    APR_ASSERT_SUCCESS(tc, "open file", rv);
 
187
 
 
188
    /* A funny thing happened to me the other day: I wrote something
 
189
     * into a buffered file, then asked for its size using
 
190
     * apr_file_info_get; and guess what? The size was 0! That's not a
 
191
     * nice way to behave.
 
192
     */
 
193
    bytes = data_len;
 
194
    rv = apr_file_write(thefile, NEWFILEDATA, &bytes);
 
195
    APR_ASSERT_SUCCESS(tc, "write file contents", rv);
 
196
    ABTS_TRUE(tc, data_len == bytes);
 
197
 
 
198
    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, thefile);
 
199
    APR_ASSERT_SUCCESS(tc, "get file size", rv);
 
200
    ABTS_TRUE(tc, bytes == (apr_size_t) finfo.size);
 
201
    apr_file_close(thefile);
 
202
}
 
203
 
 
204
static void test_mtime_set(abts_case *tc, void *data)
 
205
{
 
206
    apr_file_t *thefile;
 
207
    apr_finfo_t finfo;
 
208
    apr_time_t epoch = 0;
 
209
    apr_status_t rv;
 
210
 
 
211
    /* This test sort of depends on the system clock being at least
 
212
     * marginally ccorrect; We'll be setting the modification time to
 
213
     * the epoch.
 
214
     */
 
215
    rv = apr_file_open(&thefile, NEWFILENAME,
 
216
                       APR_READ | APR_WRITE | APR_CREATE | APR_TRUNCATE
 
217
                       | APR_BUFFERED | APR_DELONCLOSE,
 
218
                       APR_OS_DEFAULT, p);
 
219
    APR_ASSERT_SUCCESS(tc, "open file", rv);
 
220
 
 
221
    /* Check that the current mtime is not the epoch */
 
222
    rv = apr_stat(&finfo, NEWFILENAME, APR_FINFO_MTIME, p);
 
223
    if (rv  == APR_INCOMPLETE) {
 
224
        char *str;
 
225
        int i;
 
226
        str = apr_pstrdup(p, "APR_INCOMPLETE:  Missing ");
 
227
        for (i = 0; vfi[i].bits; ++i) {
 
228
            if (vfi[i].bits & ~finfo.valid) {
 
229
                str = apr_pstrcat(p, str, vfi[i].description, " ", NULL);
 
230
            }
 
231
        }
 
232
        ABTS_FAIL(tc, str);
 
233
    }
 
234
    APR_ASSERT_SUCCESS(tc, "get initial mtime", rv);
 
235
    ABTS_TRUE(tc, finfo.mtime != epoch);
 
236
 
 
237
    /* Reset the mtime to the epoch and verify the result.
 
238
     * Note: we blindly assume that if the first apr_stat succeeded,
 
239
     * the second one will, too.
 
240
     */
 
241
    rv = apr_file_mtime_set(NEWFILENAME, epoch, p);
 
242
    APR_ASSERT_SUCCESS(tc, "set mtime", rv);
 
243
 
 
244
    rv = apr_stat(&finfo, NEWFILENAME, APR_FINFO_MTIME, p);
 
245
    APR_ASSERT_SUCCESS(tc, "get modified mtime", rv);
 
246
    ABTS_TRUE(tc, finfo.mtime == epoch);
 
247
 
 
248
    apr_file_close(thefile);
 
249
}
 
250
 
 
251
abts_suite *testfileinfo(abts_suite *suite)
 
252
{
 
253
    suite = ADD_SUITE(suite)
 
254
 
 
255
    abts_run_test(suite, test_info_get, NULL);
 
256
    abts_run_test(suite, test_stat, NULL);
 
257
    abts_run_test(suite, test_stat_eq_finfo, NULL);
 
258
    abts_run_test(suite, test_buffered_write_size, NULL);
 
259
    abts_run_test(suite, test_mtime_set, NULL);
 
260
 
 
261
    return suite;
 
262
}
 
263