run_stress_test 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #!/bin/bash
  2. # Copyright 2013 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. # Stress test and size measurement for courgette patches.
  6. source "$(dirname ${0})/stress_test_common"
  7. outdir_prefix="stress_test_"
  8. time="/usr/bin/time"
  9. if [ $# -lt 2 ]; then
  10. cat <<EOF
  11. USAGE: $(basename ${0}) [-s] dir1 dir2 [outdir]
  12. -s only test files supported by courgette
  13. Stress test courgette by generating and applying patches for two given
  14. directories, dir1 and dir2. The test will use files with the same
  15. name and relative path in the two directories, which makes it easy to
  16. compare two extracted ChromeOS images. It also compares the unzipped
  17. and bzipped patches against the likewise bsdiff patches. If outdir is
  18. not specified, the name will be "${outdir_prefix}" concatenated with
  19. the current date and time.
  20. EOF
  21. exit 1
  22. fi
  23. if [ "${1}" == "-s" ]; then
  24. test_supported_only=true
  25. shift
  26. else
  27. test_supported_only=
  28. fi
  29. dir1="${1}"
  30. if [ ! -e "${dir1}" ]; then
  31. error "\"${dir1}\" not found"
  32. exit 1
  33. fi
  34. dir2="${2}"
  35. if [ ! -e "${dir2}" ]; then
  36. error "\"${dir2}\" not found"
  37. exit 1
  38. fi
  39. out_dir="${3:-${outdir_prefix}$(date +%Y%m%d_%H%M%S)}"
  40. if [ -e "${out_dir}" ]; then
  41. error "\"${out_dir}\" already exists"
  42. exit 1
  43. fi
  44. mkdir -p "${out_dir}" || exit 1
  45. patches_dir="${out_dir}/patches"
  46. applied_dir="${out_dir}/applied"
  47. dis_dir="${out_dir}/dis"
  48. bsdiff="${out_dir}/bsdiff"
  49. log="${out_dir}/log"
  50. results="${out_dir}/results"
  51. echo "${0} ${@}" > "${log}"
  52. date >> "${log}"
  53. run_test() {
  54. if [[ ! -z "${1}" && ! -z "${2}" ]]; then
  55. local file1="${1}"
  56. local file2="${2}"
  57. local patch="${patches_dir}/${file1}.patch"
  58. local apply="${applied_dir}/${file2}.applied"
  59. local dis="${dis_dir}/${file1}.dis"
  60. local asm="${dis_dir}/${file1}.asm"
  61. mkdir -p "$(dirname "${dis}")"
  62. if [ ! $test_supported_only ]; then
  63. courgette -supported "${file1}" >/dev/null
  64. if [ "${?}" -eq 0 ]; then
  65. courgette -dis "${file1}" "${dis}"
  66. courgette -asm "${dis}" "${asm}"
  67. cmp -s "${file1}" "${asm}"
  68. if [ "${?}" -ne 0 ]; then
  69. echo "FAIL_DISASSEMBLE ${file1}"
  70. fi
  71. fi
  72. fi
  73. mkdir -p "$(dirname "${patch}")"
  74. mkdir -p "$(dirname "${apply}")"
  75. echo "courgette -gen"
  76. ${time} -f "TIME_GEN %e ${file1}" courgette -gen "${file1}" "${file2}" \
  77. "${patch}"
  78. echo "courgette -apply"
  79. ${time} -f "TIME_APPLY %e ${file1}" courgette -apply "${file1}" "${patch}" \
  80. "${apply}"
  81. cmp -s "${file2}" "${apply}"
  82. if [ "${?}" -ne 0 ]; then
  83. echo "FAIL_COURGETTE ${file1}"
  84. else
  85. echo "PASS_COURGETTE ${file1}"
  86. local bsdiff_patch="${patches_dir}/${file1}.bsdiff_patch"
  87. local bsdiff_apply="${applied_dir}/${file2}.bsdiff_applied"
  88. echo "RUN bsdiff"
  89. ${time} -f "TIME_BSDIFF %e ${file1}" bsdiff "${file1}" "${file2}" \
  90. "${bsdiff_patch}"
  91. echo "RUN bspatch"
  92. ${time} -f "TIME_BSPATCH %e ${file1}" bspatch "${file1}" \
  93. "${bsdiff_apply}" "${bsdiff_patch}"
  94. cmp -s "${file2}" "${bsdiff_apply}"
  95. if [ "${?}" -ne 0 ]; then
  96. echo "FAIL_BSDIFF ${file1}"
  97. else
  98. echo "PASS_BSDIFF ${file1}"
  99. local bz2_patch="${patch}.bz2"
  100. local xz_patch="${patch}.xz"
  101. bzip2 -9 -c "${patch}" > "${bz2_patch}"
  102. xz -9 -c "${patch}" > "${xz_patch}"
  103. local patch_size="$(du -b "${bz2_patch}" | cut -f1)"
  104. local bsdiff_patch_size="$(du -b "${bsdiff_patch}" | cut -f1)"
  105. local xz_patch_size="$(du -b "${xz_patch}" | cut -f1)"
  106. echo "SIZE courgette=${patch_size} bsdiff=${bsdiff_patch_size}" \
  107. "courgette_xz=${xz_patch_size} ${file1}"
  108. if [ "${patch_size}" -eq "${bsdiff_patch_size}" ]; then
  109. echo "BEST_TIE ${patch_size} ${file1}"
  110. elif [ "${patch_size}" -lt "${bsdiff_patch_size}" ]; then
  111. echo "BEST_COURGETTE ${patch_size} ${file1}"
  112. elif [ "${patch_size}" -gt "${bsdiff_patch_size}" ]; then
  113. echo "BEST_BSDIFF ${bsdiff_patch_size} ${file1}"
  114. fi
  115. if [ "${xz_patch_size}" -eq "${bsdiff_patch_size}" ]; then
  116. echo "XZBEST_TIE ${xz_patch_size} ${file1}"
  117. elif [ "${xz_patch_size}" -lt "${bsdiff_patch_size}" ]; then
  118. echo "XZBEST_COURGETTE ${xz_patch_size} ${file1}"
  119. elif [ "${xz_patch_size}" -gt "${bsdiff_patch_size}" ]; then
  120. echo "XZBEST_BSDIFF ${bsdiff_patch_size} ${file1}"
  121. fi
  122. fi
  123. fi
  124. fi
  125. }
  126. # Use diff to find the files that appear in both directories.
  127. time diff -qr "${dir1}" "${dir2}" 2>/dev/null \
  128. | grep "^Files" \
  129. | awk '{print $2,$4}' \
  130. | while read file; do
  131. # Use awk to separate the two filenames. May break if filenames
  132. # contain spaces.
  133. file1="$(echo "${file}" | awk '{print $1}')"
  134. file2="$(echo "${file}" | awk '{print $2}')"
  135. if [ $test_supported_only ]; then
  136. courgette -supported "${file1}" >/dev/null
  137. if [ "${?}" -ne 0 ]; then
  138. continue;
  139. fi
  140. fi
  141. run_test "${file1}" "${file2}"
  142. done 2>&1 | tee -a "${log}"
  143. date >> "${log}"
  144. cat <<EOF | tee -a "${log}"
  145. $(count_result "PASS_COURGETTE") successful courgette patches
  146. $(count_result "FAIL_COURGETTE") failed courgette patches (search log for \
  147. "^FAIL_COURGETTE")
  148. $(count_result "FAIL_DISASSEMBLE") failed to disassemble/assemble (search log \
  149. for "^FAIL_DISASSEMBLE")
  150. $(count_result "PASS_BSDIFF") succesful bsdiff patches
  151. $(count_result "FAIL_BSDIFF") failed bsdiff patches
  152. $(count_result "BEST_COURGETTE") patch(es) where courgette (bz2) is smaller
  153. $(count_result "BEST_BSDIFF") patch(es) where bsdiff is smaller (bz2)
  154. $(count_result "BEST_TIE") patch(es) where both are the same size (bz2)
  155. $(count_result "XZBEST_COURGETTE") patch(es) where courgette (xz) is smaller
  156. $(count_result "XZBEST_BSDIFF") patch(es) where bsdiff is smaller (xz)
  157. $(count_result "XZBEST_TIE") patch(es) where both are the same size (xz)
  158. EOF