#!/bin/sh

# general.sh  
#
# Copyright (c) 2005 Intel Corporation
# Copyright (c) 2005 The Open Group
# All rights reserved except as granted by this License.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the "Artistic License" which comes with this
# Kit, with the following modification:
# a) "executable(s)" should be interpreted to include "test case(s)"
# b) if you wish to make changes as defined in clause 2 and 3, and
# distribute a modified version of this package, then
# clauses 3c and 4c are required
# c) Clause 7 is rephrased as follows: "Subroutines supplied by you
# and linked into this Package shall not be considered part of this
# Package".
#
#
# Intel Corporation and The Open Group DISCLAIM ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTEL OR THE OPEN GROUP BE
# LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# You should have received a copy of the Artistic License with this
# Kit, in the file named "Artistic".  If not, we'll be glad to provide one.
#
# This is $Revision: 1.25 $
#
# $Log: general.sh,v $
# Revision 1.25  2005/06/25 06:02:12  ajosey
# ensure we call remove_initd in cleanup, this assumes its ok to make redundant calls to remove_initd
#
# Revision 1.24  2005/06/24 12:18:56  mats
# Move decision on non-SYSV style to helper routines which look at
# the rc.d files. Allows tests to be executed, but without the manual
# crosscheck, instead of not doing the tests at all if non-SYSV-init.
#
# Revision 1.23  2005/06/23 22:04:29  mats
# a little more tracing on what's going on (this is helping me track
# down a problem!)
#
# Revision 1.22  2005/06/23 21:00:52  mats
# Be more wordy about what's being tested in each TP.  Note this is just an
# interim while we think about having the assertions (and maybe strategy)
# in-line.  Also replicate some error handling to be sure a TP can be
# run individually (this was something checked only by tp1).
#
# Revision 1.21  2005/06/23 19:30:52  mats
# one-time reformat to indentation style used by FHS tests
# no functional changes (some comments moved, so there are diffs)
#
#

tet_startup="startup"			# startup function
tet_cleanup="cleanup"			# cleanup function
iclist="ic1 ic2 ic3 ic4 ic5"
# for debugging a single test
#iclist="ic5"
ic1="tp1"
ic2="tp2"
ic3="tp3"
ic4="tp4"
ic5="tp5"


tp1()
{
    tpstart "Reference 20-3.1(C), Testing activation of initscript"
    tet_infoline "An initscript shall be activated by a call to install_initd"

    startup_internal
    check_exit_value $? 0
    if [ $FAIL = Y ]
    then
	tet_infoline "Prerequisite startup_internal failed"
	tpresult UNINITIATED
	return
    fi

    tet_infoline "Call $LSB_INSTALL_INITD /etc/init.d/lsb-initB"
    lsb_execwithpriv $LSB_INSTALL_INITD /etc/init.d/lsb-initB >out.stdout 2> out.sdterr
    check_exit_value $? 0
    check_nostderr
    checkinitfileexists lsb-initB

    cleanup_internal
    tpresult
}

tp2()
{
    tpstart "Reference 20.3-2(C) Testing activation of initscript"
    tet_infoline "If an initscript depends on a boot facility it shall be activated"
    tet_infoline "by a call to install_initd if the dependency is met"

    startup_internal
    check_exit_value $? 0
    if [ $FAIL = Y ]
    then
	tet_infoline "Prerequisite startup_internal failed"
	tpresult UNINITIATED
	return
    fi

    tet_infoline "Call $LSB_INSTALL_INITD /etc/init.d/lsb-initB"
    lsb_execwithpriv $LSB_INSTALL_INITD /etc/init.d/lsb-initB >out.stdout 2> out.sdterr
    check_exit_value $? 0

    tet_infoline "Call $LSB_INSTALL_INITD /etc/init.d/lsb-initA"
    lsb_execwithpriv $LSB_INSTALL_INITD /etc/init.d/lsb-initA >out.stdout 2> out.sdterr
    check_exit_value $? 0 

    checkinitfileexists lsb-initA
    checkinitfileexists lsb-initB

    tet_infoline "Check that the installed lsb-initA init script"
    tet_infoline "is lexically greater than the installed lsb-initB init script"
    iA=`ls $LSB_INITD_RC_PARENT_DIR/rc2.d/S??lsb-initA`
    iB=`ls $LSB_INITD_RC_PARENT_DIR/rc2.d/S??lsb-initB`
    # echo $iA $iB
    if  expr "$iA" \< "$iB" > /dev/null
    then
	tet_infoline "scripts are installed incorrectly, lexically lsb-initA is expected after lsb-initB"
	FAIL=Y
    fi

    cleanup_internal
    tpresult                        # set result code
}

