1231984Sjilles/*- 2231984Sjilles * Copyright (c) 2012 Jilles Tjoelker 3231984Sjilles * All rights reserved. 4231984Sjilles * 5231984Sjilles * Redistribution and use in source and binary forms, with or without 6231984Sjilles * modification, are permitted provided that the following conditions 7231984Sjilles * are met: 8231984Sjilles * 1. Redistributions of source code must retain the above copyright 9231984Sjilles * notice, this list of conditions and the following disclaimer. 10231984Sjilles * 2. Redistributions in binary form must reproduce the above copyright 11231984Sjilles * notice, this list of conditions and the following disclaimer in the 12231984Sjilles * documentation and/or other materials provided with the distribution. 13231984Sjilles * 14231984Sjilles * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15231984Sjilles * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16231984Sjilles * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17231984Sjilles * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18231984Sjilles * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19231984Sjilles * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20231984Sjilles * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21231984Sjilles * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22231984Sjilles * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23231984Sjilles * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24231984Sjilles * SUCH DAMAGE. 25231984Sjilles */ 26231984Sjilles 27231984Sjilles#include <sys/cdefs.h> 28231984Sjilles__FBSDID("$FreeBSD: releng/10.3/lib/libc/tests/gen/fmtmsg_test.c 291190 2015-11-23 10:53:01Z ngie $"); 29231984Sjilles 30290572Sngie#include <sys/param.h> 31231984Sjilles#include <sys/wait.h> 32231984Sjilles#include <err.h> 33231984Sjilles#include <errno.h> 34231984Sjilles#include <fmtmsg.h> 35231984Sjilles#include <stdio.h> 36231984Sjilles#include <stdlib.h> 37231984Sjilles#include <string.h> 38231984Sjilles#include <unistd.h> 39231984Sjilles 40290572Sngie#include <atf-c.h> 41290572Sngie 42231984Sjillesstatic char *run_test(long classification, const char *label, int severity, 43231984Sjilles const char *text, const char *action, const char *tag); 44231984Sjilles 45231984Sjillesstruct testcase { 46231984Sjilles long classification; 47231984Sjilles const char *label; 48231984Sjilles int severity; 49231984Sjilles const char *text; 50231984Sjilles const char *action; 51231984Sjilles const char *tag; 52231984Sjilles const char *msgverb; 53231984Sjilles const char *result; 54231984Sjilles} testcases[] = { 55231984Sjilles { 56231984Sjilles MM_UTIL | MM_PRINT, "BSD:ls", MM_ERROR, 57231984Sjilles "illegal option -- z", "refer to manual", "BSD:ls:001", 58231984Sjilles NULL, 59231984Sjilles "BSD:ls: ERROR: illegal option -- z\n" 60231984Sjilles "TO FIX: refer to manual BSD:ls:001\n" 61231984Sjilles }, 62231984Sjilles { 63231984Sjilles MM_UTIL | MM_PRINT, "BSD:ls", MM_ERROR, 64231984Sjilles "illegal option -- z", "refer to manual", "BSD:ls:001", 65231984Sjilles "text:severity:action:tag", 66231984Sjilles "illegal option -- z: ERROR\n" 67231984Sjilles "TO FIX: refer to manual BSD:ls:001\n" 68231984Sjilles }, 69231984Sjilles { 70231984Sjilles MM_UTIL | MM_PRINT, "BSD:ls", MM_ERROR, 71231984Sjilles "illegal option -- z", "refer to manual", "BSD:ls:001", 72231984Sjilles "text", 73231984Sjilles "illegal option -- z\n" 74231984Sjilles }, 75231984Sjilles { 76231984Sjilles MM_UTIL | MM_PRINT, "BSD:ls", MM_ERROR, 77231984Sjilles "illegal option -- z", "refer to manual", "BSD:ls:001", 78231984Sjilles "severity:text", 79231984Sjilles "ERROR: illegal option -- z\n" 80231984Sjilles }, 81231984Sjilles { 82231984Sjilles MM_UTIL | MM_PRINT, "BSD:ls", MM_ERROR, 83231984Sjilles "illegal option -- z", "refer to manual", "BSD:ls:001", 84231984Sjilles "ignore me", 85231984Sjilles "BSD:ls: ERROR: illegal option -- z\n" 86231984Sjilles "TO FIX: refer to manual BSD:ls:001\n" 87231984Sjilles }, 88231984Sjilles { 89231984Sjilles MM_UTIL | MM_PRINT, "BSD:ls", MM_ERROR, 90231984Sjilles "illegal option -- z", "refer to manual", "BSD:ls:001", 91231984Sjilles "tag:severity:text:nothing:action", 92231984Sjilles "BSD:ls: ERROR: illegal option -- z\n" 93231984Sjilles "TO FIX: refer to manual BSD:ls:001\n" 94231984Sjilles }, 95231984Sjilles { 96231984Sjilles MM_UTIL | MM_PRINT, "BSD:ls", MM_ERROR, 97231984Sjilles "illegal option -- z", "refer to manual", "BSD:ls:001", 98231984Sjilles "", 99231984Sjilles "BSD:ls: ERROR: illegal option -- z\n" 100231984Sjilles "TO FIX: refer to manual BSD:ls:001\n" 101231984Sjilles }, 102231984Sjilles { 103231984Sjilles MM_UTIL | MM_PRINT, MM_NULLLBL, MM_ERROR, 104231984Sjilles "illegal option -- z", "refer to manual", "BSD:ls:001", 105231984Sjilles NULL, 106231984Sjilles "ERROR: illegal option -- z\n" 107231984Sjilles "TO FIX: refer to manual BSD:ls:001\n" 108231984Sjilles }, 109231984Sjilles { 110231984Sjilles MM_UTIL | MM_PRINT, "BSD:ls", MM_ERROR, 111231984Sjilles "illegal option -- z", MM_NULLACT, MM_NULLTAG, 112231984Sjilles NULL, 113231984Sjilles "BSD:ls: ERROR: illegal option -- z\n" 114231984Sjilles }, 115231984Sjilles { 116231984Sjilles MM_UTIL | MM_NULLMC, "BSD:ls", MM_ERROR, 117231984Sjilles "illegal option -- z", "refer to manual", "BSD:ls:001", 118231984Sjilles NULL, 119231984Sjilles "" 120231984Sjilles }, 121231984Sjilles { 122231984Sjilles MM_APPL | MM_PRINT, "ABCDEFGHIJ:abcdefghijklmn", MM_INFO, 123231984Sjilles "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 124231984Sjilles "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 125231984Sjilles "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 126231984Sjilles "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 127231984Sjilles "refer to manual", "ABCDEFGHIJ:abcdefghijklmn:001", 128231984Sjilles NULL, 129231984Sjilles "ABCDEFGHIJ:abcdefghijklmn: INFO: " 130231984Sjilles "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 131231984Sjilles "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 132231984Sjilles "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 133231984Sjilles "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" 134231984Sjilles "TO FIX: refer to manual ABCDEFGHIJ:abcdefghijklmn:001\n" 135231984Sjilles }, 136231984Sjilles { 137231984Sjilles MM_OPSYS | MM_PRINT, "TEST:test", MM_HALT, 138231984Sjilles "failed", "nothing can help me", "NOTHING", 139231984Sjilles NULL, 140231984Sjilles "TEST:test: HALT: failed\n" 141231984Sjilles "TO FIX: nothing can help me NOTHING\n" 142231984Sjilles }, 143231984Sjilles { 144231984Sjilles MM_OPSYS | MM_PRINT, "TEST:test", MM_WARNING, 145231984Sjilles "failed", "nothing can help me", "NOTHING", 146231984Sjilles NULL, 147231984Sjilles "TEST:test: WARNING: failed\n" 148231984Sjilles "TO FIX: nothing can help me NOTHING\n" 149231984Sjilles }, 150231984Sjilles { 151231984Sjilles MM_OPSYS | MM_PRINT, "TEST:test", MM_NOSEV, 152231984Sjilles "failed", "nothing can help me", "NOTHING", 153231984Sjilles NULL, 154231984Sjilles "TEST:test: failed\n" 155231984Sjilles "TO FIX: nothing can help me NOTHING\n" 156231984Sjilles } 157231984Sjilles}; 158231984Sjilles 159231984Sjillesstatic char * 160231984Sjillesrun_test(long classification, const char *label, int severity, 161231984Sjilles const char *text, const char *action, const char *tag) 162231984Sjilles{ 163231984Sjilles int pip[2]; 164231984Sjilles pid_t pid, wpid; 165231984Sjilles char *result, *p; 166231984Sjilles size_t resultsize; 167231984Sjilles ssize_t n; 168231984Sjilles int status; 169231984Sjilles 170231984Sjilles if (pipe(pip) == -1) 171231984Sjilles err(2, "pipe"); 172231984Sjilles pid = fork(); 173231984Sjilles if (pid == -1) 174231984Sjilles err(2, "fork"); 175231984Sjilles if (pid == 0) { 176231984Sjilles close(pip[0]); 177231984Sjilles if (pip[1] != STDERR_FILENO && 178231984Sjilles dup2(pip[1], STDERR_FILENO) == -1) 179231984Sjilles _exit(2); 180231984Sjilles if (fmtmsg(classification, label, severity, text, action, tag) 181231984Sjilles != MM_OK) 182231984Sjilles _exit(1); 183231984Sjilles else 184231984Sjilles _exit(0); 185231984Sjilles } 186231984Sjilles close(pip[1]); 187231984Sjilles resultsize = 1024; 188231984Sjilles result = malloc(resultsize); 189231984Sjilles p = result; 190231984Sjilles while ((n = read(pip[0], p, result + resultsize - p - 1)) != 0) { 191231984Sjilles if (n == -1) { 192231984Sjilles if (errno == EINTR) 193231984Sjilles continue; 194231984Sjilles else 195231984Sjilles err(2, "read"); 196231984Sjilles } 197231984Sjilles p += n; 198231984Sjilles if (result + resultsize == p - 1) { 199231984Sjilles resultsize *= 2; 200231984Sjilles result = realloc(result, resultsize); 201231984Sjilles if (result == NULL) 202231984Sjilles err(2, "realloc"); 203231984Sjilles } 204231984Sjilles } 205231984Sjilles if (memchr(result, '\0', p - result) != NULL) { 206231984Sjilles free(result); 207231984Sjilles return (NULL); 208231984Sjilles } 209231984Sjilles *p = '\0'; 210231984Sjilles close(pip[0]); 211231984Sjilles while ((wpid = waitpid(pid, &status, 0)) == -1 && errno == EINTR) 212231984Sjilles ; 213231984Sjilles if (wpid == -1) 214231984Sjilles err(2, "waitpid"); 215231984Sjilles if (status != 0) { 216231984Sjilles free(result); 217231984Sjilles return (NULL); 218231984Sjilles } 219231984Sjilles return (result); 220231984Sjilles} 221231984Sjilles 222290572SngieATF_TC_WITHOUT_HEAD(fmtmsg_test); 223290572SngieATF_TC_BODY(fmtmsg_test, tc) 224231984Sjilles{ 225231984Sjilles char *result; 226231984Sjilles struct testcase *t; 227290572Sngie int i; 228231984Sjilles 229290572Sngie for (i = 0; i < nitems(testcases); i++) { 230231984Sjilles t = &testcases[i]; 231231984Sjilles if (t->msgverb != NULL) 232231984Sjilles setenv("MSGVERB", t->msgverb, 1); 233231984Sjilles else 234231984Sjilles unsetenv("MSGVERB"); 235231984Sjilles result = run_test(t->classification, t->label, t->severity, 236231984Sjilles t->text, t->action, t->tag); 237290572Sngie ATF_CHECK_MSG(result != NULL, "testcase %d failed", i + 1); 238290572Sngie if (result != NULL) 239290572Sngie ATF_CHECK_MSG(strcmp(result, t->result) == 0, 240290572Sngie "results for testcase %d didn't match; " 241290572Sngie "`%s` != `%s`", i + 1, result, t->result); 242231984Sjilles free(result); 243231984Sjilles } 244290572Sngie} 245231984Sjilles 246290572SngieATF_TP_ADD_TCS(tp) 247290572Sngie{ 248290572Sngie 249290572Sngie ATF_TP_ADD_TC(tp, fmtmsg_test); 250290572Sngie 251290572Sngie return (atf_no_error()); 252231984Sjilles} 253