#!/bin/bash
set -euo pipefail

# A harness that runs SQLite with the parquet extension in an environment where malloc randomly
# fails. "Success" is if the logs don't have any C++ exceptions that talk about std::bad_alloc
#
# The results can need a bit of interpretation; look at the log and see if it sniffs like
# the segfault came from Python or SQLite.

ensure_failmalloc() {
  if [ ! -d libfailmalloc ]; then
    git clone https://github.com/cldellow/libfailmalloc.git
  fi

  if [ ! -e libfailmalloc/.libs/libfailmalloc.so ]; then
    cd libfailmalloc
    ./configure
    make
  fi
}

run_under_low_memory() {
  start=$(date +%s%3N)
  set +e
  env LD_PRELOAD="$here"/libfailmalloc/.libs/libfailmalloc.so FAILMALLOC_PROBABILITY=0.00001 ./test-random >results.bad_alloc 2>&1
  rv=$?
  now=$(date +%s%3N)
  echo "Bailed after $((now-start)) ms"
  set -e
  if [ "$rv" -gt 127 ]; then
    cat results.bad_alloc
    echo "Segfaulted with exit code: $rv"
    exit 1
  fi
}

main() {
  here=$(dirname "${BASH_SOURCE[0]}")
  here=$(readlink -f "$here")
  cd "$here"

  ensure_failmalloc
  # Sometimes we'll exit due to a Python memory issue, so try a few times.
  for i in {0..100}; do
    run_under_low_memory
  done
}

main "$@"