108ca345cSEnji Cooper /*- 208ca345cSEnji Cooper * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org> 308ca345cSEnji Cooper * All rights reserved. 408ca345cSEnji Cooper * 508ca345cSEnji Cooper * Redistribution and use in source and binary forms, with or without 608ca345cSEnji Cooper * modification, are permitted provided that the following conditions 708ca345cSEnji Cooper * are met: 808ca345cSEnji Cooper * 1. Redistributions of source code must retain the above copyright 908ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer. 1008ca345cSEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 1108ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer in the 1208ca345cSEnji Cooper * documentation and/or other materials provided with the distribution. 1308ca345cSEnji Cooper * 1408ca345cSEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1508ca345cSEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1608ca345cSEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1708ca345cSEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1808ca345cSEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1908ca345cSEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2008ca345cSEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2108ca345cSEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2208ca345cSEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2308ca345cSEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2408ca345cSEnji Cooper * SUCH DAMAGE. 2508ca345cSEnji Cooper * 2608ca345cSEnji Cooper */ 2708ca345cSEnji Cooper 2808ca345cSEnji Cooper #include <sys/cdefs.h> 2908ca345cSEnji Cooper __FBSDID("$FreeBSD$"); 3008ca345cSEnji Cooper 3108ca345cSEnji Cooper #include <assert.h> 3208ca345cSEnji Cooper #include <errno.h> 3308ca345cSEnji Cooper #include <stdio.h> 3408ca345cSEnji Cooper #include <stdlib.h> 3508ca345cSEnji Cooper #include <string.h> 3608ca345cSEnji Cooper #include <unistd.h> 3708ca345cSEnji Cooper 3808ca345cSEnji Cooper #include <atf-c.h> 3908ca345cSEnji Cooper 4008ca345cSEnji Cooper #include "testutil.h" 4108ca345cSEnji Cooper 4208ca345cSEnji Cooper enum test_methods { 4308ca345cSEnji Cooper TEST_GETUSERSHELL, 4408ca345cSEnji Cooper TEST_BUILD_SNAPSHOT 4508ca345cSEnji Cooper }; 4608ca345cSEnji Cooper 4708ca345cSEnji Cooper struct usershell { 4808ca345cSEnji Cooper char *path; 4908ca345cSEnji Cooper }; 5008ca345cSEnji Cooper 5108ca345cSEnji Cooper DECLARE_TEST_DATA(usershell) 5208ca345cSEnji Cooper DECLARE_TEST_FILE_SNAPSHOT(usershell) 5308ca345cSEnji Cooper DECLARE_2PASS_TEST(usershell) 5408ca345cSEnji Cooper 5508ca345cSEnji Cooper static void clone_usershell(struct usershell *, struct usershell const *); 5608ca345cSEnji Cooper static int compare_usershell(struct usershell *, struct usershell *, void *); 5708ca345cSEnji Cooper static void free_usershell(struct usershell *); 5808ca345cSEnji Cooper 5908ca345cSEnji Cooper static void sdump_usershell(struct usershell *, char *, size_t); 6008ca345cSEnji Cooper static void dump_usershell(struct usershell *); 6108ca345cSEnji Cooper 6208ca345cSEnji Cooper IMPLEMENT_TEST_DATA(usershell) 6308ca345cSEnji Cooper IMPLEMENT_TEST_FILE_SNAPSHOT(usershell) 6408ca345cSEnji Cooper IMPLEMENT_2PASS_TEST(usershell) 6508ca345cSEnji Cooper 6608ca345cSEnji Cooper static void 6708ca345cSEnji Cooper clone_usershell(struct usershell *dest, struct usershell const *src) 6808ca345cSEnji Cooper { 6908ca345cSEnji Cooper assert(dest != NULL); 7008ca345cSEnji Cooper assert(src != NULL); 7108ca345cSEnji Cooper 7208ca345cSEnji Cooper if (src->path != NULL) { 7308ca345cSEnji Cooper dest->path = strdup(src->path); 7408ca345cSEnji Cooper assert(dest->path != NULL); 7508ca345cSEnji Cooper } 7608ca345cSEnji Cooper } 7708ca345cSEnji Cooper 7808ca345cSEnji Cooper static int 79*93ee3b7eSEnji Cooper compare_usershell(struct usershell *us1, struct usershell *us2, 80*93ee3b7eSEnji Cooper void *mdata __unused) 8108ca345cSEnji Cooper { 8208ca345cSEnji Cooper int rv; 8308ca345cSEnji Cooper 8408ca345cSEnji Cooper assert(us1 != NULL); 8508ca345cSEnji Cooper assert(us2 != NULL); 8608ca345cSEnji Cooper 8708ca345cSEnji Cooper dump_usershell(us1); 8808ca345cSEnji Cooper dump_usershell(us2); 8908ca345cSEnji Cooper 9008ca345cSEnji Cooper if (us1 == us2) 9108ca345cSEnji Cooper return (0); 9208ca345cSEnji Cooper 9308ca345cSEnji Cooper rv = strcmp(us1->path, us2->path); 9408ca345cSEnji Cooper if (rv != 0) { 9508ca345cSEnji Cooper printf("following structures are not equal:\n"); 9608ca345cSEnji Cooper dump_usershell(us1); 9708ca345cSEnji Cooper dump_usershell(us2); 9808ca345cSEnji Cooper } 9908ca345cSEnji Cooper 10008ca345cSEnji Cooper return (rv); 10108ca345cSEnji Cooper } 10208ca345cSEnji Cooper 10308ca345cSEnji Cooper static void 10408ca345cSEnji Cooper free_usershell(struct usershell *us) 10508ca345cSEnji Cooper { 10608ca345cSEnji Cooper free(us->path); 10708ca345cSEnji Cooper } 10808ca345cSEnji Cooper 10908ca345cSEnji Cooper static void 11008ca345cSEnji Cooper sdump_usershell(struct usershell *us, char *buffer, size_t buflen) 11108ca345cSEnji Cooper { 11208ca345cSEnji Cooper snprintf(buffer, buflen, "%s", us->path); 11308ca345cSEnji Cooper } 11408ca345cSEnji Cooper 11508ca345cSEnji Cooper static void 11608ca345cSEnji Cooper dump_usershell(struct usershell *us) 11708ca345cSEnji Cooper { 11808ca345cSEnji Cooper if (us != NULL) { 11908ca345cSEnji Cooper char buffer[2048]; 12008ca345cSEnji Cooper sdump_usershell(us, buffer, sizeof(buffer)); 12108ca345cSEnji Cooper printf("%s\n", buffer); 12208ca345cSEnji Cooper } else 12308ca345cSEnji Cooper printf("(null)\n"); 12408ca345cSEnji Cooper } 12508ca345cSEnji Cooper 12608ca345cSEnji Cooper static int 12708ca345cSEnji Cooper usershell_read_snapshot_func(struct usershell *us, char *line) 12808ca345cSEnji Cooper { 12908ca345cSEnji Cooper 13008ca345cSEnji Cooper us->path = strdup(line); 13108ca345cSEnji Cooper ATF_REQUIRE(us->path != NULL); 13208ca345cSEnji Cooper 13308ca345cSEnji Cooper return (0); 13408ca345cSEnji Cooper } 13508ca345cSEnji Cooper 136bbccc5a7SEnji Cooper static int 13708ca345cSEnji Cooper run_tests(const char *snapshot_file, enum test_methods method) 13808ca345cSEnji Cooper { 13908ca345cSEnji Cooper struct usershell_test_data td, td_snap; 14008ca345cSEnji Cooper struct usershell ushell; 14108ca345cSEnji Cooper int rv; 14208ca345cSEnji Cooper 14308ca345cSEnji Cooper rv = 0; 14408ca345cSEnji Cooper 14508ca345cSEnji Cooper TEST_DATA_INIT(usershell, &td, clone_usershell, free_usershell); 14608ca345cSEnji Cooper TEST_DATA_INIT(usershell, &td_snap, clone_usershell, free_usershell); 14708ca345cSEnji Cooper 14808ca345cSEnji Cooper setusershell(); 14908ca345cSEnji Cooper while ((ushell.path = getusershell()) != NULL) { 15008ca345cSEnji Cooper printf("usershell found:\n"); 15108ca345cSEnji Cooper dump_usershell(&ushell); 15208ca345cSEnji Cooper TEST_DATA_APPEND(usershell, &td, &ushell); 15308ca345cSEnji Cooper } 15408ca345cSEnji Cooper endusershell(); 15508ca345cSEnji Cooper 15608ca345cSEnji Cooper if (snapshot_file != NULL) { 15708ca345cSEnji Cooper if (access(snapshot_file, W_OK | R_OK) != 0) { 15808ca345cSEnji Cooper if (errno == ENOENT) 15908ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 16008ca345cSEnji Cooper else { 16108ca345cSEnji Cooper printf("can't access the snapshot file %s\n", 16208ca345cSEnji Cooper snapshot_file); 16308ca345cSEnji Cooper 16408ca345cSEnji Cooper rv = -1; 16508ca345cSEnji Cooper goto fin; 16608ca345cSEnji Cooper } 16708ca345cSEnji Cooper } else { 16808ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_READ(usershell, snapshot_file, 16908ca345cSEnji Cooper &td_snap, usershell_read_snapshot_func); 17008ca345cSEnji Cooper if (rv != 0) { 17108ca345cSEnji Cooper printf("error reading snapshot file\n"); 17208ca345cSEnji Cooper goto fin; 17308ca345cSEnji Cooper } 17408ca345cSEnji Cooper } 17508ca345cSEnji Cooper } 17608ca345cSEnji Cooper 17708ca345cSEnji Cooper switch (method) { 17808ca345cSEnji Cooper case TEST_GETUSERSHELL: 17908ca345cSEnji Cooper rv = DO_2PASS_TEST(usershell, &td, &td_snap, 18008ca345cSEnji Cooper compare_usershell, NULL); 18108ca345cSEnji Cooper break; 18208ca345cSEnji Cooper case TEST_BUILD_SNAPSHOT: 18308ca345cSEnji Cooper if (snapshot_file != NULL) { 18408ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_WRITE(usershell, snapshot_file, 18508ca345cSEnji Cooper &td, sdump_usershell); 18608ca345cSEnji Cooper } 18708ca345cSEnji Cooper break; 18808ca345cSEnji Cooper default: 18908ca345cSEnji Cooper rv = 0; 19008ca345cSEnji Cooper break; 19108ca345cSEnji Cooper } 19208ca345cSEnji Cooper 19308ca345cSEnji Cooper fin: 19408ca345cSEnji Cooper TEST_DATA_DESTROY(usershell, &td_snap); 19508ca345cSEnji Cooper TEST_DATA_DESTROY(usershell, &td); 19608ca345cSEnji Cooper 19708ca345cSEnji Cooper return (rv); 19808ca345cSEnji Cooper } 19908ca345cSEnji Cooper 20008ca345cSEnji Cooper #define SNAPSHOT_FILE "snapshot_usershell" 20108ca345cSEnji Cooper 20208ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getusershell_with_snapshot); 20308ca345cSEnji Cooper ATF_TC_BODY(getusershell_with_snapshot, tc) 20408ca345cSEnji Cooper { 20508ca345cSEnji Cooper 20608ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 20708ca345cSEnji Cooper } 20808ca345cSEnji Cooper 20908ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getusershell_with_two_pass); 21008ca345cSEnji Cooper ATF_TC_BODY(getusershell_with_two_pass, tc) 21108ca345cSEnji Cooper { 21208ca345cSEnji Cooper 21308ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 21408ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETUSERSHELL) == 0); 21508ca345cSEnji Cooper } 21608ca345cSEnji Cooper 21708ca345cSEnji Cooper ATF_TP_ADD_TCS(tp) 21808ca345cSEnji Cooper { 21908ca345cSEnji Cooper 22008ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getusershell_with_snapshot); 22108ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getusershell_with_two_pass); 22208ca345cSEnji Cooper 22308ca345cSEnji Cooper return (atf_no_error()); 22408ca345cSEnji Cooper } 225