1*08ca345cSEnji Cooper /*- 2*08ca345cSEnji Cooper * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org> 3*08ca345cSEnji Cooper * All rights reserved. 4*08ca345cSEnji Cooper * 5*08ca345cSEnji Cooper * Redistribution and use in source and binary forms, with or without 6*08ca345cSEnji Cooper * modification, are permitted provided that the following conditions 7*08ca345cSEnji Cooper * are met: 8*08ca345cSEnji Cooper * 1. Redistributions of source code must retain the above copyright 9*08ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer. 10*08ca345cSEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 11*08ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer in the 12*08ca345cSEnji Cooper * documentation and/or other materials provided with the distribution. 13*08ca345cSEnji Cooper * 14*08ca345cSEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*08ca345cSEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*08ca345cSEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*08ca345cSEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*08ca345cSEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*08ca345cSEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*08ca345cSEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*08ca345cSEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*08ca345cSEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*08ca345cSEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*08ca345cSEnji Cooper * SUCH DAMAGE. 25*08ca345cSEnji Cooper * 26*08ca345cSEnji Cooper */ 27*08ca345cSEnji Cooper 28*08ca345cSEnji Cooper #include <sys/cdefs.h> 29*08ca345cSEnji Cooper __FBSDID("$FreeBSD$"); 30*08ca345cSEnji Cooper 31*08ca345cSEnji Cooper #include <assert.h> 32*08ca345cSEnji Cooper #include <errno.h> 33*08ca345cSEnji Cooper #include <stdio.h> 34*08ca345cSEnji Cooper #include <stdlib.h> 35*08ca345cSEnji Cooper #include <string.h> 36*08ca345cSEnji Cooper #include <unistd.h> 37*08ca345cSEnji Cooper 38*08ca345cSEnji Cooper #include <atf-c.h> 39*08ca345cSEnji Cooper 40*08ca345cSEnji Cooper #include "testutil.h" 41*08ca345cSEnji Cooper 42*08ca345cSEnji Cooper enum test_methods { 43*08ca345cSEnji Cooper TEST_GETUSERSHELL, 44*08ca345cSEnji Cooper TEST_BUILD_SNAPSHOT 45*08ca345cSEnji Cooper }; 46*08ca345cSEnji Cooper 47*08ca345cSEnji Cooper struct usershell { 48*08ca345cSEnji Cooper char *path; 49*08ca345cSEnji Cooper }; 50*08ca345cSEnji Cooper 51*08ca345cSEnji Cooper static enum test_methods method = TEST_GETUSERSHELL; 52*08ca345cSEnji Cooper 53*08ca345cSEnji Cooper DECLARE_TEST_DATA(usershell) 54*08ca345cSEnji Cooper DECLARE_TEST_FILE_SNAPSHOT(usershell) 55*08ca345cSEnji Cooper DECLARE_2PASS_TEST(usershell) 56*08ca345cSEnji Cooper 57*08ca345cSEnji Cooper static void clone_usershell(struct usershell *, struct usershell const *); 58*08ca345cSEnji Cooper static int compare_usershell(struct usershell *, struct usershell *, void *); 59*08ca345cSEnji Cooper static void free_usershell(struct usershell *); 60*08ca345cSEnji Cooper 61*08ca345cSEnji Cooper static void sdump_usershell(struct usershell *, char *, size_t); 62*08ca345cSEnji Cooper static void dump_usershell(struct usershell *); 63*08ca345cSEnji Cooper 64*08ca345cSEnji Cooper IMPLEMENT_TEST_DATA(usershell) 65*08ca345cSEnji Cooper IMPLEMENT_TEST_FILE_SNAPSHOT(usershell) 66*08ca345cSEnji Cooper IMPLEMENT_2PASS_TEST(usershell) 67*08ca345cSEnji Cooper 68*08ca345cSEnji Cooper static void 69*08ca345cSEnji Cooper clone_usershell(struct usershell *dest, struct usershell const *src) 70*08ca345cSEnji Cooper { 71*08ca345cSEnji Cooper assert(dest != NULL); 72*08ca345cSEnji Cooper assert(src != NULL); 73*08ca345cSEnji Cooper 74*08ca345cSEnji Cooper if (src->path != NULL) { 75*08ca345cSEnji Cooper dest->path = strdup(src->path); 76*08ca345cSEnji Cooper assert(dest->path != NULL); 77*08ca345cSEnji Cooper } 78*08ca345cSEnji Cooper } 79*08ca345cSEnji Cooper 80*08ca345cSEnji Cooper static int 81*08ca345cSEnji Cooper compare_usershell(struct usershell *us1, struct usershell *us2, void *mdata) 82*08ca345cSEnji Cooper { 83*08ca345cSEnji Cooper int rv; 84*08ca345cSEnji Cooper 85*08ca345cSEnji Cooper assert(us1 != NULL); 86*08ca345cSEnji Cooper assert(us2 != NULL); 87*08ca345cSEnji Cooper 88*08ca345cSEnji Cooper dump_usershell(us1); 89*08ca345cSEnji Cooper dump_usershell(us2); 90*08ca345cSEnji Cooper 91*08ca345cSEnji Cooper if (us1 == us2) 92*08ca345cSEnji Cooper return (0); 93*08ca345cSEnji Cooper 94*08ca345cSEnji Cooper rv = strcmp(us1->path, us2->path); 95*08ca345cSEnji Cooper if (rv != 0) { 96*08ca345cSEnji Cooper printf("following structures are not equal:\n"); 97*08ca345cSEnji Cooper dump_usershell(us1); 98*08ca345cSEnji Cooper dump_usershell(us2); 99*08ca345cSEnji Cooper } 100*08ca345cSEnji Cooper 101*08ca345cSEnji Cooper return (rv); 102*08ca345cSEnji Cooper } 103*08ca345cSEnji Cooper 104*08ca345cSEnji Cooper static void 105*08ca345cSEnji Cooper free_usershell(struct usershell *us) 106*08ca345cSEnji Cooper { 107*08ca345cSEnji Cooper free(us->path); 108*08ca345cSEnji Cooper } 109*08ca345cSEnji Cooper 110*08ca345cSEnji Cooper static void 111*08ca345cSEnji Cooper sdump_usershell(struct usershell *us, char *buffer, size_t buflen) 112*08ca345cSEnji Cooper { 113*08ca345cSEnji Cooper snprintf(buffer, buflen, "%s", us->path); 114*08ca345cSEnji Cooper } 115*08ca345cSEnji Cooper 116*08ca345cSEnji Cooper static void 117*08ca345cSEnji Cooper dump_usershell(struct usershell *us) 118*08ca345cSEnji Cooper { 119*08ca345cSEnji Cooper if (us != NULL) { 120*08ca345cSEnji Cooper char buffer[2048]; 121*08ca345cSEnji Cooper sdump_usershell(us, buffer, sizeof(buffer)); 122*08ca345cSEnji Cooper printf("%s\n", buffer); 123*08ca345cSEnji Cooper } else 124*08ca345cSEnji Cooper printf("(null)\n"); 125*08ca345cSEnji Cooper } 126*08ca345cSEnji Cooper 127*08ca345cSEnji Cooper static int 128*08ca345cSEnji Cooper usershell_read_snapshot_func(struct usershell *us, char *line) 129*08ca345cSEnji Cooper { 130*08ca345cSEnji Cooper 131*08ca345cSEnji Cooper us->path = strdup(line); 132*08ca345cSEnji Cooper ATF_REQUIRE(us->path != NULL); 133*08ca345cSEnji Cooper 134*08ca345cSEnji Cooper return (0); 135*08ca345cSEnji Cooper } 136*08ca345cSEnji Cooper 137*08ca345cSEnji Cooper int 138*08ca345cSEnji Cooper run_tests(const char *snapshot_file, enum test_methods method) 139*08ca345cSEnji Cooper { 140*08ca345cSEnji Cooper struct usershell_test_data td, td_snap; 141*08ca345cSEnji Cooper struct usershell ushell; 142*08ca345cSEnji Cooper int rv; 143*08ca345cSEnji Cooper 144*08ca345cSEnji Cooper rv = 0; 145*08ca345cSEnji Cooper 146*08ca345cSEnji Cooper TEST_DATA_INIT(usershell, &td, clone_usershell, free_usershell); 147*08ca345cSEnji Cooper TEST_DATA_INIT(usershell, &td_snap, clone_usershell, free_usershell); 148*08ca345cSEnji Cooper 149*08ca345cSEnji Cooper setusershell(); 150*08ca345cSEnji Cooper while ((ushell.path = getusershell()) != NULL) { 151*08ca345cSEnji Cooper printf("usershell found:\n"); 152*08ca345cSEnji Cooper dump_usershell(&ushell); 153*08ca345cSEnji Cooper TEST_DATA_APPEND(usershell, &td, &ushell); 154*08ca345cSEnji Cooper } 155*08ca345cSEnji Cooper endusershell(); 156*08ca345cSEnji Cooper 157*08ca345cSEnji Cooper if (snapshot_file != NULL) { 158*08ca345cSEnji Cooper if (access(snapshot_file, W_OK | R_OK) != 0) { 159*08ca345cSEnji Cooper if (errno == ENOENT) 160*08ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 161*08ca345cSEnji Cooper else { 162*08ca345cSEnji Cooper printf("can't access the snapshot file %s\n", 163*08ca345cSEnji Cooper snapshot_file); 164*08ca345cSEnji Cooper 165*08ca345cSEnji Cooper rv = -1; 166*08ca345cSEnji Cooper goto fin; 167*08ca345cSEnji Cooper } 168*08ca345cSEnji Cooper } else { 169*08ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_READ(usershell, snapshot_file, 170*08ca345cSEnji Cooper &td_snap, usershell_read_snapshot_func); 171*08ca345cSEnji Cooper if (rv != 0) { 172*08ca345cSEnji Cooper printf("error reading snapshot file\n"); 173*08ca345cSEnji Cooper goto fin; 174*08ca345cSEnji Cooper } 175*08ca345cSEnji Cooper } 176*08ca345cSEnji Cooper } 177*08ca345cSEnji Cooper 178*08ca345cSEnji Cooper switch (method) { 179*08ca345cSEnji Cooper case TEST_GETUSERSHELL: 180*08ca345cSEnji Cooper rv = DO_2PASS_TEST(usershell, &td, &td_snap, 181*08ca345cSEnji Cooper compare_usershell, NULL); 182*08ca345cSEnji Cooper break; 183*08ca345cSEnji Cooper case TEST_BUILD_SNAPSHOT: 184*08ca345cSEnji Cooper if (snapshot_file != NULL) { 185*08ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_WRITE(usershell, snapshot_file, 186*08ca345cSEnji Cooper &td, sdump_usershell); 187*08ca345cSEnji Cooper } 188*08ca345cSEnji Cooper break; 189*08ca345cSEnji Cooper default: 190*08ca345cSEnji Cooper rv = 0; 191*08ca345cSEnji Cooper break; 192*08ca345cSEnji Cooper } 193*08ca345cSEnji Cooper 194*08ca345cSEnji Cooper fin: 195*08ca345cSEnji Cooper TEST_DATA_DESTROY(usershell, &td_snap); 196*08ca345cSEnji Cooper TEST_DATA_DESTROY(usershell, &td); 197*08ca345cSEnji Cooper 198*08ca345cSEnji Cooper return (rv); 199*08ca345cSEnji Cooper } 200*08ca345cSEnji Cooper 201*08ca345cSEnji Cooper #define SNAPSHOT_FILE "snapshot_usershell" 202*08ca345cSEnji Cooper 203*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getusershell_with_snapshot); 204*08ca345cSEnji Cooper ATF_TC_BODY(getusershell_with_snapshot, tc) 205*08ca345cSEnji Cooper { 206*08ca345cSEnji Cooper 207*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 208*08ca345cSEnji Cooper } 209*08ca345cSEnji Cooper 210*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getusershell_with_two_pass); 211*08ca345cSEnji Cooper ATF_TC_BODY(getusershell_with_two_pass, tc) 212*08ca345cSEnji Cooper { 213*08ca345cSEnji Cooper 214*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 215*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETUSERSHELL) == 0); 216*08ca345cSEnji Cooper } 217*08ca345cSEnji Cooper 218*08ca345cSEnji Cooper ATF_TP_ADD_TCS(tp) 219*08ca345cSEnji Cooper { 220*08ca345cSEnji Cooper 221*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getusershell_with_snapshot); 222*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getusershell_with_two_pass); 223*08ca345cSEnji Cooper 224*08ca345cSEnji Cooper return (atf_no_error()); 225*08ca345cSEnji Cooper } 226