]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libsbuf/tests/sbuf_stdio_test.c
strfmon: Remove XXX marks
[FreeBSD/FreeBSD.git] / lib / libsbuf / tests / sbuf_stdio_test.c
1 /*-
2  * Copyright (c) 2017 Enji Cooper <ngie@freebsd.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28
29 #include <sys/param.h>
30 #include <sys/sbuf.h>
31 #include <errno.h>
32 #include <stdarg.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37
38 #include <atf-c.h>
39
40 #include "sbuf_test_common.h"
41
42 static char     test_string[] = "this is a test string";
43
44 #define MESSAGE_FORMAT  "message: %s\n"
45 #define MESSAGE_SEPARATOR       ';'
46
47 static int
48 sbuf_vprintf_helper(struct sbuf *sb, const char * restrict format, ...)
49 {
50         va_list ap;
51         int rc;
52
53         va_start(ap, format);
54
55         rc = sbuf_vprintf(sb, format, ap);
56
57         va_end(ap);
58
59         return (rc);
60 }
61
62 ATF_TC_WITHOUT_HEAD(sbuf_printf_drain_null_test);
63 ATF_TC_BODY(sbuf_printf_drain_null_test, tc)
64 {
65         struct sbuf *sb;
66         char buf[2];
67         pid_t child_proc;
68
69         sb = sbuf_new(NULL, buf, sizeof(buf), SBUF_FIXEDLEN);
70         ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s",
71             strerror(errno));
72
73         child_proc = atf_utils_fork();
74         if (child_proc == 0) {
75                 sbuf_set_drain(sb, sbuf_printf_drain, NULL);
76
77                 ATF_REQUIRE_EQ_MSG(0, sbuf_cat(sb, test_string),
78                     "sbuf_cat failed");
79
80                 ATF_CHECK_EQ(0, sbuf_finish(sb));
81                 exit(0);
82         }
83         atf_utils_wait(child_proc, 0, test_string, "");
84
85         sbuf_delete(sb);
86 }
87
88 ATF_TC_WITHOUT_HEAD(sbuf_printf_drain_test);
89 ATF_TC_BODY(sbuf_printf_drain_test, tc)
90 {
91         struct sbuf *sb;
92         char buf[2];
93         pid_t child_proc;
94         size_t cnt = 0;
95
96         sb = sbuf_new(NULL, buf, sizeof(buf), SBUF_FIXEDLEN);
97         ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s",
98             strerror(errno));
99
100         child_proc = atf_utils_fork();
101         if (child_proc == 0) {
102                 sbuf_set_drain(sb, sbuf_printf_drain, &cnt);
103
104                 ATF_REQUIRE_EQ_MSG(0, sbuf_cat(sb, test_string),
105                     "sbuf_cat failed");
106
107                 ATF_CHECK_EQ(0, sbuf_finish(sb));
108                 ATF_CHECK_EQ(strlen(test_string), cnt);
109                 exit(0);
110         }
111         atf_utils_wait(child_proc, 0, test_string, "");
112
113         sbuf_delete(sb);
114 }
115
116 ATF_TC_WITHOUT_HEAD(sbuf_printf_test);
117 ATF_TC_BODY(sbuf_printf_test, tc)
118 {
119         struct sbuf *sb;
120         char *test_string_tmp;
121
122         asprintf(&test_string_tmp, "%s%c" MESSAGE_FORMAT,
123             test_string, MESSAGE_SEPARATOR, test_string);
124         ATF_REQUIRE_MSG(test_string_tmp != NULL, "asprintf failed");
125
126         sb = sbuf_new_auto();
127         ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s",
128             strerror(errno));
129
130         ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed");
131         ATF_REQUIRE_MSG(sbuf_putc(sb, MESSAGE_SEPARATOR) == 0,
132             "sbuf_putc failed");
133
134         ATF_REQUIRE_MSG(sbuf_printf(sb, MESSAGE_FORMAT, test_string) == 0,
135             "sbuf_printf failed");
136
137         ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s",
138             strerror(errno));
139
140         ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string_tmp,
141             "sbuf (\"%s\") != test string (\"%s\")", sbuf_data(sb),
142             test_string_tmp);
143
144         sbuf_delete(sb);
145
146         free(test_string_tmp);
147 }
148
149 ATF_TC_WITHOUT_HEAD(sbuf_putbuf_test);
150 ATF_TC_BODY(sbuf_putbuf_test, tc)
151 {
152         struct sbuf *sb;
153         pid_t child_proc;
154
155         sb = sbuf_new_auto();
156         ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s",
157             strerror(errno));
158
159         ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed");
160
161         child_proc = atf_utils_fork();
162         if (child_proc == 0) {
163                 ATF_CHECK_EQ(0, sbuf_finish(sb));
164                 sbuf_putbuf(sb);
165                 exit(0);
166         }
167         atf_utils_wait(child_proc, 0, test_string, "");
168
169         ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s",
170             strerror(errno));
171
172         sbuf_delete(sb);
173 }
174
175 ATF_TC_WITHOUT_HEAD(sbuf_vprintf_test);
176 ATF_TC_BODY(sbuf_vprintf_test, tc)
177 {
178         struct sbuf *sb;
179         char *test_string_tmp;
180         int rc;
181
182         asprintf(&test_string_tmp, "%s%c" MESSAGE_FORMAT,
183             test_string, MESSAGE_SEPARATOR, test_string);
184         ATF_REQUIRE_MSG(test_string_tmp != NULL, "asprintf failed");
185
186         sb = sbuf_new_auto();
187         ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s",
188             strerror(errno));
189
190         ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed");
191         ATF_REQUIRE_MSG(sbuf_putc(sb, MESSAGE_SEPARATOR) == 0,
192             "sbuf_putc failed");
193
194         rc = sbuf_vprintf_helper(sb, MESSAGE_FORMAT, test_string);
195         ATF_REQUIRE_MSG(rc == 0, "sbuf_vprintf failed");
196
197         ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s",
198             strerror(errno));
199
200         ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string_tmp,
201             "sbuf (\"%s\") != test string (\"%s\")", sbuf_data(sb),
202             test_string_tmp);
203
204         sbuf_delete(sb);
205 }
206
207 ATF_TP_ADD_TCS(tp)
208 {
209
210         ATF_TP_ADD_TC(tp, sbuf_printf_drain_null_test);
211         ATF_TP_ADD_TC(tp, sbuf_printf_drain_test);
212         ATF_TP_ADD_TC(tp, sbuf_printf_test);
213         ATF_TP_ADD_TC(tp, sbuf_putbuf_test);
214         ATF_TP_ADD_TC(tp, sbuf_vprintf_test);
215
216         return (atf_no_error());
217 }