Tutorial: Moodle VPL -- Catching Java Programs that Hung
--D. Thiebaut (talk) 14:53, 28 September 2014 (EDT)
This VPL module loops through different tests to evaluate a Java program. It also has a time-out feature in case the java program goes into an infinite loop.
Setup
- Homework 3, Problem 2
- Requested files: Hw3_2.java (Download)
- Run: Yes Evaluate: Yes
- Automatic grade: Yes
- See http://cs.smith.edu/dftwiki/index.php/CSC212_Homework_3_2014 for more info.
- Requested files: Hw3_2.java
Execution Files
vpl_run.sh
#! /bin/bash
# D. Thiebaut
cat > vpl_execution <<EEOOFF
#! /bin/bash
prog1=Hw3_2
javac \${prog1}.java
if ((\$? > 0)); then
echo "Error compiling your program"
exit
fi
# --- create test input files ---
cat > data1.txt <<EOF
Cardiff Bute Park
Location 3176E 1773N, 9 metres amsl
Estimated data is marked with a * after the value.
yyyy mm tmax tmin af rain sun
degC degC days mm hours
1977 9 18.3 8.1 0 48.6 117.9
1977 10 15.4 9.0 0 76.0 80.4
1977 11 10.3 4.7 4 147.9 76.4
1977 12 9.6 4.6 2 88.0 25.6
1978 1 7.5 2.0 6 134.1 64.7
1978 2 6.2 0.9 13 134.1 56.9
...
2009 7 20.2 13.1 0 194.1 ---
2009 8 20.7 --- 0 76.0 120.5
2009 9 19.1 10.6 0 34.7 ---
2009 10 16.3 8.6 0 73.6 ---
2009 11 12.6 6.5 0 220.4 ---
2009 12 7.2 0.0 15 114.9 ---
2010 1 6.0 -1.2 16 73.5 ---
2010 2 7.3 0.8 7 72.1 ---
EOF
echo "Testing your program with a text file containing:"
cat data1.txt
echo ""
echo "Output of your program:"
java \${prog1} data1.txt
EEOOFF
chmod +x vpl_execution
vpl_evaluate.sh
#! /bin/bash
# D. Thiebaut
cat > vpl_execution <<EEOOFF
#! /bin/bash
# --- program tested (no extension) ---
prog1=Hw3_2
gradeNotCompile=20
gradeCompileNoGoodOutput=30
gradeIncrement=35 # (100-30)/2 / number of tests
# --- 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
# =================================================
# --- create test input files ---
cat > data1.txt <<EOF
Cardiff Bute Park
Location 3176E 1773N, 9 metres amsl
Estimated data is marked with a * after the value.
yyyy mm tmax tmin af rain sun
degC degC days mm hours
1977 9 18.3 8.1 0 48.6 117.9
1977 10 15.4 9.0 0 76.0 80.4
1977 11 10.3 4.7 4 147.9 76.4
1977 12 9.6 4.6 2 88.0 25.6
1978 1 7.5 2.0 6 134.1 64.7
1978 2 6.2 0.9 13 134.1 56.9
...
2009 7 20.2 13.1 0 194.1 ---
2009 8 20.7 5.5 0 76.0 120.5
2009 9 19.1 10.6 0 34.7 ---
2009 10 16.3 8.6 0 73.6 ---
2009 11 12.6 6.5 0 220.4 ---
2009 12 7.2 0.0 15 114.9 ---
2010 1 6.0 -1.2 16 73.5 ---
2010 2 7.3 0.8 7 72.1 ---
EOF
cat > data2.txt <<EOF
yyyy mm tmax tmin af rain sun
degC degC days mm hours
1976 9 18.3 8.1 0 30.3 117.9
1979 9 18.3 8.1 0 48.6 ---
EOF
#--- create expected outputs ---
cat > data1.out <<EOF
rain 2009 220.40
sun 2009 120.50
EOF
cat > data2.out <<EOF
rain 1979 48.60
sun 1976 117.90
EOF
# =================================================
# function that prints the difference between user and expected output
incorrectOutput() {
if [ "\$1" ]; then # if there's a parameter
i=\$1
echo "Comment :=>>- Your output is incorrect."
#--- display test file ---
echo "Comment :=>>- Your program tested with:"
echo "<|--"
cat data\${i}.txt
echo "--|>"
echo "Comment :=>> ---------------"
echo "Comment :=>>- Your output:"
echo "Comment :=>> ---------------"
echo "<|--"
cat user.out.org
echo "--|>"
echo ""
echo "Comment :=>> ---------------"
echo "Comment :=>>- Expected output (only the numbers): "
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
}
# =================================================
# --- LOOP THROUGH THE TEST FILES ---
for i in 1 2 ; do
echo "Comment :=>>-TEST \$i"
# ==============================================
# 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 ---
#--- spawn the program and get its pid ---
timeout 30 java \${prog1} data\${i}.txt &> user.out
retcode=\$?
#--- if we killed the waiter, everything is good ---
if [ \$retcode -eq 124 ]; then
echo "Comment :=>>-Your program has stopped working."
timeoutOutput \$i
continue
else
echo "Comment :=>>-Your program ran to completion."
fi
cp user.out user.out.org
#--- 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
# =================================================
# Report grade
if (( grade > 100 )); then
grade=100
fi
echo "Grade :=>> \$grade"
EEOOFF
chmod +x vpl_execution