tp3()
{
    tpstart "Reference 20.3-3(C) Testing activation of initscript"
    tet_infoline "If an initscript depends on a boot facility it shall not be"
    tet_infoline "activated by a call to install_initd if the dependency is not met"

    startup_internal
    check_exit_value $? 0
    if [ $FAIL = Y ]
    then
	tet_infoline "Prerequisite startup_internal failed"
	tpresult UNINITIATED
	return
    fi

    tet_infoline "Call $LSB_INSTALL_INITD /etc/init.d/lsb-initA"
    lsb_execwithpriv $LSB_INSTALL_INITD /etc/init.d/lsb-initA >out.stdout 2> out.sdterr
    check_exit_value2 $? 1

    # check that lsb-initA was not activated
    checkinitfilenonexist lsb-initA

    cleanup_internal
    tpresult                        # set result code
}

tp4()
{
    tpstart "Reference 20.4-4(C) Testing deactivation of initscript"
    tet_infoline "An initscript shall be deactivated by a call to remove_initd"

    startup_internal
    check_exit_value $? 0
    if [ $FAIL = Y ]
    then
	tet_infoline "Prerequisite startup_internal failed"
	tpresult UNINITIATED
	return
    fi

    tet_infoline "Call $LSB_INSTALL_INITD /etc/init.d/lsb-initB"
    lsb_execwithpriv $LSB_INSTALL_INITD /etc/init.d/lsb-initB >out.stdout 2> out.sdterr
    check_exit_value $? 0

    checkinitfileexists lsb-initB

    if [ $FAIL != Y ]
    then
        tet_infoline "Call $LSB_REMOVE_INITD /etc/init.d/lsb-initB"
	lsb_execwithpriv $LSB_REMOVE_INITD /etc/init.d/lsb-initB >out.stdout 2> out.sdterr
	check_exit_value $? 0

	# check that lsb-initB was removed
	checkinitfilenonexist lsb-initB
    fi

    cleanup_internal
    tpresult                        # set result code
}

tp5()
{
    tpstart "Reference 20.4-5(C)  Testing deactivation of initscript"
    tet_infoline "If a boot facility provided by an initscript is depended on by another"
    tet_infoline "initscript the script shall not be deactivated by a call to remove_initd"

    startup_internal
    check_exit_value $? 0
    if [ $FAIL = Y ]
    then
	tet_infoline "Prerequisite startup_internal failed"
	tpresult UNINITIATED
	return
    fi

    tet_infoline "Call $LSB_INSTALL_INITD /etc/init.d/lsb-initB"
    lsb_execwithpriv $LSB_INSTALL_INITD /etc/init.d/lsb-initB >out.stdout 2> out.sdterr
    check_exit_value $? 0

    tet_infoline "Call $LSB_INSTALL_INITD /etc/init.d/lsb-initA"
    lsb_execwithpriv $LSB_INSTALL_INITD /etc/init.d/lsb-initA >out.stdout 2> out.sdterr
    check_exit_value $? 0 

    checkinitfileexists lsb-initA
    checkinitfileexists lsb-initB
    
    # Verify B can not be un-installed since A is installed and depends on B
    tet_infoline "Call $LSB_INSTALL_INITD /etc/init.d/lsb-initB"
    lsb_execwithpriv $LSB_REMOVE_INITD /etc/init.d/lsb-initB >out.stdout 2> out.sdterr
    check_exit_value $? 1
    checkinitfileexists lsb-initB

    cleanup_internal
    tpresult                        # set result code
}

## common routines and startup code follow

#
# check for a named init file in initscript directories
#
checkinitfileexists () 
{
    if [ "$LSB_INITD_SYSV_INIT" != "true" ]
    then
	tet_infoline "The implementation does not provide a System V Init mechanism"
	tet_infoline "not checking for activated links"
	return
    fi

    fname=$1
    tet_infoline "Check that $fname is installed in initscript directories"
    
    # don't check exit status for K* files, some systems do not use them 
    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc0.d/K??$fname  >out.stdout 2>out.stderr
    #check_exit_value2 $? 2

    # don't check exit status for K* files, some systems do not use them
    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc1.d/K??$fname  >out.stdout 2>out.stderr
    #check_exit_value2 $? 2

    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc2.d/S??$fname  >out.stdout 2>out.stderr
    check_exit_value2 $? 2

    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc3.d/S??$fname  >out.stdout 2>out.stderr
    check_exit_value2 $? 2

    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc4.d/S??$fname  >out.stdout 2>out.stderr
    check_exit_value2 $? 2

    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc5.d/S??$fname  >out.stdout 2>out.stderr
    check_exit_value2 $? 2

    # don't check exit status for K* files, some systems do not use them
    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc6.d/K??$fname  >out.stdout 2>out.stderr
    #check_exit_value2 $? 2

    return 0
}

#
# Check that a named init file does not exist in initscript directories
#
checkinitfilenonexist () 
{
    if [ "$LSB_INITD_SYSV_INIT" != "true" ]
    then
	tet_infoline "The implementation does not provide a System V Init mechanism"
	tet_infoline "not checking for activated links"
	return
    fi

    fname=$1
    tet_infoline "Check that $fname is not installed in initscript directories"

    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc0.d/K??$fname  >out.stdout 2>out.stderr
    check_exit_value2 $? 1

    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc1.d/K??$fname  >out.stdout 2>out.stderr
    check_exit_value2 $? 1

    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc2.d/S??$fname  >out.stdout 2>out.stderr
    check_exit_value2 $? 1

    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc3.d/S??$fname  >out.stdout 2>out.stderr
    check_exit_value2 $? 1

    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc4.d/S??$fname  >out.stdout 2>out.stderr
    check_exit_value2 $? 1

    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc5.d/S??$fname  >out.stdout 2>out.stderr
    check_exit_value2 $? 1

    lsb_test_file $LSB_INITD_RC_PARENT_DIR/rc6.d/K??$fname  >out.stdout 2>out.stderr
    check_exit_value2 $? 1
    return 0
}

