Home | History | Annotate | Download | only in cts
      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.autofillservice.cts;
     18 
     19 import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
     20 
     21 import android.util.Log;
     22 
     23 import androidx.annotation.NonNull;
     24 
     25 import com.android.compatibility.common.util.SafeCleanerRule;
     26 
     27 import org.junit.AssumptionViolatedException;
     28 import org.junit.rules.TestRule;
     29 import org.junit.runner.Description;
     30 import org.junit.runners.model.Statement;
     31 
     32 /**
     33  * Custom JUnit4 rule that improves autofill-related logging by:
     34  *
     35  * <ol>
     36  *   <li>Setting logging level to verbose before test start.
     37  *   <li>Call {@code dumpsys autofill} in case of failure.
     38  * </ol>
     39  */
     40 public class AutofillLoggingTestRule implements TestRule, SafeCleanerRule.Dumper {
     41 
     42     private static final String TAG = "AutofillLoggingTestRule";
     43 
     44     private final String mTag;
     45     private boolean mDumped;
     46 
     47     public AutofillLoggingTestRule(String tag) {
     48         mTag = tag;
     49     }
     50 
     51     @Override
     52     public Statement apply(Statement base, Description description) {
     53         return new Statement() {
     54 
     55             @Override
     56             public void evaluate() throws Throwable {
     57                 final String testName = description.getDisplayName();
     58                 final String levelBefore = runShellCommand("cmd autofill get log_level");
     59                 if (!levelBefore.equals("verbose")) {
     60                     runShellCommand("cmd autofill set log_level verbose");
     61                 }
     62                 try {
     63                     base.evaluate();
     64                 } catch (Throwable t) {
     65                     dump(testName, t);
     66                     throw t;
     67                 } finally {
     68                     try {
     69                         if (!levelBefore.equals("verbose")) {
     70                             runShellCommand("cmd autofill set log_level %s", levelBefore);
     71                         }
     72                     } finally {
     73                         Log.v(TAG, "@After " + testName);
     74                     }
     75                 }
     76             }
     77         };
     78     }
     79 
     80     @Override
     81     public void dump(@NonNull String testName, @NonNull Throwable t) {
     82         if (mDumped) {
     83             Log.e(mTag, "dump(" + testName + "): already dumped");
     84             return;
     85         }
     86         if ((t instanceof AssumptionViolatedException)) {
     87             // This exception is used to indicate a test should be skipped and is
     88             // ignored by JUnit runners - we don't need to dump it...
     89             Log.w(TAG, "ignoring exception: " + t);
     90             return;
     91         }
     92         Log.e(mTag, "Dumping after exception on " + testName, t);
     93         Helper.dumpAutofillService(mTag);
     94         final String activityDump = runShellCommand("dumpsys activity top");
     95         Log.e(mTag, "top activity dump: \n" + activityDump);
     96         mDumped = true;
     97     }
     98 }
     99