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 #include <sys/param.h> 28 #include <sys/sbuf.h> 29 #include <errno.h> 30 #include <stdarg.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <unistd.h> 35 36 #include <atf-c.h> 37 38 #include "sbuf_test_common.h" 39 40 static char test_string[] = "this is a test string"; 41 42 #define MESSAGE_FORMAT "message: %s\n" 43 #define MESSAGE_SEPARATOR ';' 44 45 static int 46 sbuf_vprintf_helper(struct sbuf *sb, const char * restrict format, ...) 47 { 48 va_list ap; 49 int rc; 50 51 va_start(ap, format); 52 53 rc = sbuf_vprintf(sb, format, ap); 54 55 va_end(ap); 56 57 return (rc); 58 } 59 60 ATF_TC_WITHOUT_HEAD(sbuf_printf_drain_null_test); 61 ATF_TC_BODY(sbuf_printf_drain_null_test, tc) 62 { 63 struct sbuf *sb; 64 char buf[2]; 65 pid_t child_proc; 66 67 sb = sbuf_new(NULL, buf, sizeof(buf), SBUF_FIXEDLEN); 68 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 69 strerror(errno)); 70 71 child_proc = atf_utils_fork(); 72 if (child_proc == 0) { 73 sbuf_set_drain(sb, sbuf_printf_drain, NULL); 74 75 ATF_REQUIRE_EQ_MSG(0, sbuf_cat(sb, test_string), 76 "sbuf_cat failed"); 77 78 ATF_CHECK_EQ(0, sbuf_finish(sb)); 79 exit(0); 80 } 81 atf_utils_wait(child_proc, 0, test_string, ""); 82 83 sbuf_delete(sb); 84 } 85 86 ATF_TC_WITHOUT_HEAD(sbuf_printf_drain_test); 87 ATF_TC_BODY(sbuf_printf_drain_test, tc) 88 { 89 struct sbuf *sb; 90 char buf[2]; 91 pid_t child_proc; 92 size_t cnt = 0; 93 94 sb = sbuf_new(NULL, buf, sizeof(buf), SBUF_FIXEDLEN); 95 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 96 strerror(errno)); 97 98 child_proc = atf_utils_fork(); 99 if (child_proc == 0) { 100 sbuf_set_drain(sb, sbuf_printf_drain, &cnt); 101 102 ATF_REQUIRE_EQ_MSG(0, sbuf_cat(sb, test_string), 103 "sbuf_cat failed"); 104 105 ATF_CHECK_EQ(0, sbuf_finish(sb)); 106 ATF_CHECK_EQ(strlen(test_string), cnt); 107 exit(0); 108 } 109 atf_utils_wait(child_proc, 0, test_string, ""); 110 111 sbuf_delete(sb); 112 } 113 114 ATF_TC_WITHOUT_HEAD(sbuf_printf_test); 115 ATF_TC_BODY(sbuf_printf_test, tc) 116 { 117 struct sbuf *sb; 118 char *test_string_tmp; 119 120 asprintf(&test_string_tmp, "%s%c" MESSAGE_FORMAT, 121 test_string, MESSAGE_SEPARATOR, test_string); 122 ATF_REQUIRE_MSG(test_string_tmp != NULL, "asprintf failed"); 123 124 sb = sbuf_new_auto(); 125 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 126 strerror(errno)); 127 128 ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed"); 129 ATF_REQUIRE_MSG(sbuf_putc(sb, MESSAGE_SEPARATOR) == 0, 130 "sbuf_putc failed"); 131 132 ATF_REQUIRE_MSG(sbuf_printf(sb, MESSAGE_FORMAT, test_string) == 0, 133 "sbuf_printf failed"); 134 135 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 136 strerror(errno)); 137 138 ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string_tmp, 139 "sbuf (\"%s\") != test string (\"%s\")", sbuf_data(sb), 140 test_string_tmp); 141 142 sbuf_delete(sb); 143 144 free(test_string_tmp); 145 } 146 147 ATF_TC_WITHOUT_HEAD(sbuf_putbuf_test); 148 ATF_TC_BODY(sbuf_putbuf_test, tc) 149 { 150 struct sbuf *sb; 151 pid_t child_proc; 152 153 sb = sbuf_new_auto(); 154 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 155 strerror(errno)); 156 157 ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed"); 158 159 child_proc = atf_utils_fork(); 160 if (child_proc == 0) { 161 ATF_CHECK_EQ(0, sbuf_finish(sb)); 162 sbuf_putbuf(sb); 163 exit(0); 164 } 165 atf_utils_wait(child_proc, 0, test_string, ""); 166 167 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 168 strerror(errno)); 169 170 sbuf_delete(sb); 171 } 172 173 ATF_TC_WITHOUT_HEAD(sbuf_vprintf_test); 174 ATF_TC_BODY(sbuf_vprintf_test, tc) 175 { 176 struct sbuf *sb; 177 char *test_string_tmp; 178 int rc; 179 180 asprintf(&test_string_tmp, "%s%c" MESSAGE_FORMAT, 181 test_string, MESSAGE_SEPARATOR, test_string); 182 ATF_REQUIRE_MSG(test_string_tmp != NULL, "asprintf failed"); 183 184 sb = sbuf_new_auto(); 185 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 186 strerror(errno)); 187 188 ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed"); 189 ATF_REQUIRE_MSG(sbuf_putc(sb, MESSAGE_SEPARATOR) == 0, 190 "sbuf_putc failed"); 191 192 rc = sbuf_vprintf_helper(sb, MESSAGE_FORMAT, test_string); 193 ATF_REQUIRE_MSG(rc == 0, "sbuf_vprintf failed"); 194 195 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 196 strerror(errno)); 197 198 ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string_tmp, 199 "sbuf (\"%s\") != test string (\"%s\")", sbuf_data(sb), 200 test_string_tmp); 201 202 sbuf_delete(sb); 203 } 204 205 ATF_TP_ADD_TCS(tp) 206 { 207 208 ATF_TP_ADD_TC(tp, sbuf_printf_drain_null_test); 209 ATF_TP_ADD_TC(tp, sbuf_printf_drain_test); 210 ATF_TP_ADD_TC(tp, sbuf_printf_test); 211 ATF_TP_ADD_TC(tp, sbuf_putbuf_test); 212 ATF_TP_ADD_TC(tp, sbuf_vprintf_test); 213 214 return (atf_no_error()); 215 } 216