~vorlon/ubuntu/raring/upstart/lp.1199778

« back to all changes in this revision

Viewing changes to init/tests/test_conf.c

  • Committer: Scott James Remnant
  • Date: 2007-06-06 12:25:15 UTC
  • Revision ID: scott@netsplit.com-20070606122515-lrsv5qwjrd5una9m
* init/conf.c (conf_file_new): Rename to conf_file_get; in practice
we never just want to allocate one of these, we always want to
return the existing entry if it exists.
(conf_item_new): Rename to conf_item_set; again in practice we always
want to update an existing item.  This function will grow the "deal
with replacement" stuff.
(conf_reload): Start putting in place the code that will allow
mandatory reloads, as well as initial setup.  This function iterates
over the sources and deals with errors.
(conf_source_reload): Function to reload an individual source, calls
out to one of the following two functions and will eventually perform
the deleted items scan.
(conf_source_reload_file): Set up a watch on a file, and reload it.
(conf_source_reload_dir): Set up a watch on a directory and reload it.
(conf_file_filter): Filter for watching parent directory of files.
(conf_create_modify_handler): File creation and modification handler.
(conf_delete_handler): File deletion handler.
(conf_file_visitor): Tree walk handler.
(conf_reload_path): Function that deals with files themselves,
currently just sorts out the ConfFile structure and maps the file
into memory.
* init/conf.h: Add new prototypes, update existing ones.
* init/tests/test_conf.c (test_file_new): Rename to test_file_get,
also test repeated calls when already in the table.
(test_item_new): Rename to test_item_set, also test repeated calls
when already in the table.
(test_source_reload): Start of test for reloading sources.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
#include <nih/test.h>
24
24
 
 
25
#ifdef HAVE_SYS_INOTIFY_H
 
26
# include <sys/inotify.h>
 
27
#else
 
28
# include <nih/inotify.h>
 
29
#endif /* HAVE_SYS_INOTIFY_H */
 
30
 
 
31
#include <sys/types.h>
 
32
#include <sys/stat.h>
 
33
 
 
34
#include <fcntl.h>
 
35
#include <stdio.h>
 
36
#include <limits.h>
 
37
#include <string.h>
 
38
#include <unistd.h>
 
39
 
25
40
#include <nih/macros.h>
26
41
#include <nih/alloc.h>
27
42
#include <nih/list.h>
28
43
#include <nih/hash.h>
 
44
#include <nih/watch.h>
 
45
#include <nih/error.h>
29
46
 
30
47
#include "conf.h"
31
48
 
67
84
}
68
85
 
69
86
void
70
 
test_file_new (void)
 
