1 /* 2 * Copyright (C) 2012 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.filesystem.cts; 18 19 import static androidx.test.InstrumentationRegistry.getContext; 20 import static androidx.test.InstrumentationRegistry.getInstrumentation; 21 22 import android.util.Log; 23 24 import androidx.test.runner.AndroidJUnit4; 25 26 import com.android.compatibility.common.util.DeviceReportLog; 27 import com.android.compatibility.common.util.SystemUtil; 28 29 import org.junit.After; 30 import org.junit.Before; 31 import org.junit.Test; 32 import org.junit.runner.RunWith; 33 34 import java.util.concurrent.atomic.AtomicBoolean; 35 import java.util.concurrent.atomic.AtomicInteger; 36 37 @RunWith(AndroidJUnit4.class) 38 public class AlmostFullTest { 39 private static final String DIR_INITIAL_FILL = "INITIAL_FILL"; 40 private static final String DIR_SEQ_UPDATE = "SEQ_UPDATE"; 41 private static final String DIR_RANDOM_WR = "RANDOM_WR"; 42 private static final String DIR_RANDOM_RD = "RANDOM_RD"; 43 private static final String TAG = "AlmostFullTest"; 44 private static final String REPORT_LOG_NAME = "CtsFileSystemTestCases"; 45 46 private static final long FREE_SPACE_FINAL = 1000L * 1024 * 1024L; 47 48 // test runner creates multiple instances at the begging. 49 // use that to fill disk only once. 50 // set as final to initialize it only once 51 private static final AtomicInteger mRefCounter = new AtomicInteger(0); 52 private static final AtomicBoolean mDiskFilled = new AtomicBoolean(false); 53 AlmostFullTest()54 public AlmostFullTest() { 55 int currentCounter = mRefCounter.incrementAndGet(); 56 Log.i(TAG, "++currentCounter: " + currentCounter); 57 } 58 59 @Before setUp()60 public void setUp() throws Exception { 61 if (mDiskFilled.compareAndSet(false, true)) { 62 Log.i(TAG, "Filling disk"); 63 // initial fill done in two stage as disk can be filled by other 64 // components 65 long freeDisk = SystemUtil.getFreeDiskSize(getContext()); 66 long diskToFill = freeDisk - FREE_SPACE_FINAL; 67 if (diskToFill >= 0) { 68 Log.i(TAG, "free disk " + freeDisk + ", to fill " + diskToFill); 69 } else { 70 Log.i(TAG, "free disk " + freeDisk + " too small, needs " + FREE_SPACE_FINAL); 71 return; 72 } 73 // Ensure MAX_SIZE_TO_FILL is an integral multiple of FileUtil.BUFFER_SIZE to avoid 74 // rounding errors caused by FileUtil.createNewFilledFile. See b/63535343. 75 final long MAX_FILE_SIZE_TO_FILL = FileUtil.BUFFER_SIZE * 100L; 76 long filled = 0; 77 while (filled < diskToFill) { 78 long toFill = diskToFill - filled; 79 if (toFill > MAX_FILE_SIZE_TO_FILL) { 80 toFill = MAX_FILE_SIZE_TO_FILL; 81 } 82 Log.i(TAG, "Generating file " + toFill); 83 FileUtil.createNewFilledFile(getContext(), 84 DIR_INITIAL_FILL, toFill); 85 filled += toFill; 86 } 87 } 88 Log.i(TAG, "free disk " + SystemUtil.getFreeDiskSize(getContext())); 89 } 90 91 @After tearDown()92 public void tearDown() throws Exception { 93 Log.i(TAG, "tearDown free disk " + SystemUtil.getFreeDiskSize(getContext())); 94 int currentCounter = mRefCounter.decrementAndGet(); 95 Log.i(TAG, "--currentCounter: " + currentCounter); 96 if (currentCounter == 0) { 97 FileUtil.removeFileOrDir(getContext(), DIR_INITIAL_FILL); 98 } 99 FileUtil.removeFileOrDir(getContext(), DIR_SEQ_UPDATE); 100 FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_WR); 101 FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_RD); 102 Log.i(TAG, "tearDown free disk " + SystemUtil.getFreeDiskSize(getContext())); 103 } 104 105 @Test testSequentialUpdate()106 public void testSequentialUpdate() throws Exception { 107 // now about freeSpaceToLeave should be left 108 // and try updating exceeding the free space size 109 final long FILE_SIZE = 400L * 1024L * 1024L; 110 long freeDisk = SystemUtil.getFreeDiskSize(getContext()); 111 Log.i(TAG, "Now free space is " + freeDisk); 112 if (freeDisk < FILE_SIZE) { 113 Log.w(TAG, "too little space: " + freeDisk); 114 return; 115 } 116 final int BUFFER_SIZE = 10 * 1024 * 1024; 117 final int NUMBER_REPETITION = 10; 118 String streamName = "test_sequential_update"; 119 FileUtil.doSequentialUpdateTest(getContext(), DIR_SEQ_UPDATE, FILE_SIZE, BUFFER_SIZE, 120 NUMBER_REPETITION, REPORT_LOG_NAME, streamName); 121 } 122 123 // TODO: file size too small and caching will give wrong better result. 124 // needs to flush cache by reading big files per each read. 125 @Test testRandomRead()126 public void testRandomRead() throws Exception { 127 final int BUFFER_SIZE = 4 * 1024; 128 final long fileSize = 400L * 1024L * 1024L; 129 long freeDisk = SystemUtil.getFreeDiskSize(getContext()); 130 if (freeDisk < fileSize) { 131 Log.w(TAG, "too little space: " + freeDisk); 132 return; 133 } 134 String streamName = "test_random_read"; 135 DeviceReportLog report = new DeviceReportLog(REPORT_LOG_NAME, streamName); 136 FileUtil.doRandomReadTest(getContext(), DIR_RANDOM_RD, report, fileSize, BUFFER_SIZE); 137 report.submit(getInstrumentation()); 138 } 139 140 @Test testRandomUpdate()141 public void testRandomUpdate() throws Exception { 142 final int BUFFER_SIZE = 4 * 1024; 143 final long fileSize = 256L * 1024L * 1024L; 144 long freeDisk = SystemUtil.getFreeDiskSize(getContext()); 145 if (freeDisk < fileSize) { 146 Log.w(TAG, "too little space: " + freeDisk); 147 return; 148 } 149 String streamName = "test_random_update"; 150 DeviceReportLog report = new DeviceReportLog(REPORT_LOG_NAME, streamName); 151 FileUtil.doRandomWriteTest(getContext(), DIR_RANDOM_WR, report, fileSize, BUFFER_SIZE); 152 report.submit(getInstrumentation()); 153 } 154 } 155