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.backup.cts;
     18 
     19 import android.app.Instrumentation;
     20 import android.content.pm.PackageManager;
     21 import android.os.ParcelFileDescriptor;
     22 import android.test.InstrumentationTestCase;
     23 
     24 import com.android.compatibility.common.util.LogcatInspector;
     25 
     26 import java.io.BufferedReader;
     27 import java.io.FileInputStream;
     28 import java.io.IOException;
     29 import java.io.InputStream;
     30 import java.io.InputStreamReader;
     31 import java.nio.charset.StandardCharsets;
     32 
     33 /**
     34  * Base class for backup instrumentation tests.
     35  *
     36  * Ensures that backup is enabled and local transport selected, and provides some utility methods.
     37  */
     38 public class BaseBackupCtsTest extends InstrumentationTestCase {
     39     private static final String APP_LOG_TAG = "BackupCTSApp";
     40 
     41     private static final String LOCAL_TRANSPORT =
     42             "android/com.android.internal.backup.LocalTransport";
     43 
     44     private boolean isBackupSupported;
     45     private LogcatInspector mLogcatInspector =
     46             new LogcatInspector() {
     47                 @Override
     48                 protected InputStream executeShellCommand(String command) throws IOException {
     49                     return executeStreamedShellCommand(getInstrumentation(), command);
     50                 }
     51             };
     52 
     53     @Override
     54     protected void setUp() throws Exception {
     55         super.setUp();
     56         PackageManager packageManager = getInstrumentation().getContext().getPackageManager();
     57         isBackupSupported = packageManager != null
     58                 && packageManager.hasSystemFeature(PackageManager.FEATURE_BACKUP);
     59 
     60         if (isBackupSupported) {
     61             assertTrue("Backup not enabled", isBackupEnabled());
     62             assertTrue("LocalTransport not selected", isLocalTransportSelected());
     63             exec("setprop log.tag." + APP_LOG_TAG +" VERBOSE");
     64         }
     65     }
     66 
     67     public boolean isBackupSupported() {
     68         return isBackupSupported;
     69     }
     70 
     71     private boolean isBackupEnabled() throws Exception {
     72         String output = exec("bmgr enabled");
     73         return output.contains("currently enabled");
     74     }
     75 
     76     private boolean isLocalTransportSelected() throws Exception {
     77         String output = exec("bmgr list transports");
     78         return output.contains("* " + LOCAL_TRANSPORT);
     79     }
     80 
     81     /** See {@link LogcatInspector#mark(String)}. */
     82     protected String markLogcat() throws Exception {
     83         return mLogcatInspector.mark(APP_LOG_TAG);
     84     }
     85 
     86     /** See {@link LogcatInspector#assertLogcatContainsInOrder(String, int, String...)}. */
     87     protected void waitForLogcat(int maxTimeoutInSeconds, String... logcatStrings)
     88             throws Exception {
     89         mLogcatInspector.assertLogcatContainsInOrder(
     90                 APP_LOG_TAG + ":* *:S", maxTimeoutInSeconds, logcatStrings);
     91     }
     92 
     93     protected void createTestFileOfSize(String packageName, int size) throws Exception {
     94         exec("am start -a android.intent.action.MAIN " +
     95             "-c android.intent.category.LAUNCHER " +
     96             "-n " + packageName + "/android.backup.app.MainActivity " +
     97             "-e file_size " + size);
     98         waitForLogcat(30, "File created!");
     99     }
    100 
    101     protected String exec(String command) throws Exception {
    102         try (InputStream in = executeStreamedShellCommand(getInstrumentation(), command)) {
    103             BufferedReader br = new BufferedReader(
    104                     new InputStreamReader(in, StandardCharsets.UTF_8));
    105             String str;
    106             StringBuilder out = new StringBuilder();
    107             while ((str = br.readLine()) != null) {
    108                 out.append(str);
    109             }
    110             return out.toString();
    111         }
    112     }
    113 
    114     private static FileInputStream executeStreamedShellCommand(
    115             Instrumentation instrumentation, String command) throws IOException {
    116         final ParcelFileDescriptor pfd =
    117                 instrumentation.getUiAutomation().executeShellCommand(command);
    118         return new ParcelFileDescriptor.AutoCloseInputStream(pfd);
    119     }
    120 
    121     private static void drainAndClose(BufferedReader reader) {
    122         try {
    123             while (reader.read() >= 0) {
    124                 // do nothing.
    125             }
    126         } catch (IOException ignored) {
    127         }
    128         closeQuietly(reader);
    129     }
    130 
    131     private static void closeQuietly(AutoCloseable closeable) {
    132         if (closeable != null) {
    133             try {
    134                 closeable.close();
    135             } catch (RuntimeException rethrown) {
    136                 throw rethrown;
    137             } catch (Exception ignored) {
    138             }
    139         }
    140     }
    141 }
    142