~ubuntu-branches/ubuntu/saucy/augeas/saucy-proposed

« back to all changes in this revision

Viewing changes to tests/test-run.c

  • Committer: Package Import Robot
  • Author(s): Nicolas Valcárcel Scerpella
  • Date: 2011-11-10 09:20:03 UTC
  • mto: (1.5.1) (19.1.11 precise)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: package-import@ubuntu.com-20111110092003-sb3z6bq97rlb96de
Tags: upstream-0.9.0
Import upstream version 0.9.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * test-run.c: test the aug_srun API function
 
3
 *
 
4
 * Copyright (C) 2009 Red Hat Inc.
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Lesser General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2.1 of the License, or (at your option) any later version.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public
 
17
 * License along with this library; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 
19
 *
 
20
 * Author: David Lutterkort <lutter@redhat.com>
 
21
 */
 
22
 
 
23
#include <config.h>
 
24
 
 
25
#include <stdlib.h>
 
26
#include <stdio.h>
 
27
#include <ctype.h>
 
28
 
 
29
#include "augeas.h"
 
30
 
 
31
#include "cutest.h"
 
32
#include "internal.h"
 
33
#include <memory.h>
 
34
 
 
35
#include <unistd.h>
 
36
 
 
37
static const char *abs_top_srcdir;
 
38
 
 
39
#define KW_TEST "test"
 
40
#define KW_PRINTS "prints"
 
41
#define KW_SOMETHING "something"
 
42
 
 
43
/* This array needs to be kept in sync with aug_errcode_t, and
 
44
 * the entries need to be in the same order as in that enum; used
 
45
 * by errtok
 
46
 */
 
47
static const char *const errtokens[] = {
 
48
    "NOERROR", "ENOMEM", "EINTERNAL", "EPATHX", "ENOMATCH",
 
49
    "EMMATCH", "ESYNTAX", "ENOLENS", "EMXFM", "ENOSPAN",
 
50
    "EMVDESC", "ECMDRUN"
 
51
};
 
52
 
 
53
struct test {
 
54
    struct test *next;
 
55
    char *name;
 
56
    int  result;
 
57
    int  errcode;
 
58
    char *cmd;
 
59
    char *out;
 
60
    bool  out_present;
 
61
};
 
62
 
 
63
#define die(msg)                                                    \
 
64
    do {                                                            \
 
65
        fprintf(stderr, "%d: Fatal error: %s\n", __LINE__, msg);    \
 
66
        exit(EXIT_FAILURE);                                         \
 
67
    } while(0)
 
68
 
 
69
static char *skipws(char *s) {
 
70
    while (isspace(*s)) s++;
 
71
    return s;
 
72
}
 
73
 
 
74
static char *findws(char *s) {
 
75
    while (*s && ! isspace(*s)) s++;
 
76
    return s;
 
77
}
 
78
 
 
79
static char *token(char *s, char **tok) {
 
80
    char *t = skipws(s);
 
81
    s = findws(t);
 
82
    *tok = strndup(t, s - t);
 
83
    return s;
 
84
}
 
85
 
 
86
static char *inttok(char *s, int *tok) {
 
87
    char *t = skipws(s);
 
88
    s = findws(t);
 
89
    *tok = strtol(t, NULL, 10);
 
90
    return s;
 
91
}
 
92
 
 
93
static char *errtok(char *s, int *err) {
 
94
    char *t = skipws(s);
 
95
    s = findws(t);
 
96
    if (s == t) {
 
97
        *err = AUG_NOERROR;
 
98
        return s;
 
99
    }
 
100
    for (*err = 0; *err < ARRAY_CARDINALITY(errtokens); *err += 1) {
 
101
        const char *e = errtokens[*err];
 
102
        if (strlen(e) == s - t && STREQLEN(e, t, s - t))
 
103
            return s;
 
104
    }
 
105
    fprintf(stderr, "errtok: '%s'\n", t);
 
106
    die("unknown error code");
 
107
}
 
108
 
 
109
static bool looking_at(const char *s, const char *kw) {
 
110
    return STREQLEN(s, kw, strlen(kw));
 
111
}
 
