#!/bin/bash

cd $LTPROOT/testcases/bin

grep -w memory /proc/cgroups 2> /dev/null > /dev/null
if [ $? -ne 0 ]; then
    tst_brkm TBROK NULL "Memory Resource Controller not supported. Skipping all tests"
    exit 0
fi

export TCID="cgroup_mem_tests"
export TST_TOTAL=1
export TST_COUNT=0

TOT_MEM_LIMIT=$1
ACTIVE_MEM_LIMIT=$2
PROC_MEM=$3

TST_PATH=$PWD

PASS=0
FAIL=1

# Check if the test process is killed on crossing boundary
test_proc_kill() {
    $TST_PATH/mem_process -m $PROC_MEM > /dev/null &
    sleep 1
    echo $! > tasks
 
    #Signal the test process to start acquiring memory
    kill -s SIGUSR1 $! 2> /dev/null
    sleep 1

    #Check if killed
    ps -p $! > /dev/null 2> /dev/null
    if [ $? -eq 0 ]; then
	/bin/kill -s "SIGINT" $! 2> /dev/null
    else
	KILLED_CNT=$(($KILLED_CNT + 1))
    fi
}
    
# Validate the memory usage limit imposed by the hierarchically topmost group
testcase_1() {
    TST_COUNT=1
    tst_resm TINFO "Test #1: Checking if the memory usage limit imposed by the topmost group is enforced"

    echo "$ACTIVE_MEM_LIMIT"m > $TST_PATH/mnt/$i/memory.limit_in_bytes
    echo "$TOT_MEM_LIMIT"m > $TST_PATH/mnt/$i/memory.memsw.limit_in_bytes

    mkdir sub 2> /dev/null
    pushd sub > /dev/null

    KILLED_CNT=0
    test_proc_kill;

    if [ $PROC_MEM -gt $TOT_MEM_LIMIT ] && [ $KILLED_CNT -eq 0 ]; then
	result $FAIL "Test #1: failed"
    else
	result $PASS "Test #1: passed"
    fi

    popd > /dev/null
    rmdir sub 2> /dev/null
}


# Record the test results
#
# $1: Result of the test case, $PASS or $FAIL
# $2: Output information
result() {
    RES=$1
    INFO=$2

    if [ $RES -eq $PASS ]; then
	tst_resm TPASS "$INFO"
    else
	FAILED_CNT=$(($FAILED_CNT + 1))
	tst_resm TFAIL "$INFO"
    fi
}	
    

cleanup() {
    if [ -e mnt ]; then
	umount $TST_PATH/mnt 2> /dev/null
	rm -rf mnt 2> /dev/null
    fi
}

do_mount() {
    cleanup;

    mkdir $TST_PATH/mnt 2> /dev/null
    mount -t cgroup -o memory cgroup $TST_PATH/mnt 2> /dev/null
    if [ $? -ne 0 ]; then
	tst_brkm TBROK NULL "Mounting cgroup to temp dir failed"
	rmdir $TST_PATH/mnt 2> /dev/null
	exit 1
    fi
}

do_mount;

echo 1 > mnt/memory.use_hierarchy 2> /dev/null

FAILED_CNT=0

for i in $(seq 1 $TST_TOTAL)
do
    pushd $TST_PATH/mnt > /dev/null
    mkdir $TST_PATH/mnt/$i 2> /dev/null
    pushd $i > /dev/null

    testcase_$i;

    popd > /dev/null
    rmdir $i 2> /dev/null
    popd > /dev/null
done

cleanup;

if [ "$FAILED_CNT" -ne 0 ]; then
    tst_resm TFAIL "cgroup_mem_tests: failed"
    exit 1
else
    tst_resm TPASS "cgroup_mem_tests: passed"
    exit 0
fi