87
test_file_get (void)
71
88
{
72
89
        ConfSource *source;
73
 
        ConfFile   *file;
 
90
        ConfFile   *conf_file, *ptr;
 
91
 
 
92
        TEST_FUNCTION ("conf_file_get");
 
93
        source = conf_source_new (NULL, "/tmp", CONF_JOB_DIR);
74
94
 
75
95
        /* Check that we can request a new ConfFile structure, it should be
76
96
         * allocated with nih_alloc and placed into the files hash table of
77
97
         * the source, with the flag copied.
78
98
         */
79
 
        TEST_FUNCTION ("conf_file_new");
80
 
        source = conf_source_new (NULL, "/tmp", CONF_JOB_DIR);
81
 
        source->flag = TRUE;
82
 
 
83
 
        TEST_ALLOC_FAIL {
84
 
                file = conf_file_new (NULL, source, "/tmp/foo");
85
 
 
86
 
                if (test_alloc_failed) {
87
 
                        TEST_EQ_P (file, NULL);
88
 
                        continue;
89
 
                }
90
 
 
91
 
                TEST_ALLOC_SIZE (file, sizeof (ConfFile));
92
 
                TEST_LIST_NOT_EMPTY (&file->entry);
93
 
                TEST_ALLOC_PARENT (file->path, file);
94
 
                TEST_EQ_STR (file->path, "/tmp/foo");
95
 
                TEST_EQ (file->flag, TRUE);
96
 
                TEST_NE_P (file->items, NULL);
97
 
 
98
 
                TEST_EQ_P ((void *)nih_hash_lookup (source->files, "/tmp/foo"),
99
 
                           file);
100
 
 
101
 
                nih_list_free (&file->entry);
102
 
        }
103
 
 
 
99
        TEST_FEATURE ("with new path");
 
100
        TEST_ALLOC_FAIL {
 
101
                conf_file = conf_file_get (source, "/tmp/foo");
 
102
 
 
103
                if (test_alloc_failed) {
 
104
                        TEST_EQ_P (conf_file, NULL);
 
105
                        continue;
 
106
                }
 
107
 
 
108
                TEST_ALLOC_SIZE (conf_file, sizeof (ConfFile));
 
109
                TEST_ALLOC_PARENT (conf_file, source);
 
110
                TEST_LIST_NOT_EMPTY (&conf_file->entry);
 
111
                TEST_ALLOC_PARENT (conf_file->path, conf_file);
 
112
                TEST_EQ_STR (conf_file->path, "/tmp/foo");
 
113
                TEST_EQ (conf_file->flag, source->flag);
 
114
                TEST_NE_P (conf_file->items, NULL);
 
115
 
 
116
                TEST_EQ_P ((void *)nih_hash_lookup (source->files, "/tmp/foo"),
 
117
                           conf_file);
 
118
 
 
119
                nih_list_free (&conf_file->entry);
 
120
        }
 
121
 
 
122
 
 
123
        /* Check that we can retrieve an existing ConfFile entry for a
 
124
         * source, and that the flag is updated to the new value.
 
125
         */
 
126
        TEST_FEATURE ("with existing path");
 
127
        conf_file = conf_file_get (source, "/tmp/foo");
 
128
        source->flag = (! source->flag);
 
129
 
 
130
        TEST_ALLOC_FAIL {
 
131
                ptr = conf_file_get (source, "/tmp/foo");
 
132
 
 
133
                if (test_alloc_failed) {
 
134
                        TEST_EQ_P (ptr, NULL);
 
135
                        continue;
 
136
                }
 
137
 
 
138
                TEST_EQ_P (ptr, conf_file);
 
139
 
 
140
                TEST_ALLOC_SIZE (conf_file, sizeof (ConfFile));
 
141
                TEST_ALLOC_PARENT (conf_file, source);
 
142
                TEST_LIST_NOT_EMPTY (&conf_file->entry);
 
143
                TEST_ALLOC_PARENT (conf_file->path, conf_file);
 
144
                TEST_EQ_STR (conf_file->path, "/tmp/foo");
 
145
                TEST_EQ (conf_file->flag, source->flag);
 
146
                TEST_NE_P (conf_file->items, NULL);
 
147
 
 
148
                TEST_EQ_P ((void *)nih_hash_lookup (source->files, "/tmp/foo"),
 
149
                           conf_file);
 
150
        }
 
151
 
 
152
        nih_list_free (&conf_file->entry);
104
153
        nih_list_free (&source->entry);
105
154
}
106
155
 
107
156
void
108
 
test_item_new (void)
 
