#!/bin/bash

# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This script can be used by waterfall sheriffs to fetch the status
# of Valgrind bots on the memory waterfall and test if their local
# suppressions match the reports on the waterfall.

set -e

THISDIR=$(dirname "${0}")
LOGS_DIR=$THISDIR/waterfall.tmp
WATERFALL_PAGE="http://build.chromium.org/p/chromium.memory/builders"
WATERFALL_FYI_PAGE="http://build.chromium.org/p/chromium.memory.fyi/builders"

download() {
  # Download a file.
  # $1 = URL to download
  # $2 = Path to the output file
  # {{{1
  if [ "$(which curl)" != "" ]
  then
    if ! curl -s -o "$2" "$1"
    then
      echo
      echo "Failed to download '$1'... aborting"
      exit 1
    fi
  elif [ "$(which wget)" != "" ]
  then
    if ! wget "$1" -O "$2" -q
    then
      echo
      echo "Failed to download '$1'... aborting"
      exit 1
    fi
  else
    echo "Need either curl or wget to download stuff... aborting"
    exit 1
  fi
  # }}}
}

fetch_logs() {
  # Fetch Valgrind logs from the waterfall {{{1

  # TODO(timurrrr,maruel): use JSON, see
  # http://build.chromium.org/p/chromium.memory/json/help

  rm -rf "$LOGS_DIR" # Delete old logs
  mkdir "$LOGS_DIR"

  echo "Fetching the list of builders..."
  download $1 "$LOGS_DIR/builders"
  SLAVES=$(grep "<a href=\"builders\/" "$LOGS_DIR/builders" | \
           grep 'td class="box"' | \
           sed "s/.*<a href=\"builders\///" | sed "s/\".*//" | \
           sort | uniq)

  for S in $SLAVES
  do
    SLAVE_URL=$1/$S
    SLAVE_NAME=$(echo $S | sed -e "s/%20/ /g" -e "s/%28/(/g" -e "s/%29/)/g")
    echo -n "Fetching builds by slave '${SLAVE_NAME}'"
    download $SLAVE_URL?numbuilds=${NUMBUILDS} "$LOGS_DIR/slave_${S}"

    # We speed up the 'fetch' step by skipping the builds/tests which succeeded.
    # TODO(timurrrr): OTOH, we won't be able to check
    # if some suppression is not used anymore.
    #
    # The awk script here joins the lines ending with </td> to make it possible
    # to find the failed builds.
    LIST_OF_BUILDS=$(cat "$LOGS_DIR/slave_$S" | \
                     awk 'BEGIN { buf = "" }
                          {
                            if ($0 ~ /<\/td>/) { buf = (buf $0); }
                            else {
                              if (buf) { print buf; buf="" }
                              print $0
                            }
                          }
                          END {if (buf) print buf}' | \
                     grep "success\|failure" | \
                     head -n $NUMBUILDS | \
                     grep "failure" | \
                     grep -v "failed compile" | \
                     sed "s/.*\/builds\///" | sed "s/\".*//")

    for BUILD in $LIST_OF_BUILDS
    do
      # We'll fetch a few tiny URLs now, let's use a temp file.
      TMPFILE=$(mktemp -t memory_waterfall.XXXXXX)
      download $SLAVE_URL/builds/$BUILD "$TMPFILE"

      REPORT_FILE="$LOGS_DIR/report_${S}_${BUILD}"
      rm -f $REPORT_FILE 2>/dev/null || true  # make sure it doesn't exist

      REPORT_URLS=$(grep -o "[0-9]\+/steps/memory.*/logs/[0-9A-F]\{16\}" \
                    "$TMPFILE" \
                    || true)  # `true` is to succeed on empty output
      FAILED_TESTS=$(grep -o "[0-9]\+/steps/memory.*/logs/[A-Za-z0-9_.]\+" \
                     "$TMPFILE" | grep -v "[0-9A-F]\{16\}" \
                     | grep -v "stdio" || true)

      for REPORT in $REPORT_URLS
      do
        download "$SLAVE_URL/builds/$REPORT/text" "$TMPFILE"
        echo "" >> "$TMPFILE"  # Add a newline at the end
        cat "$TMPFILE" | tr -d '\r' >> "$REPORT_FILE"
      done

      for FAILURE in $FAILED_TESTS
      do
        echo -n "FAILED:" >> "$REPORT_FILE"
        echo "$FAILURE" | sed -e "s/.*\/logs\///" -e "s/\/.*//" \
          >> "$REPORT_FILE"
      done

      rm "$TMPFILE"
      echo $SLAVE_URL/builds/$BUILD >> "$REPORT_FILE"
    done
    echo " DONE"
  done
  # }}}
}

match_suppressions() {
  PYTHONPATH=$THISDIR/../python/google \
             python "$THISDIR/test_suppressions.py" $@ "$LOGS_DIR/report_"*
}

match_gtest_excludes() {
  for PLATFORM in "Linux" "Chromium%20Mac" "Chromium%20OS"
  do
    echo
    echo "Test failures on ${PLATFORM}:" | sed "s/%20/ /"
    grep -h -o "^FAILED:.*" -R "$LOGS_DIR"/*${PLATFORM}* | \
         grep -v "FAILS\|FLAKY" | sort | uniq | \
         sed -e "s/^FAILED://" -e "s/^/  /"
    # Don't put any operators between "grep | sed" and "RESULT=$PIPESTATUS"
    RESULT=$PIPESTATUS

    if [ "$RESULT" == 1 ]
    then
      echo "  None!"
    else
      echo
      echo "  Note: we don't check for failures already excluded locally yet"
      echo "  TODO(timurrrr): don't list tests we've already excluded locally"
    fi
  done
  echo
  echo "Note: we don't print FAILS/FLAKY tests and 1200s-timeout failures"
}

usage() {
  cat <<EOF
usage: $0 fetch|match options

This script can be used by waterfall sheriffs to fetch the status
of Valgrind bots on the memory waterfall and test if their local
suppressions match the reports on the waterfall.

OPTIONS:
   -h      Show this message
   -n N    Fetch N builds from each slave.

COMMANDS:
  fetch    Fetch Valgrind logs from the memory waterfall
  match    Test the local suppression files against the downloaded logs

EOF
}

NUMBUILDS=3

CMD=$1
if [ $# != 0 ]; then
  shift
fi

# Arguments for "match" are handled in match_suppressions
if [ "$CMD" != "match" ]; then
  while getopts “hn:” OPTION
  do
    case $OPTION in
      h)
        usage
        exit
        ;;
      n)
        NUMBUILDS=$OPTARG
        ;;
      ?)
        usage
        exit
        ;;
    esac
  done
  shift $((OPTIND-1))
  if [ $# != 0 ]; then
    usage
    exit 1
  fi
fi

if [ "$CMD" = "fetch" ]; then
  echo "Fetching $NUMBUILDS builds"
  fetch_logs $WATERFALL_PAGE
  fetch_logs $WATERFALL_FYI_PAGE
elif [ "$CMD" = "match" ]; then
  match_suppressions $@
  match_gtest_excludes
elif [ "$CMD" = "blame" ]; then
  echo The blame command died of bitrot. If you need it, please reimplement it.
  echo Reimplementation is blocked on http://crbug.com/82688
else
  usage
  exit 1
fi
