1 /*
2  * Copyright (C) 2017 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 package android.contentcaptureservice.cts;
18 
19 import static android.contentcaptureservice.cts.Helper.MY_PACKAGE;
20 import static android.contentcaptureservice.cts.Helper.TAG;
21 
22 import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
23 
24 import android.util.Log;
25 
26 import androidx.annotation.NonNull;
27 
28 import com.android.compatibility.common.util.SafeCleanerRule;
29 
30 import org.junit.AssumptionViolatedException;
31 import org.junit.rules.TestRule;
32 import org.junit.runner.Description;
33 import org.junit.runners.model.Statement;
34 
35 /**
36  * Custom JUnit4 rule that improves ContentCapture-related logging by:
37  *
38  * <ol>
39  *   <li>Setting logging level to verbose before test start.
40  *   <li>Call {@code dumpsys} in case of failure.
41  * </ol>
42  */
43 public class ContentCaptureLoggingTestRule implements TestRule, SafeCleanerRule.Dumper {
44 
45     private boolean mDumped;
46 
47     @Override
apply(Statement base, Description description)48     public Statement apply(Statement base, Description description) {
49         return new Statement() {
50 
51             @Override
52             public void evaluate() throws Throwable {
53                 final String testName = description.getDisplayName();
54                 try {
55                     base.evaluate();
56                 } catch (Throwable t) {
57                     dump(testName, t);
58                     throw t;
59                 }
60             }
61         };
62     }
63 
64     @Override
65     public void dump(@NonNull String testName, @NonNull Throwable t) {
66         if (mDumped) {
67             Log.e(TAG, "dump(" + testName + "): already dumped");
68             return;
69         }
70         if ((t instanceof AssumptionViolatedException)) {
71             // This exception is used to indicate a test should be skipped and is
72             // ignored by JUnit runners - we don't need to dump it...
73             Log.w(TAG, "ignoring exception: " + t);
74             return;
75         }
76         // TODO(b/123540602, b/120784831): should dump to a file (and integrate with tradefed)
77         // instead of outputting to log directly...
78         Log.e(TAG, "Dumping after exception on " + testName, t);
79         final String serviceDump = runShellCommand("dumpsys content_capture");
80         Log.e(TAG, "content_capture dump: \n" + serviceDump);
81         final String activityDump = runShellCommand("dumpsys activity %s --contentcapture",
82                 MY_PACKAGE);
83         Log.e(TAG, "activity dump: \n" + activityDump);
84         mDumped = true;
85     }
86 }
87