Home | History | Annotate | Download | only in storageapp
      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 com.android.cts.storageapp;
     18 
     19 import android.content.Context;
     20 import android.system.Os;
     21 import android.system.OsConstants;
     22 import android.system.StructUtsname;
     23 import android.util.Log;
     24 
     25 import junit.framework.AssertionFailedError;
     26 
     27 import java.io.BufferedReader;
     28 import java.io.ByteArrayOutputStream;
     29 import java.io.File;
     30 import java.io.FileDescriptor;
     31 import java.io.FileOutputStream;
     32 import java.io.FileReader;
     33 import java.io.IOException;
     34 import java.io.InputStream;
     35 import java.io.OutputStream;
     36 import java.util.Arrays;
     37 import java.util.regex.Matcher;
     38 import java.util.regex.Pattern;
     39 
     40 public class Utils {
     41     public static final String TAG = "StorageApp";
     42 
     43     public static final String PKG_A = "com.android.cts.storageapp_a";
     44     public static final String PKG_B = "com.android.cts.storageapp_b";
     45 
     46     // You will pry my kibibytes from my cold dead hands! But to make test
     47     // results easier to debug, we'll use kilobytes...
     48     public static final long KB_IN_BYTES = 1000;
     49     public static final long MB_IN_BYTES = KB_IN_BYTES * 1000;
     50     public static final long GB_IN_BYTES = MB_IN_BYTES * 1000;
     51 
     52     public static final long DATA_INT = (2 + 3 + 5 + 13 + 17 + 19 + 23) * MB_IN_BYTES;
     53     public static final long DATA_EXT = (7 + 11) * MB_IN_BYTES;
     54     public static final long DATA_ALL = DATA_INT + DATA_EXT; // 100MB
     55 
     56     public static final long CACHE_INT = (3 + 5 + 17 + 19 + 23) * MB_IN_BYTES;
     57     public static final long CACHE_EXT = (11) * MB_IN_BYTES;
     58     public static final long CACHE_ALL = CACHE_INT + CACHE_EXT; // 78MB
     59 
     60     public static final long CODE_ALL = 29 * MB_IN_BYTES;
     61 
     62     public static void useSpace(Context c) throws Exception {
     63         // We use prime numbers for all values so that we can easily identify
     64         // which file(s) are missing from broken test results.
     65         useWrite(makeUniqueFile(c.getFilesDir()), 2 * MB_IN_BYTES);
     66         useWrite(makeUniqueFile(c.getCodeCacheDir()), 3 * MB_IN_BYTES);
     67         useWrite(makeUniqueFile(c.getCacheDir()), 5 * MB_IN_BYTES);
     68         useWrite(makeUniqueFile(c.getExternalFilesDir("meow")), 7 * MB_IN_BYTES);
     69         useWrite(makeUniqueFile(c.getExternalCacheDir()), 11 * MB_IN_BYTES);
     70 
     71         useFallocate(makeUniqueFile(c.getFilesDir()), 13 * MB_IN_BYTES);
     72         useFallocate(makeUniqueFile(c.getCodeCacheDir()), 17 * MB_IN_BYTES);
     73         useFallocate(makeUniqueFile(c.getCacheDir()), 19 * MB_IN_BYTES);
     74         final File subdir = makeUniqueFile(c.getCacheDir());
     75         Os.mkdir(subdir.getAbsolutePath(), 0700);
     76         useFallocate(makeUniqueFile(subdir), 23 * MB_IN_BYTES);
     77 
     78         useWrite(makeUniqueFile(c.getObbDir()), 29 * MB_IN_BYTES);
     79     }
     80 
     81     public static void assertAtLeast(long expected, long actual) {
     82         if (actual < expected) {
     83             throw new AssertionFailedError("Expected at least " + expected + " but was " + actual
     84                     + " [" + android.os.Process.myUserHandle() + "]");
     85         }
     86     }
     87 
     88     public static void assertMostlyEquals(long expected, long actual) {
     89         assertMostlyEquals(expected, actual, 500 * KB_IN_BYTES);
     90     }
     91 
     92     public static void assertMostlyEquals(long expected, long actual, long delta) {
     93         if (Math.abs(expected - actual) > delta) {
     94             throw new AssertionFailedError("Expected roughly " + expected + " but was " + actual
     95                     + " [" + android.os.Process.myUserHandle() + "]");
     96         }
     97     }
     98 
     99     public static File makeUniqueFile(File dir) {
    100         return new File(dir, Long.toString(System.nanoTime()));
    101     }
    102 
    103     public static File useWrite(File file, long size) throws Exception {
    104         try (FileOutputStream os = new FileOutputStream(file)) {
    105             final byte[] buf = new byte[1024];
    106             while (size > 0) {
    107                 os.write(buf, 0, (int) Math.min(buf.length, size));
    108                 size -= buf.length;
    109             }
    110         }
    111         return file;
    112     }
    113 
    114     public static File useFallocate(File file, long length, long time) throws Exception {
    115         final File res = useFallocate(file, length);
    116         file.setLastModified(time);
    117         return res;
    118     }
    119 
    120     public static File useFallocate(File file, long length) throws Exception {
    121         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
    122                 OsConstants.O_CREAT | OsConstants.O_RDWR | OsConstants.O_TRUNC, 0700);
    123         try {
    124             Os.posix_fallocate(fd, 0, length);
    125         } finally {
    126             Os.close(fd);
    127         }
    128         return file;
    129     }
    130 
    131     public static long getSizeManual(File dir) throws Exception {
    132         return getSizeManual(dir, false);
    133     }
    134 
    135     public static long getSizeManual(File dir, boolean excludeObb) throws Exception {
    136         long size = getAllocatedSize(dir);
    137         for (File f : dir.listFiles()) {
    138             if (f.isDirectory()) {
    139                 if (excludeObb && f.getName().equalsIgnoreCase("obb")
    140                         && f.getParentFile().getName().equalsIgnoreCase("Android")) {
    141                     Log.d(TAG, "Ignoring OBB directory " + f);
    142                 } else {
    143                     size += getSizeManual(f, excludeObb);
    144                 }
    145             } else {
    146                 size += getAllocatedSize(f);
    147             }
    148         }
    149         return size;
    150     }
    151 
    152     private static long getAllocatedSize(File f) throws Exception {
    153         return Os.lstat(f.getAbsolutePath()).st_blocks * 512;
    154     }
    155 
    156     public static boolean deleteContents(File dir) {
    157         File[] files = dir.listFiles();
    158         boolean success = true;
    159         if (files != null) {
    160             for (File file : files) {
    161                 if (file.isDirectory()) {
    162                     success &= deleteContents(file);
    163                 }
    164                 if (!file.delete()) {
    165                     success = false;
    166                 }
    167             }
    168         }
    169         return success;
    170     }
    171 
    172     public static void logCommand(String... cmd) throws Exception {
    173         final Process proc = new ProcessBuilder(cmd).redirectErrorStream(true).start();
    174 
    175         final ByteArrayOutputStream buf = new ByteArrayOutputStream();
    176         copy(proc.getInputStream(), buf);
    177         final int res = proc.waitFor();
    178 
    179         Log.d(TAG, Arrays.toString(cmd) + " result " + res + ":");
    180         Log.d(TAG, buf.toString());
    181     }
    182 
    183     /** Shamelessly lifted from libcore.io.Streams */
    184     public static int copy(InputStream in, OutputStream out) throws IOException {
    185         int total = 0;
    186         byte[] buffer = new byte[8192];
    187         int c;
    188         while ((c = in.read(buffer)) != -1) {
    189             total += c;
    190             out.write(buffer, 0, c);
    191         }
    192         return total;
    193     }
    194 }
    195