# startup function
startup()
{
    rm -f out.stdout out.stderr out.experr dev.out fail.out >/dev/null 2>&1

    # if the pathnames are not set to the correct lsb paths, just delete
    # a single test to allow the rest to run for debugging purposes.
    if  [ "$LSB_INSTALL_INITD" != "/usr/lib/lsb/install_initd" ]
    then
	tet_delete tp1 "LSB_INSTALL_INITD not set to /usr/lib/lsb/install_initd, this is required for certification"
	return
    fi
    if  [ "$LSB_REMOVE_INITD" != "/usr/lib/lsb/remove_initd" ]
    then
	tet_delete tp1 "LSB_REMOVE_INITD not set to /usr/lib/lsb/remve_initd, this is required for certification "
	return
    fi

    # check that the LSB_INITD_RC_PARENT_DIR is defined in tetexec.cfg
    # as a valid directory name
    # if not then ensure all tests are not run
    if [ ! -d "$LSB_INITD_RC_PARENT_DIR" ]
    then
	tet_infoline "Expected LSB_INITD_RC_PARENT_DIR parameter to be defined in tetexec.cfg as a directory"
	for testcasename in tp1 tp2 tp3 tp4 tp5
	do
	    tet_delete $testcasename "Test Setup Failure, LSB_INITD_RC_PARENT_DIR parameter not set to a directory name"
	done
	return
    fi
}

# startup_internal called at the start of each test case
startup_internal()
{
    if [ "$LSB_INITD_SYSV_INIT" != "true" ]
    then
	return
    fi

    lsb_execwithpriv rm -f $LSB_INITD_RC_PARENT_DIR/rc?.d/*lsb-init* >/dev/null 2>&1
    lsb_execwithpriv rm -f /etc/init.d/lsb-initA >/dev/null 2>&1
    lsb_execwithpriv rm -f /etc/init.d/lsb-initB >/dev/null 2>&1

    #
    # Make sure there are no files hanging around
    # Call test directly rather than lsb_test_file that logs
    # journal entries.
    #
    if test -e $LSB_INITD_RC_PARENT_DIR/rc?.d/*lsb-init*
    then
	FAIL=Y
    fi

    if test -e /etc/init.d/lsb-initA
    then
	FAIL=Y
    fi

    if test -e /etc/init.d/lsb-initB
    then
	FAIL=Y
    fi
    if [ $FAIL = Y ]
    then
	tet_infoline "startup_internal():failed to cleanup test files"
	return 1
    fi

    lsb_execwithpriv cp $LSB_INITD_SCRIPTS_DIR/lsb-initA /etc/init.d
    check_exit_value $? 0 
    if [ $FAIL = Y ]
    then
	tet_infoline "startup_internal():cp $LSB_INITD_SCRIPTS_DIR/lsb-initA /etc/init.d failed "
	return 1
    fi

    lsb_execwithpriv cp $LSB_INITD_SCRIPTS_DIR/lsb-initB /etc/init.d
    check_exit_value $? 0 

    if [ $FAIL = Y ]
    then
	tet_infoline "startup_internal():cp $LSB_INITD_SCRIPTS_DIR/lsb-initB /etc/init.d failed "
	return 1
    fi

    return 0
}

cleanup() # clean-up function
{
    rm -f out.stdout out.stderr out.experr dev.out fail.out >/dev/null 2>&1
}

cleanup_internal()
{
    tet_infoline "Cleanup, deactivate initscripts, if any"
    lsb_execwithpriv $LSB_REMOVE_INITD /etc/init.d/lsb-initA >out.stdout 2> out.sdterr
    lsb_execwithpriv $LSB_REMOVE_INITD /etc/init.d/lsb-initB >out.stdout 2> out.sdterr

    if [ "$LSB_INITD_SYSV_INIT" = "true" ]
    then
        tet_infoline "Cleanup, remove initscript files, if any"
        lsb_execwithpriv rm -f $LSB_INITD_RC_PARENT_DIR/rc?.d/*lsb-init* >/dev/null 2>&1
        lsb_execwithpriv rm -f /etc/init.d/lsb-initA >/dev/null 2>&1
        lsb_execwithpriv rm -f /etc/init.d/lsb-initB >/dev/null 2>&1
    fi
}

# source common shell functions
. $TET_EXECUTE/LIB/shfuncs.sh
. $TET_EXECUTE/LIB/lsbfuncs.sh

# execute shell test case manager - must be last line
. $TET_ROOT/lib/xpg3sh/tcm.sh
