Tutorial: Moodle VPL -- Test Elapsed Time of Program

From dftwiki3
Jump to: navigation, search

--D. Thiebaut (talk) 21:15, 24 October 2014 (EDT)


MoodleVPLLogo.png



Moodle VPL Tutorials



This VPL activity tests a Java program and verifies that it spends more than a predefined amount of seconds to run.


vpl_run.sh


#! /bin/bash
# D. Thiebaut

cat > vpl_execution <<EEOOFF
#! /bin/bash
 
prog1=Hw5_2
 
javac \${prog1}.java > /dev/null
 
if ((\$? > 0)); then
     echo "Error compiling your program"
     exit
fi
Ns=(7 8 9 10 12 14) 
CORRECTOUTPUTS=(40 92 352 724 14200 365596)
for i in \`seq 0 5\`; do
   echo ""
   N=\${Ns[\$i]}
   echo "Test # \$i"
   echo "N = \$N"
   #echo "The correct output is: \${CORRECTOUTPUTS[\$i]}"
   echo "Your program output:"
   echo "java \${prog1} \$N"
   java  \${prog1} \$N
done
echo ""
echo "Done!"
EEOOFF
 
chmod +x vpl_execution


vpl_evaluate.sh


#! /bin/bash
# D. Thiebaut

cat > vpl_execution <<EEOOFF
#! /bin/bash
#set -x
 
# --- program tested (no extension) ---
prog1=Hw5_2

# --- grades 
gradeNotCompile=20
gradeCompileNoGoodOutput=30
gradeIncrement=12    # (100-30)/ number of tests
gradePenaltyTooFast=50

# --- compile student program ---
javac \${prog1}.java 
 
if ((\$? > 0)); then
     echo "Comment :=>>  Error compiling your program"
     echo "Grade :=>> \$gradeNotCompile"
     exit
fi

# --- minimum grade if not passing any test ---
grade=\$gradeCompileNoGoodOutput

# =================================================
Ns=(7 8 9 10 12 14) 
CORRECTOUTPUTS=(40 92 352 724 14200 365596)
NOTESTS=6


# =================================================
# function that prints the difference between user and expected output
incorrectOutput() {
    if [ "\$1" ]; then   # if there's a parameter
        i=\$1
        echo "Comment :=>>- Incorrect output."

        #--- display test file ---
        echo "Comment :=>>- Your program was tested with:"
        echo "<|--" 
        cat data\${i}.txt
        echo "--|>"

        echo "Comment :=>> ---------------"
        echo "Comment :=>>- Your output was: "
        echo "Comment :=>> ---------------"
        echo "<|--"
        cat user.out.org
        echo "--|>"
        echo ""
        echo "Comment :=>> ---------------"
        echo "Comment :=>>- Debug your program, and try again!"
        echo "Comment :=>> ---------------"
        #echo "<|--"
        #cat data\${i}.out
        #echo "--|>"
    fi
}

# function that tells user of program crash or infinite loop, and what the test was.
timeoutOutput() {
    if [ "\$1" ]; then   # if there's a parameter
        i=\$1
        echo "Comment :=>>- Your program has timed out or crashed."

        #--- display test file ---
        echo "Comment :=>>- Your program tested with:"
        echo "<|--" 
        cat data\${i}.txt
        echo "--|>"
    fi
}

# function that removes non-digits, extra spaces, and extra blank lines from text file.
cleanup () {
    if [ "\$1" ]; then   # if there's a parameter
        
        #--- remove non numbers and non minus---
        cat \$1 | sed 's/[^0-9*.0-9\ -]*//g' > dummy.out
        mv dummy.out \$1
 
        #--- remove multiple spaces --- 
        cat \$1 | sed 's/  */ /g' > dummy.out
        mv dummy.out \$1

        #--- remove blank lines ---
        cat \$1 | sed '/^\s*\$/d' > dummy.out
        mv dummy.out \$1
   fi
}


#---------------------------------------------------------
# Start testing here
#---------------------------------------------------------
STARTTIME=\$(date +%s)
NOTESTS_1=\`expr \$NOTESTS - 1 \`
for i in \`seq 0  \$NOTESTS_1 \`; do
   # ==============================================
   # TEST i
   # timeout code from 
   # http://stackoverflow.com/questions/5161193/bash-script-that-kills-a-child-process-after-a-given-timeout
   # ==============================================
   #--- run program, capture output, display to student ---

   N=\${Ns[\$i]}
   echo "Comment :=>>-TEST \$i" 
   echo "Comment :=>> N = \$N"
   echo \$N > data\${i}.txt 

   timeout 50 java \${prog1} \$N  &> user.out
   retcode=\$?

   #--- if we killed the waiter, everything is good ---
   if [ \$retcode -eq  124 ]; then
       echo "Comment :=>>-Your program has stopped working or was taking TOO LONG!"
       timeoutOutput \$i
       continue
   else
       echo "Comment :=>>-Your program ran to completion."
   fi

   cp user.out user.out.org

   #--- copy expected output in output file
   echo \${CORRECTOUTPUTS[\$i]} > data\${i}.out

   #--- remove non numbers, space and extra lines from user.out ---
   #--- and from datai.out
   cleanup user.out
   cleanup data\${i}.out

   #--- compute difference --- 
   diff -y -w --ignore-all-space user.out data\${i}.out > diff.out
   #echo "----- diff.out ------"
   #cat diff.out
   #echo "---------------------"
   #diff -y -w --ignore-all-space user.out data\${i}.out > diff.out

   #--- reject if different ---
   if ((\$? > 0)); then
      incorrectOutput \$i
   
      # --------------------- REWARD IF CORRECT OUTPUT -----------------
   else
      #--- good output ---
      echo "Comment :=>>- Congrats, your output is correct."
      echo "Comment :=>> --------------------------------."
      echo "<|--"
      cat user.out.org
      echo "--|>"
      grade=\$((grade+gradeIncrement))
   fi
done
ENDTIME=\$(date +%s)
ELAPSEDTIME=\$((ENDTIME-STARTIME))

# program is too fast.  Remove 50 points
if [[ (( ELAPSEDTIME < 5 )) ]]; then
   #echo "less than 10 sec"
   grade=\$((grade-gradePenaltyTooFast))
   if (( grade < 0 )); then
      grade=0
   fi
fi


# =================================================
# Report grade
if (( grade > 100 )); then
   grade=100
fi
echo "Grade :=>> \$grade"






EEOOFF
 
chmod +x vpl_execution



...