1 /* 2 * Copyright (C) 2009 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 package android.os.cts; 17 18 import android.os.Environment; 19 import android.system.Os; 20 import android.system.StructStatVfs; 21 22 import junit.framework.TestCase; 23 24 import java.io.BufferedReader; 25 import java.io.File; 26 import java.io.FileReader; 27 28 public class EnvironmentTest extends TestCase { 29 public void testEnvironment() { 30 new Environment(); 31 assertNotNull(Environment.getExternalStorageState()); 32 assertTrue(Environment.getExternalStorageDirectory().isDirectory()); 33 assertTrue(Environment.getRootDirectory().isDirectory()); 34 assertTrue(Environment.getDownloadCacheDirectory().isDirectory()); 35 assertTrue(Environment.getDataDirectory().isDirectory()); 36 } 37 38 /** 39 * TMPDIR being set prevents apps from asking to have temporary files 40 * placed in their own storage, instead forcing their location to 41 * something OS-defined. If TMPDIR points to a global shared directory, 42 * this could compromise the security of the files. 43 */ 44 public void testNoTmpDir() { 45 assertNull("environment variable TMPDIR should not be set", 46 System.getenv("TMPDIR")); 47 } 48 49 /** 50 * Verify that all writable block filesystems are mounted "noatime" to avoid 51 * unnecessary flash churn. 52 */ 53 public void testNoAtime() throws Exception { 54 try (BufferedReader br = new BufferedReader(new FileReader("/proc/mounts"))) { 55 String line; 56 while ((line = br.readLine()) != null) { 57 final String[] fields = line.split(" "); 58 final String source = fields[0]; 59 final String options = fields[3]; 60 61 if (source.startsWith("/dev/block/") && !options.startsWith("ro,") 62 && !options.contains("noatime")) { 63 fail("Found device mounted at " + source + " without 'noatime' option, " 64 + "which can cause unnecessary flash churn; please update your fstab."); 65 } 66 } 67 } 68 } 69 70 /** 71 * Verify that all writable block filesystems are mounted with "resgid" to 72 * mitigate disk-full trouble. 73 */ 74 public void testSaneInodes() throws Exception { 75 final File file = Environment.getDataDirectory(); 76 final StructStatVfs stat = Os.statvfs(file.getAbsolutePath()); 77 78 // By default ext4 creates one inode per 16KiB; we're okay with a much 79 // wider range, but we want to make sure the device isn't going totally 80 // crazy; too few inodes can result in system instability, and too many 81 // inodes can result in wasted space. 82 final long maxsize = stat.f_blocks * stat.f_frsize; 83 final long maxInodes = maxsize / 4096; 84 final long minsize = stat.f_bavail * stat.f_frsize; 85 final long minInodes = minsize / 32768; 86 87 if (stat.f_ffree >= minInodes && stat.f_ffree <= maxInodes) { 88 // Sweet, sounds great! 89 } else { 90 fail("Number of inodes " + stat.f_ffree + " not within sane range for partition of " 91 + minsize + "," + maxsize + " bytes; expected [" + minInodes + "," + maxInodes + "]"); 92 } 93 } 94 } 95