157
test_item_set (void)
109
158
{
110
159
        ConfSource *source;
111
 
        ConfFile   *file;
112
 
        ConfItem   *item;
 
160
        ConfFile   *conf_file;
 
161
        ConfItem   *item, *ptr;
 
162
        Job        *job1, *job2;
 
163
 
 
164
        TEST_FUNCTION ("conf_item_set");
 
165
        source = conf_source_new (NULL, "/tmp", CONF_JOB_DIR);
 
166
        conf_file = conf_file_get (source, "/tmp/foo");
113
167
 
114
168
        /* Check that we can request a new Confitem structure, it should be
115
169
         * allocated with nih_alloc and placed into the items hash table of
116
170
         * the file, with the flag copied.
117
171
         */
118
 
        TEST_FUNCTION ("conf_item_new");
119
 
        source = conf_source_new (NULL, "/tmp", CONF_JOB_DIR);
120
 
        source->flag = TRUE;
121
 
 
122
 
        file = conf_file_new (NULL, source, "/tmp/foo");
 
172
        TEST_FEATURE ("with new item");
 
173
        job1 = job_new (NULL, "foo");
123
174
 
124
175
        TEST_ALLOC_FAIL {
125
 
                item = conf_item_new (NULL, file, "foo");
 
176
                item = conf_item_set (source, conf_file, "foo", job1);
126
177
 
127
178
                if (test_alloc_failed) {
128
179
                        TEST_EQ_P (item, NULL);
130
181
                }
131
182
 
132
183
                TEST_ALLOC_SIZE (item, sizeof (ConfItem));
 
184
                TEST_ALLOC_PARENT (item, conf_file);
133
185
                TEST_LIST_NOT_EMPTY (&item->entry);
134
186
                TEST_ALLOC_PARENT (item->name, item);
135
187
                TEST_EQ_STR (item->name, "foo");
136
 
                TEST_EQ (item->flag, TRUE);
137
 
                TEST_EQ_P (item->data, NULL);
 
188
                TEST_EQ (item->flag, conf_file->flag);
 
189
                TEST_EQ_P (item->data, job1);
138
190
 
139
 
                TEST_EQ_P ((void *)nih_hash_lookup (file->items, "foo"),
 
191
                TEST_EQ_P ((void *)nih_hash_lookup (conf_file->items, "foo"),
140
192
                           item);
141
193
 
142
194
                nih_list_free (&item->entry);
143
195
        }
144
196
 
145
 
        nih_list_free (&file->entry);
 
197
        /* Check that we can retrieve an existing ConfItem for a given name,
 
198
         * and that the flag and data are both updated to the new value.
 
199
         */
 
200
        TEST_FEATURE ("with existing item");
 
201
        item = conf_item_set (source, conf_file, "foo", job1);
 
202
        source->flag = (! source->flag);
 
203
 
 
204
        job2 = job_new (NULL, "foo");
 
205
 
 
206
        TEST_ALLOC_FAIL {
 
207
                ptr = conf_item_set (source, conf_file, "foo", job2);
 
208
 
 
209
                if (test_alloc_failed) {
 
210
                        TEST_EQ_P (ptr, NULL);
 
211
                        continue;
 
212
                }
 
213
 
 
214
                TEST_EQ_P (ptr, item);
 
215
 
 
216
                TEST_ALLOC_SIZE (item, sizeof (ConfItem));
 
217
                TEST_ALLOC_PARENT (item, conf_file);
 
218
                TEST_LIST_NOT_EMPTY (&item->entry);
 
219
                TEST_ALLOC_PARENT (item->name, item);
 
220
                TEST_EQ_STR (item->name, "foo");
 
221
                TEST_EQ (item->flag, conf_file->flag);
 
222
                TEST_EQ_P (item->data, job2);
 
223
 
 
224
                TEST_EQ_P ((void *)nih_hash_lookup (conf_file->items, "foo"),
 
225
                           item);
 
226
        }
 
227
 
 
228
        nih_list_free (&conf_file->entry);
146
229
        nih_list_free (&source->entry);
147
230
}
148
231
 
149
232
 
 
233
void
 
234
test_source_reload (void)
 
235
{
 
236
        ConfSource *source;
 
237
        FILE       *f;
 
238
        int         ret, fd[4096], i = 0;
 
239
        char        dirname[PATH_MAX], filename[PATH_MAX];
 
240
 
 
241
        TEST_FUNCTION ("conf_source_reload");
 
242
        TEST_FILENAME (dirname);
 
243
        mkdir (dirname, 0755);
 
244
 
 
245
        strcpy (filename, dirname);
 
246
        strcat (filename, "/foo");
 
247
 
 
248
        f = fopen (filename, "w");
 
249
        fprintf (f, "exec /sbin/daemon\n");
 
250
        fprintf (f, "respawn\n");
 
251
        fclose (f);
 
252
 
 
253
        /* Make sure that we have inotify before performing some tests... */
 
254
        if ((fd[0] = inotify_init ()) < 0) {
 
255
                printf ("SKIP: inotify not available\n");
 
256
                goto no_inotify;
 
257
        }
 
258
        close (fd[0]);
 
259
 
 
260
 
 
261
        /* Check that we can reload a new file source.  An inotify watch
 
262
         * should be established on the parent directory, and its file
 
263
         * descriptor set to be closed on exec.
 
264
         */
 
265
        TEST_FEATURE ("with new file source");
 
266
        strcpy (filename, dirname);
 
267
        strcat (filename, "/foo");
 
268
 
 
269
        TEST_ALLOC_FAIL {
 
270
                TEST_ALLOC_SAFE {
 
271
                        source = conf_source_new (NULL, filename, CONF_FILE);
 
272
                }
 
273
 
 
274
                ret = conf_source_reload (source);
 
275
 
 
276
                TEST_EQ (ret, 0);
 
277
                TEST_ALLOC_SIZE (source->watch, sizeof (NihWatch));
 
278
                TEST_EQ_STR (source->watch->path, dirname);
 
279
                TEST_EQ_P (source->watch->data, source);
 
280
 
 
281
                TEST_TRUE (fcntl (source->watch->fd, F_GETFD) & FD_CLOEXEC);
 
282
 
 
283
                nih_list_free (&source->entry);
 
284
        }
 
285
 
 
286
 
 
287
        /* Consume all available inotify instances so that the following
 
288
         * tests run without inotify.
 
289
         */
 
290
        for (i = 0; i < 4096; i++)
 
291
                if ((fd[i] = inotify_init ()) < 0)
 
292
                        break;
 
293
no_inotify:
 
294
 
 
295
 
 
296
        strcpy (filename, dirname);
 
297
        strcat (filename, "/foo");
 
298
        unlink (filename);
 
299
 
 
300
        rmdir (dirname);
 
301
}
 
302
 
 
303
 
150
304
int
151
305
main (int   argc,
152
306
      char *argv[])
153
307
{
154
308
        test_source_new ();
155
 
        test_file_new ();
156
 
        test_item_new ();
 
309
        test_file_get ();
 
310
        test_item_set ();
 
311
        test_source_reload ();
157
312
 
158
313
        return 0;
159
314
}