112
 
 
113
static struct test *read_tests(void) {
 
114
    char *fname;
 
115
    FILE *fp;
 
116
    char line[BUFSIZ];
 
117
    struct test *result = NULL, *t = NULL;
 
118
    int lc = 0;
 
119
    bool append_cmd = true;
 
120
 
 
121
    if (asprintf(&fname, "%s/tests/run.tests", abs_top_srcdir) < 0)
 
122
        die("asprintf fname");
 
123
 
 
124
    if ((fp = fopen(fname, "r")) == NULL)
 
125
        die("fopen run.tests");
 
126
 
 
127
    while (fgets(line, BUFSIZ, fp) != NULL) {
 
128
        lc += 1;
 
129
        char *s = skipws(line);
 
130
        if (*s == '#' || *s == '\0')
 
131
            continue;
 
132
        if (*s == ':')
 
133
            s += 1;
 
134
        if (looking_at(s, KW_TEST)) {
 
135
            if (ALLOC(t) < 0)
 
136
                die_oom();
 
137
            list_append(result, t);
 
138
            append_cmd = true;
 
139
            s = token(s + strlen(KW_TEST), &(t->name));
 
140
            s = inttok(s, &t->result);
 
141
            s = errtok(s, &t->errcode);
 
142
        } else if (looking_at(s, KW_PRINTS)) {
 
143
            s = skipws(s + strlen(KW_PRINTS));
 
144
            t->out_present = looking_at(s, KW_SOMETHING);
 
145
            append_cmd = false;
 
146
        } else {
 
147
            char **buf = append_cmd ? &(t->cmd) : &(t->out);
 
148
            if (*buf == NULL) {
 
149
                *buf = strdup(s);
 
150
                if (*buf == NULL)
 
151
                    die_oom();
 
152
            } else {
 
153
                if (REALLOC_N(*buf, strlen(*buf) + strlen(s) + 1) < 0)
 
154
                    die_oom();
 
155
                strcat(*buf, s);
 
156
            }
 
157
        }
 
158
        if (t->out != NULL)
 
159
            t->out_present = true;
 
160
    }
 
161
    return result;
 
162
}
 
163
 
 
164
#define fail(cond, msg ...)                     \
 
165
    if (cond) {                                 \
 
166
        printf("FAIL (");                       \
 
167
        fprintf(stdout, ## msg);                \
 
168
        printf(")\n");                          \
 
169
        goto error;                             \
 
170
    }
 
171
 
 
172
static int run_one_test(struct test *test) {
 
173
    int r;
 
174
    struct augeas *aug = NULL;
 
175
    struct memstream ms;
 
176
    int result = 0;
 
177
 
 
178
    aug = aug_init("/dev/null", NULL, AUG_NO_STDINC|AUG_NO_LOAD);
 
179
    fail(aug == NULL, "aug_init");
 
180
    fail(aug_error(aug) != AUG_NOERROR, "aug_init: errcode was %d",
 
181
         aug_error(aug));
 
182
 
 
183
    printf("%-30s ... ", test->name);
 
184
 
 
185
    r = init_memstream(&ms);
 
186
    fail(r < 0, "init_memstream");
 
187
 
 
188
    r = aug_srun(aug, ms.stream, test->cmd);
 
189
    fail(r != test->result, "return value: expected %d, actual %d",
 
190
         test->result, r);
 
191
    fail(aug_error(aug) != test->errcode, "errcode: expected %s, actual %s",
 
192
         errtokens[test->errcode], errtokens[aug_error(aug)]);
 
193
 
 
194
    r = close_memstream(&ms);
 
195
    fail(r < 0, "close_memstream");
 
196
    fail(ms.buf == NULL, "close_memstream left buf NULL");
 
197
 
 
198
    if (test->out != NULL) {
 
199
        fail(STRNEQ(ms.buf, test->out), "output: expected '%s', actual '%s'",
 
200
             test->out, ms.buf);
 
201
    } else if (test->out_present) {
 
202
        fail(strlen(ms.buf) == 0,
 
203
             "output: expected some output");
 
204
    } else {
 
205
        fail(strlen(ms.buf) > 0,
 
206
             "output: expected nothing, actual '%s'", ms.buf);
 
207
    }
 
208
    printf("PASS\n");
 
209
 
 
210
 done:
 
211
    free(ms.buf);
 
212
    aug_close(aug);
 
213
    return result;
 
214
 error:
 
215
    result = -1;
 
216
    goto done;
 
217
}
 
218
 
 
219
static int run_tests(struct test *tests) {
 
220
    int result = EXIT_SUCCESS;
 
221
 
 
222
    list_for_each(t, tests) {
 
223
        if (run_one_test(t) < 0)
 
224
            result = EXIT_FAILURE;
 
225
    }
 
226
    return result;
 
227
}
 
228
 
 
229
int main(void) {
 
230
    struct test *tests;
 
231
 
 
232
    abs_top_srcdir = getenv("abs_top_srcdir");
 
233
    if (abs_top_srcdir == NULL)
 
234
        die("env var abs_top_srcdir must be set");
 
235
 
 
236
    tests = read_tests();
 
237
    return run_tests(tests);
 
238
}
 
239
 
 
240
/*
 
241
 * Local variables:
 
242
 *  indent-tabs-mode: nil
 
243
 *  c-indent-level: 4
 
244
 *  c-basic-offset: 4
 
245
 *  tab-width: 4
 
246
 * End:
 
247
 */