Files
Kordant/android/firebase-test-lab/download_results.sh

226 lines
7.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# =============================================================================
# Download Firebase Test Lab Results
# =============================================================================
# Downloads and organizes test results from Firebase Test Lab, including
# screenshots, videos, performance metrics, and test reports.
#
# Usage:
# ./download_results.sh [options]
#
# Options:
# --project-id Firebase project ID (default: kordant-android)
# --matrix-id Specific matrix ID to download (optional, downloads latest)
# --output-dir Output directory (default: ./test_results)
# --download-all Download all artifacts including screenshots and videos
# --help Show this help message
# =============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Default values
PROJECT_ID="${FIREBASE_PROJECT_ID:-kordant-android}"
MATRIX_ID=""
OUTPUT_DIR="${SCRIPT_DIR}/test_results"
DOWNLOAD_ALL=false
# ============================================================
# Parse arguments
# ============================================================
while [[ $# -gt 0 ]]; do
case "$1" in
--project-id)
PROJECT_ID="$2"
shift 2
;;
--matrix-id)
MATRIX_ID="$2"
shift 2
;;
--output-dir)
OUTPUT_DIR="$2"
shift 2
;;
--download-all)
DOWNLOAD_ALL=true
shift
;;
--help)
grep "^#" "$0" | grep -v "^#!/" | sed 's/^# //'
exit 0
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 --help"
exit 1
;;
esac
done
# ============================================================
# Validate gcloud
# ============================================================
if ! command -v gcloud &> /dev/null; then
echo "Error: gcloud CLI is not installed."
exit 1
fi
# ============================================================
# Find the GCS bucket for test results
# ============================================================
echo "🔍 Finding Firebase Test Lab results bucket..."
echo "Project ID: $PROJECT_ID"
# Get the storage bucket name from the Firebase project
# Test Lab results are stored in gs://<project-id>-test-lab-<random-suffix>
RESULTS_BUCKET=$(gsutil ls 2>/dev/null | grep "${PROJECT_ID}-test-lab-" || echo "")
if [ -z "$RESULTS_BUCKET" ]; then
echo "No test lab bucket found via gsutil. Trying gcloud to list recent matrices..."
echo ""
fi
# ============================================================
# List recent test matrices
# ============================================================
echo "📋 Recent test matrices:"
echo ""
RECENT_MATRICES=$(gcloud firebase test android matrices list \
--project "$PROJECT_ID" \
--limit 10 \
--format="table(matrixId, state, gcsPath, createTime)" 2>/dev/null || echo "No matrices found.")
echo "$RECENT_MATRICES"
echo ""
# ============================================================
# If no matrix ID specified, get the latest
# ============================================================
if [ -z "$MATRIX_ID" ]; then
MATRIX_ID=$(gcloud firebase test android matrices list \
--project "$PROJECT_ID" \
--limit 1 \
--format="value(matrixId)" 2>/dev/null || echo "")
fi
if [ -z "$MATRIX_ID" ]; then
echo "No test matrices found. Run tests first."
exit 1
fi
echo "Selected matrix: $MATRIX_ID"
echo ""
# ============================================================
# Get GCS path for this matrix
# ============================================================
MATRIX_INFO=$(gcloud firebase test android matrices describe "$MATRIX_ID" \
--project "$PROJECT_ID" \
--format="json" 2>/dev/null || echo "{}")
GCS_PATH=$(echo "$MATRIX_INFO" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('gcsPath',''))" 2>/dev/null || echo "")
if [ -z "$GCS_PATH" ]; then
echo "Error: Could not determine GCS path for matrix $MATRIX_ID"
exit 1
fi
echo "GCS Path: $GCS_PATH"
echo ""
# ============================================================
# Create output directory
# ============================================================
mkdir -p "$OUTPUT_DIR"
# ============================================================
# Download results summary (JUnit XML)
# ============================================================
echo "📄 Downloading test results summary..."
echo " Output: $OUTPUT_DIR/"
# Download the test_results.xml (JUnit format)
gsutil -m cp "$GCS_PATH/**/test_result.xml" "$OUTPUT_DIR/" 2>/dev/null || true
gsutil -m cp "$GCS_PATH/**/test_results.xml" "$OUTPUT_DIR/" 2>/dev/null || true
# Download the performance metrics
gsutil -m cp "$GCS_PATH/**/performance_metrics.json" "$OUTPUT_DIR/performance/" 2>/dev/null || true
# Download the logcat output (if available)
gsutil -m cp "$GCS_PATH/**/logcat" "$OUTPUT_DIR/logcat/" 2>/dev/null || true
# ============================================================
# Download screenshots and videos (if --download-all)
# ============================================================
if [ "$DOWNLOAD_ALL" = true ]; then
echo ""
echo "🖼️ Downloading screenshots and videos..."
# Download all PNG screenshots
mkdir -p "$OUTPUT_DIR/screenshots"
gsutil -m cp "$GCS_PATH/**/*.png" "$OUTPUT_DIR/screenshots/" 2>/dev/null || true
SCREENSHOT_COUNT=$(find "$OUTPUT_DIR/screenshots" -name "*.png" 2>/dev/null | wc -l | tr -d ' ')
echo " Screenshots downloaded: $SCREENSHOT_COUNT"
# Download all MP4 videos
mkdir -p "$OUTPUT_DIR/videos"
gsutil -m cp "$GCS_PATH/**/*.mp4" "$OUTPUT_DIR/videos/" 2>/dev/null || true
VIDEO_COUNT=$(find "$OUTPUT_DIR/videos" -name "*.mp4" 2>/dev/null | wc -l | tr -d ' ')
echo " Videos downloaded: $VIDEO_COUNT"
# Download crawl maps (Robo test output)
mkdir -p "$OUTPUT_DIR/crawl_maps"
gsutil -m cp "$GCS_PATH/**/*.json" "$OUTPUT_DIR/crawl_maps/" 2>/dev/null || true
CRAWL_COUNT=$(find "$OUTPUT_DIR/crawl_maps" -name "*.json" 2>/dev/null | wc -l | tr -d ' ')
echo " Crawl maps downloaded: $CRAWL_COUNT"
fi
# ============================================================
# Generate report
# ============================================================
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📊 Results Summary"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Parse matrix info for summary
MATRIX_STATE=$(echo "$MATRIX_INFO" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('state','UNKNOWN'))" 2>/dev/null || echo "UNKNOWN")
echo "Matrix State: $MATRIX_STATE"
echo ""
# Show outcome summary per device
echo "$MATRIX_INFO" | python3 -c "
import sys, json
d = json.load(sys.stdin)
tests = d.get('testExecutions', [])
for t in tests:
device = t.get('device', {})
model = device.get('androidModelId', '?')
version = device.get('androidVersionId', '?')
state = t.get('state', '?')
outcome = t.get('outcome', {}).get('summary', '?')
print(f' {model} (API {version}): {state} - {outcome}')
" 2>/dev/null || echo " (Could not parse individual device results)"
echo ""
echo "Output directory: $OUTPUT_DIR"
echo ""
echo "View in Firebase Console:"
echo " https://console.firebase.google.com/project/$PROJECT_ID/testlab/histories"
# ============================================================
# Check for failures
# ============================================================
if echo "$MATRIX_STATE" | grep -qi "fail\|error\|invalid"; then
echo ""
echo "⚠️ Test matrix has failures! Review the results."
exit 1
else
echo ""
echo "✅ Test matrix completed successfully!"
exit 0
fi