Home | History | Annotate | Download | only in tests
      1 #!/bin/sh
      2 
      3 # Copyright (c) 2005, Google Inc.
      4 # All rights reserved.
      5 # 
      6 # Redistribution and use in source and binary forms, with or without
      7 # modification, are permitted provided that the following conditions are
      8 # met:
      9 # 
     10 #     * Redistributions of source code must retain the above copyright
     11 # notice, this list of conditions and the following disclaimer.
     12 #     * Redistributions in binary form must reproduce the above
     13 # copyright notice, this list of conditions and the following disclaimer
     14 # in the documentation and/or other materials provided with the
     15 # distribution.
     16 #     * Neither the name of Google Inc. nor the names of its
     17 # contributors may be used to endorse or promote products derived from
     18 # this software without specific prior written permission.
     19 # 
     20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     23 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     24 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     25 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     26 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     30 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31 
     32 # ---
     33 # Author: Craig Silverstein
     34 #
     35 # Runs the heap-profiler unittest and makes sure the profile looks appropriate.
     36 #
     37 # We run under the assumption that if $HEAP_PROFILER is run with --help,
     38 # it prints a usage line of the form
     39 #   USAGE: <actual executable being run> [...]
     40 #
     41 # This is because libtool sometimes turns the 'executable' into a
     42 # shell script which runs an actual binary somewhere else.
     43 
     44 # We expect BINDIR and PPROF_PATH to be set in the environment.
     45 # If not, we set them to some reasonable values
     46 BINDIR="${BINDIR:-.}"
     47 PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
     48 
     49 if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
     50   echo "USAGE: $0 [unittest dir] [path to pprof]"
     51   echo "       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH"
     52   exit 1
     53 fi
     54 
     55 HEAP_PROFILER="${1:-$BINDIR}/heap-profiler_unittest"
     56 PPROF="${2:-$PPROF_PATH}"
     57 TEST_TMPDIR=/tmp/heap_profile_info
     58 
     59 # It's meaningful to the profiler, so make sure we know its state
     60 unset HEAPPROFILE
     61 
     62 rm -rf "$TEST_TMPDIR"
     63 mkdir "$TEST_TMPDIR" || exit 2
     64 
     65 num_failures=0
     66 
     67 # Given one profile (to check the contents of that profile) or two
     68 # profiles (to check the diff between the profiles), and a function
     69 # name, verify that the function name takes up at least 90% of the
     70 # allocated memory.  The function name is actually specified first.
     71 VerifyMemFunction() {
     72   function="$1"
     73   shift
     74 
     75   # get program name.  Note we have to unset HEAPPROFILE so running
     76   # help doesn't overwrite existing profiles.
     77   exec=`unset HEAPPROFILE; $HEAP_PROFILER --help | awk '{print $2; exit;}'`
     78 
     79   if [ $# = 2 ]; then
     80     [ -f "$1" ] || { echo "Profile not found: $1"; exit 1; }
     81     [ -f "$2" ] || { echo "Profile not found: $2"; exit 1; }
     82     $PPROF --base="$1" $exec "$2" >"$TEST_TMPDIR/output.pprof" 2>&1
     83   else
     84     [ -f "$1" ] || { echo "Profile not found: $1"; exit 1; }
     85     $PPROF $exec "$1" >"$TEST_TMPDIR/output.pprof" 2>&1
     86   fi
     87 
     88   cat "$TEST_TMPDIR/output.pprof" \
     89       | tr -d % | awk '$6 ~ /^'$function'$/ && $2 > 90 {exit 1;}'
     90   if [ $? != 1 ]; then
     91     echo
     92     echo "--- Test failed for $function: didn't account for 90% of executable memory"
     93     echo "--- Program output:"
     94     cat "$TEST_TMPDIR/output"
     95     echo "--- pprof output:"
     96     cat "$TEST_TMPDIR/output.pprof"
     97     echo "---"
     98     num_failures=`expr $num_failures + 1`
     99   fi
    100 }
    101 
    102 VerifyOutputContains() {
    103   text="$1"
    104 
    105   if ! grep "$text" "$TEST_TMPDIR/output" >/dev/null 2>&1; then
    106     echo "--- Test failed: output does not contain '$text'"
    107     echo "--- Program output:"
    108     cat "$TEST_TMPDIR/output"
    109     echo "---"
    110     num_failures=`expr $num_failures + 1`
    111   fi
    112 }
    113 
    114 HEAPPROFILE="$TEST_TMPDIR/test"
    115 HEAP_PROFILE_INUSE_INTERVAL="10240"   # need this to be 10Kb
    116 HEAP_PROFILE_ALLOCATION_INTERVAL="$HEAP_PROFILE_INUSE_INTERVAL"
    117 HEAP_PROFILE_DEALLOCATION_INTERVAL="$HEAP_PROFILE_INUSE_INTERVAL"
    118 export HEAPPROFILE
    119 export HEAP_PROFILE_INUSE_INTERVAL
    120 export HEAP_PROFILE_ALLOCATION_INTERVAL
    121 export HEAP_PROFILE_DEALLOCATION_INTERVAL
    122 
    123 # We make the unittest run a child process, to test that the child
    124 # process doesn't try to write a heap profile as well and step on the
    125 # parent's toes.  If it does, we expect the parent-test to fail.
    126 $HEAP_PROFILER 1 >$TEST_TMPDIR/output 2>&1     # run program, with 1 child proc
    127 
    128 VerifyMemFunction Allocate2 "$HEAPPROFILE.1329.heap"
    129 VerifyMemFunction Allocate "$HEAPPROFILE.1448.heap" "$HEAPPROFILE.1548.heap"
    130 
    131 # Check the child process got to emit its own profile as well.
    132 VerifyMemFunction Allocate2 "$HEAPPROFILE"_*.1329.heap
    133 VerifyMemFunction Allocate "$HEAPPROFILE"_*.1448.heap "$HEAPPROFILE"_*.1548.heap
    134 
    135 # Make sure we logged both about allocating and deallocating memory
    136 VerifyOutputContains "62 MB allocated"
    137 VerifyOutputContains "62 MB freed"
    138 
    139 # Now try running without --heap_profile specified, to allow
    140 # testing of the HeapProfileStart/Stop functionality.
    141 $HEAP_PROFILER >"$TEST_TMPDIR/output2" 2>&1
    142 
    143 rm -rf $TMPDIR      # clean up
    144 
    145 if [ $num_failures = 0 ]; then
    146   echo "PASS"
    147 else
    148   echo "Tests finished with $num_failures failures"
    149 fi
    150 exit $num_failures
    151