]> arthur.barton.de Git - netatalk.git/blob - libevent/test/tinytest_demo.c
Re-add libevent from git, remove all build files
[netatalk.git] / libevent / test / tinytest_demo.c
1 /* tinytest_demo.c -- Copyright 2009-2012 Nick Mathewson
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions
5  * are met:
6  * 1. Redistributions of source code must retain the above copyright
7  *    notice, this list of conditions and the following disclaimer.
8  * 2. Redistributions in binary form must reproduce the above copyright
9  *    notice, this list of conditions and the following disclaimer in the
10  *    documentation and/or other materials provided with the distribution.
11  * 3. The name of the author may not be used to endorse or promote products
12  *    derived from this software without specific prior written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26
27 /* Welcome to the example file for tinytest!  I'll show you how to set up
28  * some simple and not-so-simple testcases. */
29
30 /* Make sure you include these headers. */
31 #include "tinytest.h"
32 #include "tinytest_macros.h"
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <errno.h>
38
39 /* ============================================================ */
40
41 /* First, let's see if strcmp is working.  (All your test cases should be
42  * functions declared to take a single void * as) an argument. */
43 void
44 test_strcmp(void *data)
45 {
46         (void)data; /* This testcase takes no data. */
47
48         /* Let's make sure the empty string is equal to itself */
49         if (strcmp("","")) {
50                 /* This macro tells tinytest to stop the current test
51                  * and go straight to the "end" label. */
52                 tt_abort_msg("The empty string was not equal to itself");
53         }
54
55         /* Pretty often, calling tt_abort_msg to indicate failure is more
56            heavy-weight than you want.  Instead, just say: */
57         tt_assert(strcmp("testcase", "testcase") == 0);
58
59         /* Occasionally, you don't want to stop the current testcase just
60            because a single assertion has failed.  In that case, use
61            tt_want: */
62         tt_want(strcmp("tinytest", "testcase") > 0);
63
64         /* You can use the tt_*_op family of macros to compare values and to
65            fail unless they have the relationship you want.  They produce
66            more useful output than tt_assert, since they display the actual
67            values of the failing things.
68
69            Fail unless strcmp("abc, "abc") == 0 */
70         tt_int_op(strcmp("abc", "abc"), ==, 0);
71
72         /* Fail unless strcmp("abc, "abcd") is less than 0 */
73         tt_int_op(strcmp("abc", "abcd"), < , 0);
74
75         /* Incidentally, there's a test_str_op that uses strcmp internally. */
76         tt_str_op("abc", <, "abcd");
77
78
79         /* Every test-case function needs to finish with an "end:"
80            label and (optionally) code to clean up local variables. */
81  end:
82         ;
83 }
84
85 /* ============================================================ */
86
87 /* Now let's mess with setup and teardown functions!  These are handy if
88    you have a bunch of tests that all need a similar environment, and you
89    want to reconstruct that environment freshly for each one. */
90
91 /* First you declare a type to hold the environment info, and functions to
92    set it up and tear it down. */
93 struct data_buffer {
94         /* We're just going to have couple of character buffer.  Using
95            setup/teardown functions is probably overkill for this case.
96
97            You could also do file descriptors, complicated handles, temporary
98            files, etc. */
99         char buffer1[512];
100         char buffer2[512];
101 };
102 /* The setup function needs to take a const struct testcase_t and return
103    void* */
104 void *
105 setup_data_buffer(const struct testcase_t *testcase)
106 {
107         struct data_buffer *db = malloc(sizeof(struct data_buffer));
108
109         /* If you had a complicated set of setup rules, you might behave
110            differently here depending on testcase->flags or
111            testcase->setup_data or even or testcase->name. */
112
113         /* Returning a NULL here would mean that we couldn't set up for this
114            test, so we don't need to test db for null. */
115         return db;
116 }
117 /* The clean function deallocates storage carefully and returns true on
118    success. */
119 int
120 clean_data_buffer(const struct testcase_t *testcase, void *ptr)
121 {
122         struct data_buffer *db = ptr;
123
124         if (db) {
125                 free(db);
126                 return 1;
127         }
128         return 0;
129 }
130 /* Finally, declare a testcase_setup_t with these functions. */
131 struct testcase_setup_t data_buffer_setup = {
132         setup_data_buffer, clean_data_buffer
133 };
134
135
136 /* Now let's write our test. */
137 void
138 test_memcpy(void *ptr)
139 {
140         /* This time, we use the argument. */
141         struct data_buffer *db = ptr;
142
143         /* We'll also introduce a local variable that might need cleaning up. */
144         char *mem = NULL;
145
146         /* Let's make sure that memcpy does what we'd like. */
147         strcpy(db->buffer1, "String 0");
148         memcpy(db->buffer2, db->buffer1, sizeof(db->buffer1));
149         tt_str_op(db->buffer1, ==, db->buffer2);
150
151         /* Now we've allocated memory that's referenced by a local variable.
152            The end block of the function will clean it up. */
153         mem = strdup("Hello world.");
154         tt_assert(mem);
155
156         /* Another rather trivial test. */
157         tt_str_op(db->buffer1, !=, mem);
158
159  end:
160         /* This time our end block has something to do. */
161         if (mem)
162                 free(mem);
163 }
164
165 /* ============================================================ */
166
167 /* Now we need to make sure that our tests get invoked.   First, you take
168    a bunch of related tests and put them into an array of struct testcase_t.
169 */
170
171 struct testcase_t demo_tests[] = {
172         /* Here's a really simple test: it has a name you can refer to it
173            with, and a function to invoke it. */
174         { "strcmp", test_strcmp, },
175
176         /* The second test has a flag, "TT_FORK", to make it run in a
177            subprocess, and a pointer to the testcase_setup_t that configures
178            its environment. */
179         { "memcpy", test_memcpy, TT_FORK, &data_buffer_setup },
180
181         /* The array has to end with END_OF_TESTCASES. */
182         END_OF_TESTCASES
183 };
184
185 /* Next, we make an array of testgroups.  This is mandatory.  Unlike more
186    heavy-duty testing frameworks, groups can't nest. */
187 struct testgroup_t groups[] = {
188
189         /* Every group has a 'prefix', and an array of tests.  That's it. */
190         { "demo/", demo_tests },
191
192         END_OF_GROUPS
193 };
194
195
196 int
197 main(int c, const char **v)
198 {
199         /* Finally, just call tinytest_main().  It lets you specify verbose
200            or quiet output with --verbose and --quiet.  You can list
201            specific tests:
202
203                tinytest-demo demo/memcpy
204
205            or use a ..-wildcard to select multiple tests with a common
206            prefix:
207
208                tinytest-demo demo/..
209
210            If you list no tests, you get them all by default, so that
211            "tinytest-demo" and "tinytest-demo .." mean the same thing.
212
213         */
214         return tinytest_main(c, v, groups);
215 }