heap-profiler_unittest.sh 5.4 KB

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