xref: /freebsd-src/lib/libsbuf/tests/sbuf_stdio_test.c (revision 991bd461625a2c521d5be4fd6938deed57f60972)
1b824378bSEnji Cooper /*-
2148a8da8SEnji Cooper  * Copyright (c) 2017 Enji Cooper <ngie@freebsd.org>
3b824378bSEnji Cooper  *
4b824378bSEnji Cooper  * Redistribution and use in source and binary forms, with or without
5b824378bSEnji Cooper  * modification, are permitted provided that the following conditions
6b824378bSEnji Cooper  * are met:
7b824378bSEnji Cooper  * 1. Redistributions of source code must retain the above copyright
8b824378bSEnji Cooper  *    notice, this list of conditions and the following disclaimer.
9b824378bSEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
10b824378bSEnji Cooper  *    notice, this list of conditions and the following disclaimer in the
11b824378bSEnji Cooper  *    documentation and/or other materials provided with the distribution.
12b824378bSEnji Cooper  *
13b824378bSEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14b824378bSEnji Cooper  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15b824378bSEnji Cooper  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16b824378bSEnji Cooper  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17b824378bSEnji Cooper  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18b824378bSEnji Cooper  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19b824378bSEnji Cooper  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20b824378bSEnji Cooper  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21b824378bSEnji Cooper  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22b824378bSEnji Cooper  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23b824378bSEnji Cooper  * SUCH DAMAGE.
24b824378bSEnji Cooper  */
25b824378bSEnji Cooper 
26b824378bSEnji Cooper #include <sys/param.h>
27b824378bSEnji Cooper #include <sys/sbuf.h>
28*991bd461SEnji Cooper 
29*991bd461SEnji Cooper #include <atf-c.h>
30b824378bSEnji Cooper #include <errno.h>
31b824378bSEnji Cooper #include <stdarg.h>
32b824378bSEnji Cooper #include <stdio.h>
33b824378bSEnji Cooper #include <stdlib.h>
34b824378bSEnji Cooper #include <string.h>
35b824378bSEnji Cooper #include <unistd.h>
36b824378bSEnji Cooper 
37b824378bSEnji Cooper #include "sbuf_test_common.h"
38b824378bSEnji Cooper 
39b824378bSEnji Cooper static char test_string[] = "this is a test string";
40b824378bSEnji Cooper 
41b824378bSEnji Cooper #define MESSAGE_FORMAT	  "message: %s\n"
42b824378bSEnji Cooper #define MESSAGE_SEPARATOR ';'
43b824378bSEnji Cooper 
44b824378bSEnji Cooper static int
45b824378bSEnji Cooper sbuf_vprintf_helper(struct sbuf *sb, const char *restrict format, ...)
46b824378bSEnji Cooper {
47b824378bSEnji Cooper 	va_list ap;
48b824378bSEnji Cooper 	int rc;
49b824378bSEnji Cooper 
50b824378bSEnji Cooper 	va_start(ap, format);
51b824378bSEnji Cooper 
52b824378bSEnji Cooper 	rc = sbuf_vprintf(sb, format, ap);
53b824378bSEnji Cooper 
54b824378bSEnji Cooper 	va_end(ap);
55b824378bSEnji Cooper 
56b824378bSEnji Cooper 	return (rc);
57b824378bSEnji Cooper }
58b824378bSEnji Cooper 
597d7db529SConrad Meyer ATF_TC_WITHOUT_HEAD(sbuf_printf_drain_null_test);
607d7db529SConrad Meyer ATF_TC_BODY(sbuf_printf_drain_null_test, tc)
617d7db529SConrad Meyer {
627d7db529SConrad Meyer 	struct sbuf *sb;
637d7db529SConrad Meyer 	char buf[2];
647d7db529SConrad Meyer 	pid_t child_proc;
657d7db529SConrad Meyer 
667d7db529SConrad Meyer 	sb = sbuf_new(NULL, buf, sizeof(buf), SBUF_FIXEDLEN);
677d7db529SConrad Meyer 	ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s",
687d7db529SConrad Meyer 	    strerror(errno));
697d7db529SConrad Meyer 
707d7db529SConrad Meyer 	child_proc = atf_utils_fork();
717d7db529SConrad Meyer 	if (child_proc == 0) {
727d7db529SConrad Meyer 		sbuf_set_drain(sb, sbuf_printf_drain, NULL);
737d7db529SConrad Meyer 
747d7db529SConrad Meyer 		ATF_REQUIRE_EQ_MSG(0, sbuf_cat(sb, test_string),
757d7db529SConrad Meyer 		    "sbuf_cat failed");
767d7db529SConrad Meyer 
777d7db529SConrad Meyer 		ATF_CHECK_EQ(0, sbuf_finish(sb));
787d7db529SConrad Meyer 		exit(0);
797d7db529SConrad Meyer 	}
807d7db529SConrad Meyer 	atf_utils_wait(child_proc, 0, test_string, "");
817d7db529SConrad Meyer 
827d7db529SConrad Meyer 	sbuf_delete(sb);
837d7db529SConrad Meyer }
847d7db529SConrad Meyer 
857d7db529SConrad Meyer ATF_TC_WITHOUT_HEAD(sbuf_printf_drain_test);
867d7db529SConrad Meyer ATF_TC_BODY(sbuf_printf_drain_test, tc)
877d7db529SConrad Meyer {
887d7db529SConrad Meyer 	struct sbuf *sb;
897d7db529SConrad Meyer 	char buf[2];
907d7db529SConrad Meyer 	pid_t child_proc;
917d7db529SConrad Meyer 	size_t cnt = 0;
927d7db529SConrad Meyer 
937d7db529SConrad Meyer 	sb = sbuf_new(NULL, buf, sizeof(buf), SBUF_FIXEDLEN);
947d7db529SConrad Meyer 	ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s",
957d7db529SConrad Meyer 	    strerror(errno));
967d7db529SConrad Meyer 
977d7db529SConrad Meyer 	child_proc = atf_utils_fork();
987d7db529SConrad Meyer 	if (child_proc == 0) {
997d7db529SConrad Meyer 		sbuf_set_drain(sb, sbuf_printf_drain, &cnt);
1007d7db529SConrad Meyer 
1017d7db529SConrad Meyer 		ATF_REQUIRE_EQ_MSG(0, sbuf_cat(sb, test_string),
1027d7db529SConrad Meyer 		    "sbuf_cat failed");
1037d7db529SConrad Meyer 
1047d7db529SConrad Meyer 		ATF_CHECK_EQ(0, sbuf_finish(sb));
1057d7db529SConrad Meyer 		ATF_CHECK_EQ(strlen(test_string), cnt);
1067d7db529SConrad Meyer 		exit(0);
1077d7db529SConrad Meyer 	}
1087d7db529SConrad Meyer 	atf_utils_wait(child_proc, 0, test_string, "");
1097d7db529SConrad Meyer 
1107d7db529SConrad Meyer 	sbuf_delete(sb);
1117d7db529SConrad Meyer }
1127d7db529SConrad Meyer 
113b824378bSEnji Cooper ATF_TC_WITHOUT_HEAD(sbuf_printf_test);
114b824378bSEnji Cooper ATF_TC_BODY(sbuf_printf_test, tc)
115b824378bSEnji Cooper {
116b824378bSEnji Cooper 	struct sbuf *sb;
117b824378bSEnji Cooper 	char *test_string_tmp;
118b824378bSEnji Cooper 
119*991bd461SEnji Cooper 	asprintf(&test_string_tmp, "%s%c" MESSAGE_FORMAT, test_string,
120*991bd461SEnji Cooper 	    MESSAGE_SEPARATOR, test_string);
121b824378bSEnji Cooper 	ATF_REQUIRE_MSG(test_string_tmp != NULL, "asprintf failed");
122b824378bSEnji Cooper 
123b824378bSEnji Cooper 	sb = sbuf_new_auto();
124b824378bSEnji Cooper 	ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s",
125b824378bSEnji Cooper 	    strerror(errno));
126b824378bSEnji Cooper 
127b824378bSEnji Cooper 	ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed");
128b824378bSEnji Cooper 	ATF_REQUIRE_MSG(sbuf_putc(sb, MESSAGE_SEPARATOR) == 0,
129b824378bSEnji Cooper 	    "sbuf_putc failed");
130b824378bSEnji Cooper 
131b824378bSEnji Cooper 	ATF_REQUIRE_MSG(sbuf_printf(sb, MESSAGE_FORMAT, test_string) == 0,
132b824378bSEnji Cooper 	    "sbuf_printf failed");
133b824378bSEnji Cooper 
134b824378bSEnji Cooper 	ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s",
135b824378bSEnji Cooper 	    strerror(errno));
136b824378bSEnji Cooper 
137b824378bSEnji Cooper 	ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string_tmp,
138b824378bSEnji Cooper 	    "sbuf (\"%s\") != test string (\"%s\")", sbuf_data(sb),
139b824378bSEnji Cooper 	    test_string_tmp);
140b824378bSEnji Cooper 
141b824378bSEnji Cooper 	sbuf_delete(sb);
142b824378bSEnji Cooper 
143b824378bSEnji Cooper 	free(test_string_tmp);
144b824378bSEnji Cooper }
145b824378bSEnji Cooper 
146b824378bSEnji Cooper ATF_TC_WITHOUT_HEAD(sbuf_putbuf_test);
147b824378bSEnji Cooper ATF_TC_BODY(sbuf_putbuf_test, tc)
148b824378bSEnji Cooper {
149b824378bSEnji Cooper 	struct sbuf *sb;
150b824378bSEnji Cooper 	pid_t child_proc;
151b824378bSEnji Cooper 
152b824378bSEnji Cooper 	sb = sbuf_new_auto();
153b824378bSEnji Cooper 	ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s",
154b824378bSEnji Cooper 	    strerror(errno));
155b824378bSEnji Cooper 
156b824378bSEnji Cooper 	ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed");
157b824378bSEnji Cooper 
158b824378bSEnji Cooper 	child_proc = atf_utils_fork();
159b824378bSEnji Cooper 	if (child_proc == 0) {
1607d7db529SConrad Meyer 		ATF_CHECK_EQ(0, sbuf_finish(sb));
161b824378bSEnji Cooper 		sbuf_putbuf(sb);
162b824378bSEnji Cooper 		exit(0);
163b824378bSEnji Cooper 	}
164b824378bSEnji Cooper 	atf_utils_wait(child_proc, 0, test_string, "");
165b824378bSEnji Cooper 
166b824378bSEnji Cooper 	ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s",
167b824378bSEnji Cooper 	    strerror(errno));
168b824378bSEnji Cooper 
169b824378bSEnji Cooper 	sbuf_delete(sb);
170b824378bSEnji Cooper }
171b824378bSEnji Cooper 
172b824378bSEnji Cooper ATF_TC_WITHOUT_HEAD(sbuf_vprintf_test);
173b824378bSEnji Cooper ATF_TC_BODY(sbuf_vprintf_test, tc)
174b824378bSEnji Cooper {
175b824378bSEnji Cooper 	struct sbuf *sb;
176b824378bSEnji Cooper 	char *test_string_tmp;
177b824378bSEnji Cooper 	int rc;
178b824378bSEnji Cooper 
179*991bd461SEnji Cooper 	asprintf(&test_string_tmp, "%s%c" MESSAGE_FORMAT, test_string,
180*991bd461SEnji Cooper 	    MESSAGE_SEPARATOR, test_string);
181b824378bSEnji Cooper 	ATF_REQUIRE_MSG(test_string_tmp != NULL, "asprintf failed");
182b824378bSEnji Cooper 
183b824378bSEnji Cooper 	sb = sbuf_new_auto();
184b824378bSEnji Cooper 	ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s",
185b824378bSEnji Cooper 	    strerror(errno));
186b824378bSEnji Cooper 
187b824378bSEnji Cooper 	ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed");
188b824378bSEnji Cooper 	ATF_REQUIRE_MSG(sbuf_putc(sb, MESSAGE_SEPARATOR) == 0,
189b824378bSEnji Cooper 	    "sbuf_putc failed");
190b824378bSEnji Cooper 
191b824378bSEnji Cooper 	rc = sbuf_vprintf_helper(sb, MESSAGE_FORMAT, test_string);
192b824378bSEnji Cooper 	ATF_REQUIRE_MSG(rc == 0, "sbuf_vprintf failed");
193b824378bSEnji Cooper 
194b824378bSEnji Cooper 	ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s",
195b824378bSEnji Cooper 	    strerror(errno));
196b824378bSEnji Cooper 
197b824378bSEnji Cooper 	ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string_tmp,
198b824378bSEnji Cooper 	    "sbuf (\"%s\") != test string (\"%s\")", sbuf_data(sb),
199b824378bSEnji Cooper 	    test_string_tmp);
200b824378bSEnji Cooper 
201b824378bSEnji Cooper 	sbuf_delete(sb);
202b824378bSEnji Cooper }
203b824378bSEnji Cooper 
204b824378bSEnji Cooper ATF_TP_ADD_TCS(tp)
205b824378bSEnji Cooper {
2067d7db529SConrad Meyer 	ATF_TP_ADD_TC(tp, sbuf_printf_drain_null_test);
2077d7db529SConrad Meyer 	ATF_TP_ADD_TC(tp, sbuf_printf_drain_test);
208b824378bSEnji Cooper 	ATF_TP_ADD_TC(tp, sbuf_printf_test);
209b824378bSEnji Cooper 	ATF_TP_ADD_TC(tp, sbuf_putbuf_test);
210b824378bSEnji Cooper 	ATF_TP_ADD_TC(tp, sbuf_vprintf_test);
211b824378bSEnji Cooper 
212b824378bSEnji Cooper 	return (atf_no_error());
213b824378bSEnji Cooper }
214