1#!/bin/sh
2# Copyright (C) 2014 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16#
17# acov is a tool for gathering coverage information from a device and generating
18# a report from that information. To use:
19#
20# 1. sudo apt-get install lcov
21# 2. Build application/library with coverage information.
22#     * make NATIVE_COVERAGE=true NATIVE_COVERAGE_PATHS='*'
23# 3. Push the new binaries to the device with adb sync.
24# (Optional): Run `acov --clean-device`. This will reset coverage for everything
25#      on the device.
26# 4. Run tests.
27# (Optional): Run `acov --flush`. This will dump coverage from all processes
28#      running on the device.
29# 5. Run `acov`.
30#
31# acov will pull all coverage information from the device, push it to the right
32# directories, run lcov, and display the coverage report (currently by opening
33# it in your browser).
34#
35
36ANDROID_OUT=${OUT_DIR:-out}
37FLUSH_SLEEP=${FLUSH_SLEEP:-60}
38
39function clearGcdaFiles() {
40  if [ -d "$ANDROID_OUT" ]; then
41    find $ANDROID_OUT -name '*.gcda' -delete
42  fi
43}
44
45function clearGcnoFiles() {
46  if [ -d "$ANDROID_OUT" ]; then
47    find $ANDROID_OUT -name '*.gcno' -delete
48  fi
49}
50
51if [ "$1" = "--clean" ]; then
52  echo "Clearing gcda and gcno files from the local build."
53  clearGcdaFiles
54  clearGcnoFiles
55  exit 0
56fi
57
58if [ "$1" = "--prep" ]; then
59  echo "Clearing gcda files from the local build."
60  clearGcdaFiles
61  exit 0
62fi
63
64adb root
65
66if [ "$1" = "--clean-device" ]; then
67  echo "Resetting coverage on the device..."
68  adb shell kill -37 -1
69  echo "Waiting $FLUSH_SLEEP seconds for coverage to be written..."
70  sleep $FLUSH_SLEEP
71  adb shell rm -rf /data/misc/trace/*
72  exit 0
73fi
74
75if [ "$1" = "--flush" ]; then
76  shift
77  if [ -z $@ ]; then
78    echo "Flushing coverage for all processes on the device..."
79    adb shell kill -37 -1
80  else
81    echo "Flushing coverage for [$@] on the device..."
82    adb shell kill -37 $(adb shell pidof $@)
83  fi
84  echo "Waiting $FLUSH_SLEEP seconds for coverage to be written..."
85  sleep $FLUSH_SLEEP
86  exit 0
87fi
88
89which lcov >/dev/null 2>/dev/null
90if [ $? -ne 0 ]; then
91  echo 'lcov not found: running `sudo apt-get install lcov`'
92  sudo apt-get install lcov
93fi
94
95cd $ANDROID_BUILD_TOP
96DIR=$(mktemp -d covreport-XXXXXX)
97
98# Build a coverage report for each euid that has reported coverage.
99COVERAGE_REPORTS=
100for USER_ID in $(adb shell ls /data/misc/trace)
101do
102  FILE=cov-$USER_ID.info
103  adb shell tar -czf - -C /data/misc/trace/$USER_ID/proc/self/cwd $ANDROID_OUT | tar zxvf -
104
105  lcov -c -d $ANDROID_OUT -o $DIR/$FILE --gcov-tool=llvm-gcov $@
106  COVERAGE_REPORTS="-a $DIR/$FILE $COVERAGE_REPORTS"
107
108  clearGcdaFiles
109done
110
111FILE=merged.info
112lcov $COVERAGE_REPORTS -o $DIR/$FILE
113echo "Generating coverage report at $DIR"
114genhtml -q -o $DIR $DIR/$FILE
115xdg-open $DIR/index.html >/dev/null
116