PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/deps/rocksdb/tools/check_format_compatible.sh

https://gitlab.com/barrel-db/erlang-rocksdb
Shell | 372 lines | 263 code | 48 blank | 61 comment | 41 complexity | 30cb151db65b61b66bdee1b6efbd9b4f MD5 | raw file
  1. #!/usr/bin/env bash
  2. # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
  3. #
  4. # A shell script to build and run different versions of ldb to check for
  5. # expected forward and backward compatibility with "current" version. The
  6. # working copy must have no uncommitted changes.
  7. #
  8. # Usage: <SCRIPT> [ref_for_current]
  9. # `ref_for_current` can be a revision, tag, commit or branch name. Default is HEAD.
  10. #
  11. # Return value 0 means all regression tests pass. 1 if not pass.
  12. #
  13. # Environment options:
  14. # SHORT_TEST=1 - Test only the oldest branch for each kind of test. This is
  15. # a good choice for PR validation as it is relatively fast and will find
  16. # most issues.
  17. # USE_SSH=1 - Connect to GitHub with ssh instead of https
  18. if ! git diff-index --quiet HEAD; then
  19. echo "You have uncommitted changes. Aborting."
  20. exit 1
  21. fi
  22. current_checkout_name=${1:-HEAD}
  23. # This allows the script to work even if with transient refs like "HEAD"
  24. current_checkout_hash="$(git rev-parse --quiet --verify $current_checkout_name)"
  25. if [ "$current_checkout_hash" == "" ]; then
  26. echo "Not a recognized ref: $current_checkout_name"
  27. exit 1
  28. fi
  29. # To restore to prior branch at the end
  30. orig_branch="$(git rev-parse --abbrev-ref HEAD)"
  31. tmp_branch=_tmp_format_compatible
  32. tmp_origin=_tmp_origin
  33. # Don't depend on what current "origin" might be
  34. set -e
  35. git remote remove $tmp_origin 2>/dev/null || true
  36. if [ "$USE_SSH" ]; then
  37. git remote add $tmp_origin "git@github.com:facebook/rocksdb.git"
  38. else
  39. git remote add $tmp_origin "https://github.com/facebook/rocksdb.git"
  40. fi
  41. git fetch $tmp_origin
  42. cleanup() {
  43. echo "== Cleaning up"
  44. git reset --hard || true
  45. git checkout "$orig_branch" || true
  46. git branch -D $tmp_branch || true
  47. git remote remove $tmp_origin || true
  48. }
  49. trap cleanup EXIT # Always clean up, even on failure or Ctrl+C
  50. scriptpath=`dirname ${BASH_SOURCE[0]}`
  51. test_dir=${TEST_TMPDIR:-"/tmp"}"/rocksdb_format_compatible_$USER"
  52. rm -rf ${test_dir:?}
  53. # For saving current version of scripts as we checkout different versions to test
  54. script_copy_dir=$test_dir"/script_copy"
  55. mkdir -p $script_copy_dir
  56. cp -f $scriptpath/*.sh $script_copy_dir
  57. # For shared raw input data
  58. input_data_path=$test_dir"/test_data_input"
  59. mkdir -p $input_data_path
  60. # For external sst ingestion test
  61. ext_test_dir=$test_dir"/ext"
  62. mkdir -p $ext_test_dir
  63. # For DB dump test
  64. db_test_dir=$test_dir"/db"
  65. mkdir -p $db_test_dir
  66. # For backup/restore test (uses DB test)
  67. bak_test_dir=$test_dir"/bak"
  68. mkdir -p $bak_test_dir
  69. python_bin=$(which python3 || which python || echo python3)
  70. # Generate random files.
  71. for i in {1..6}
  72. do
  73. input_data[$i]=$input_data_path/data$i
  74. echo == Generating random input file ${input_data[$i]}
  75. $python_bin - <<EOF
  76. import random
  77. random.seed($i)
  78. symbols=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
  79. with open('${input_data[$i]}', 'w') as f:
  80. for i in range(1,1024):
  81. k = ""
  82. for j in range(1, random.randint(1,32)):
  83. k=k + symbols[random.randint(0, len(symbols) - 1)]
  84. vb = ""
  85. for j in range(1, random.randint(0,128)):
  86. vb = vb + symbols[random.randint(0, len(symbols) - 1)]
  87. v = ""
  88. for j in range(1, random.randint(1, 5)):
  89. v = v + vb
  90. print(k + " ==> " + v, file=f)
  91. EOF
  92. done
  93. # Generate file(s) with sorted keys.
  94. sorted_input_data=$input_data_path/sorted_data
  95. echo == Generating file with sorted keys ${sorted_input_data}
  96. $python_bin - <<EOF
  97. with open('${sorted_input_data}', 'w') as f:
  98. for i in range(0,10):
  99. k = str(i)
  100. v = "value" + k
  101. print(k + " ==> " + v, file=f)
  102. EOF
  103. # db_backward_only_refs defined below the rest
  104. # To check for DB forward compatibility with loading options (old version
  105. # reading data from new), as well as backward compatibility
  106. declare -a db_forward_with_options_refs=("6.6.fb" "6.7.fb" "6.8.fb" "6.9.fb" "6.10.fb" "6.11.fb" "6.12.fb" "6.13.fb" "6.14.fb" "6.15.fb" "6.16.fb" "6.17.fb" "6.18.fb" "6.19.fb" "6.20.fb" "6.21.fb" "6.22.fb" "6.23.fb" "6.24.fb")
  107. # To check for DB forward compatibility without loading options (in addition
  108. # to the "with loading options" set), as well as backward compatibility
  109. declare -a db_forward_no_options_refs=() # N/A at the moment
  110. # To check for SST ingestion backward compatibility (new version reading
  111. # data from old) (ldb ingest_extern_sst added in 5.16.x, back-ported to
  112. # 5.14.x, 5.15.x)
  113. declare -a ext_backward_only_refs=("5.14.fb" "5.15.fb" "5.16.fb" "5.17.fb" "5.18.fb" "6.0.fb" "6.1.fb" "6.2.fb" "6.3.fb" "6.4.fb" "6.5.fb")
  114. # To check for SST ingestion forward compatibility (old version reading
  115. # data from new) as well as backward compatibility
  116. declare -a ext_forward_refs=("${db_forward_no_options_refs[@]}" "${db_forward_with_options_refs[@]}")
  117. # To check for backup backward compatibility (new version reading data
  118. # from old) (ldb backup/restore added in 4.11.x)
  119. declare -a bak_backward_only_refs=("4.11.fb" "4.12.fb" "4.13.fb" "5.0.fb" "5.1.fb" "5.2.fb" "5.3.fb" "5.4.fb" "5.5.fb" "5.6.fb" "5.7.fb" "5.8.fb" "5.9.fb" "5.10.fb" "5.11.fb" "5.12.fb" "5.13.fb" "${ext_backward_only_refs[@]}")
  120. # To check for backup forward compatibility (old version reading data
  121. # from new) as well as backward compatibility
  122. declare -a bak_forward_refs=("${db_forward_no_options_refs[@]}" "${db_forward_with_options_refs[@]}")
  123. # Branches (git refs) to check for DB backward compatibility (new version
  124. # reading data from old) (in addition to the "forward compatible" list)
  125. # NOTE: 2.7.fb.branch shows assertion violation in some configurations
  126. declare -a db_backward_only_refs=("2.2.fb.branch" "2.3.fb.branch" "2.4.fb.branch" "2.5.fb.branch" "2.6.fb.branch" "2.7.fb.branch" "2.8.1.fb" "3.0.fb.branch" "3.1.fb" "3.2.fb" "3.3.fb" "3.4.fb" "3.5.fb" "3.6.fb" "3.7.fb" "3.8.fb" "3.9.fb" "4.2.fb" "4.3.fb" "4.4.fb" "4.5.fb" "4.6.fb" "4.7.fb" "4.8.fb" "4.9.fb" "4.10.fb" "${bak_backward_only_refs[@]}")
  127. if [ "$SHORT_TEST" ]; then
  128. # Use only the first (if exists) of each list
  129. db_backward_only_refs=(${db_backward_only_refs[0]})
  130. db_forward_no_options_refs=(${db_forward_no_options_refs[0]})
  131. db_forward_with_options_refs=(${db_forward_with_options_refs[0]})
  132. ext_backward_only_refs=(${ext_backward_only_refs[0]})
  133. ext_forward_refs=(${ext_forward_refs[0]})
  134. bak_backward_only_refs=(${bak_backward_only_refs[0]})
  135. bak_forward_refs=(${bak_forward_refs[0]})
  136. fi
  137. # De-duplicate & accumulate
  138. declare -a checkout_refs=()
  139. for checkout_ref in "${db_backward_only_refs[@]}" "${db_forward_no_options_refs[@]}" "${db_forward_with_options_refs[@]}" "${ext_backward_only_refs[@]}" "${ext_forward_refs[@]}" "${bak_backward_only_refs[@]}" "${bak_forward_refs[@]}"
  140. do
  141. if [ ! -e $db_test_dir/$checkout_ref ]; then
  142. mkdir -p $db_test_dir/$checkout_ref
  143. checkout_refs+=($checkout_ref)
  144. fi
  145. done
  146. generate_db()
  147. {
  148. set +e
  149. $script_copy_dir/generate_random_db.sh $1 $2
  150. if [ $? -ne 0 ]; then
  151. echo ==== Error loading data from $2 to $1 ====
  152. exit 1
  153. fi
  154. set -e
  155. }
  156. compare_db()
  157. {
  158. set +e
  159. $script_copy_dir/verify_random_db.sh $1 $2 $3 $4 $5
  160. if [ $? -ne 0 ]; then
  161. echo ==== Read different content from $1 and $2 or error happened. ====
  162. exit 1
  163. fi
  164. set -e
  165. }
  166. write_external_sst()
  167. {
  168. set +e
  169. $script_copy_dir/write_external_sst.sh $1 $2 $3
  170. if [ $? -ne 0 ]; then
  171. echo ==== Error writing external SST file using data from $1 to $3 ====
  172. exit 1
  173. fi
  174. set -e
  175. }
  176. ingest_external_sst()
  177. {
  178. set +e
  179. $script_copy_dir/ingest_external_sst.sh $1 $2
  180. if [ $? -ne 0 ]; then
  181. echo ==== Error ingesting external SST in $2 to DB at $1 ====
  182. exit 1
  183. fi
  184. set -e
  185. }
  186. backup_db()
  187. {
  188. set +e
  189. $script_copy_dir/backup_db.sh $1 $2
  190. if [ $? -ne 0 ]; then
  191. echo ==== Error backing up DB $1 to $2 ====
  192. exit 1
  193. fi
  194. set -e
  195. }
  196. restore_db()
  197. {
  198. set +e
  199. $script_copy_dir/restore_db.sh $1 $2
  200. if [ $? -ne 0 ]; then
  201. echo ==== Error restoring from $1 to $2 ====
  202. exit 1
  203. fi
  204. set -e
  205. }
  206. member_of_array()
  207. {
  208. local e match="$1"
  209. shift
  210. for e; do [[ "$e" == "$match" ]] && return 0; done
  211. return 1
  212. }
  213. force_no_fbcode()
  214. {
  215. # Not all branches recognize ROCKSDB_NO_FBCODE and we should not need
  216. # to patch old branches for changes to available FB compilers.
  217. sed -i -e 's|-d /mnt/gvfs/third-party|"$ROCKSDB_FORCE_FBCODE"|' build_tools/build_detect_platform
  218. }
  219. # General structure from here:
  220. # * Check out, build, and do stuff with the "current" branch.
  221. # * For each older branch under consideration,
  222. # * Check out, build, and do stuff with it, potentially using data
  223. # generated from "current" branch.
  224. # * (Again) check out, build, and do (other) stuff with the "current"
  225. # branch, potentially using data from older branches.
  226. #
  227. # This way, we only do at most n+1 checkout+build steps, without the
  228. # need to stash away executables.
  229. # Decorate name
  230. current_checkout_name="$current_checkout_name ($current_checkout_hash)"
  231. echo "== Building $current_checkout_name debug"
  232. git checkout -B $tmp_branch $current_checkout_hash
  233. force_no_fbcode
  234. make clean
  235. DISABLE_WARNING_AS_ERROR=1 make ldb -j32
  236. echo "== Using $current_checkout_name, generate DB with extern SST and ingest"
  237. current_ext_test_dir=$ext_test_dir"/current"
  238. write_external_sst $input_data_path ${current_ext_test_dir}_pointless $current_ext_test_dir
  239. ingest_external_sst ${current_ext_test_dir}_ingest $current_ext_test_dir
  240. echo "== Generating DB from $current_checkout_name ..."
  241. current_db_test_dir=$db_test_dir"/current"
  242. generate_db $input_data_path $current_db_test_dir
  243. echo "== Creating backup of DB from $current_checkout_name ..."
  244. current_bak_test_dir=$bak_test_dir"/current"
  245. backup_db $current_db_test_dir $current_bak_test_dir
  246. for checkout_ref in "${checkout_refs[@]}"
  247. do
  248. echo "== Building $checkout_ref debug"
  249. git reset --hard $tmp_origin/$checkout_ref
  250. force_no_fbcode
  251. make clean
  252. DISABLE_WARNING_AS_ERROR=1 make ldb -j32
  253. # We currently assume DB backward compatibility for every branch listed
  254. echo "== Use $checkout_ref to generate a DB ..."
  255. generate_db $input_data_path $db_test_dir/$checkout_ref
  256. if member_of_array "$checkout_ref" "${ext_backward_only_refs[@]}" ||
  257. member_of_array "$checkout_ref" "${ext_forward_refs[@]}"
  258. then
  259. echo "== Use $checkout_ref to generate DB with extern SST file"
  260. write_external_sst $input_data_path $ext_test_dir/${checkout_ref}_pointless $ext_test_dir/$checkout_ref
  261. fi
  262. if member_of_array "$checkout_ref" "${ext_forward_refs[@]}"
  263. then
  264. echo "== Use $checkout_ref to ingest extern SST file and compare vs. $current_checkout_name"
  265. ingest_external_sst $ext_test_dir/${checkout_ref}_ingest $ext_test_dir/$checkout_ref
  266. compare_db $ext_test_dir/${checkout_ref}_ingest ${current_ext_test_dir}_ingest db_dump.txt 1 1
  267. rm -rf ${ext_test_dir:?}/${checkout_ref}_ingest
  268. echo "== Use $checkout_ref to ingest extern SST file from $current_checkout_name"
  269. ingest_external_sst $ext_test_dir/${checkout_ref}_ingest $current_ext_test_dir
  270. compare_db $ext_test_dir/${checkout_ref}_ingest ${current_ext_test_dir}_ingest db_dump.txt 1 1
  271. fi
  272. if member_of_array "$checkout_ref" "${db_forward_no_options_refs[@]}" ||
  273. member_of_array "$checkout_ref" "${db_forward_with_options_refs[@]}"
  274. then
  275. echo "== Use $checkout_ref to open DB generated using $current_checkout_name..."
  276. compare_db $db_test_dir/$checkout_ref $current_db_test_dir forward_${checkout_ref}_dump.txt 0
  277. fi
  278. if member_of_array "$checkout_ref" "${db_forward_with_options_refs[@]}"
  279. then
  280. echo "== Use $checkout_ref to open DB generated using $current_checkout_name with its options..."
  281. compare_db $db_test_dir/$checkout_ref $current_db_test_dir forward_${checkout_ref}_dump.txt 1 1
  282. fi
  283. if member_of_array "$checkout_ref" "${bak_backward_only_refs[@]}" ||
  284. member_of_array "$checkout_ref" "${bak_forward_refs[@]}"
  285. then
  286. echo "== Use $checkout_ref to backup DB"
  287. backup_db $db_test_dir/$checkout_ref $bak_test_dir/$checkout_ref
  288. fi
  289. if member_of_array "$checkout_ref" "${bak_forward_refs[@]}"
  290. then
  291. echo "== Use $checkout_ref to restore DB from $current_checkout_name"
  292. rm -rf ${db_test_dir:?}/$checkout_ref
  293. restore_db $current_bak_test_dir $db_test_dir/$checkout_ref
  294. compare_db $db_test_dir/$checkout_ref $current_db_test_dir forward_${checkout_ref}_dump.txt 0
  295. fi
  296. done
  297. echo "== Building $current_checkout_name debug (again, final)"
  298. git reset --hard $current_checkout_hash
  299. force_no_fbcode
  300. make clean
  301. DISABLE_WARNING_AS_ERROR=1 make ldb -j32
  302. for checkout_ref in "${checkout_refs[@]}"
  303. do
  304. # We currently assume DB backward compatibility for every branch listed
  305. echo "== Use $current_checkout_name to open DB generated using $checkout_ref..."
  306. compare_db $db_test_dir/$checkout_ref $current_db_test_dir db_dump.txt 1 0
  307. if member_of_array "$checkout_ref" "${ext_backward_only_refs[@]}" ||
  308. member_of_array "$checkout_ref" "${ext_forward_refs[@]}"
  309. then
  310. rm -rf ${ext_test_dir:?}/${checkout_ref}_ingest
  311. echo "== Use $current_checkout_name to ingest extern SST file from $checkout_ref"
  312. ingest_external_sst $ext_test_dir/${checkout_ref}_ingest $current_ext_test_dir
  313. compare_db $ext_test_dir/${checkout_ref}_ingest ${current_ext_test_dir}_ingest db_dump.txt 1 1
  314. fi
  315. if member_of_array "$checkout_ref" "${bak_backward_only_refs[@]}" ||
  316. member_of_array "$checkout_ref" "${bak_forward_refs[@]}"
  317. then
  318. echo "== Use $current_checkout_name to restore DB from $checkout_ref"
  319. rm -rf ${db_test_dir:?}/$checkout_ref
  320. restore_db $bak_test_dir/$checkout_ref $db_test_dir/$checkout_ref
  321. compare_db $db_test_dir/$checkout_ref $current_db_test_dir db_dump.txt 1 0
  322. fi
  323. done
  324. echo ==== Compatibility Test PASSED ====