Loading apct-tests/perftests/blobstore/Android.bp +14 −13 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ android_test { "apct-perftests-utils", "ub-uiautomator", "collector-device-lib-platform", "androidx.benchmark_benchmark-macro", ], platform_apis: true, test_suites: ["device-tests"], Loading apct-tests/perftests/blobstore/src/com/android/perftests/blob/BlobStorePerfTests.java +118 −1 Original line number Diff line number Diff line Loading @@ -15,15 +15,20 @@ */ package com.android.perftests.blob; import static com.android.utils.blob.Utils.acquireLease; import android.app.blob.BlobHandle; import android.app.blob.BlobStoreManager; import android.content.Context; import android.os.ParcelFileDescriptor; import android.perftests.utils.ManualBenchmarkState; import android.perftests.utils.PerfManualStatusReporter; import android.perftests.utils.TraceMarkParser; import android.perftests.utils.TraceMarkParser.TraceMarkSlice; import android.support.test.uiautomator.UiDevice; import android.util.DataUnit; import androidx.benchmark.macro.MacrobenchmarkScope; import androidx.test.filters.LargeTest; import androidx.test.platform.app.InstrumentationRegistry; Loading @@ -36,12 +41,16 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.Collection; import java.util.List; import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; Loading @@ -53,6 +62,8 @@ public class BlobStorePerfTests { // From f/b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java private static final String ATRACE_COMPUTE_DIGEST_PREFIX = "computeBlobDigest-"; public static final int BUFFER_SIZE_BYTES = 16 * 1024; private Context mContext; private BlobStoreManager mBlobStoreManager; private AtraceUtils mAtraceUtils; Loading Loading @@ -85,6 +96,8 @@ public class BlobStorePerfTests { @After public void tearDown() { mContext.getFilesDir().delete(); runShellCommand("cmd package clear " + mContext.getPackageName()); runShellCommand("cmd blob_store idle-maintenance"); } Loading @@ -109,6 +122,110 @@ public class BlobStorePerfTests { } } @Test public void testDirectReads() throws Exception { final File file = new File(mContext.getDataDir(), "test_read_file"); final long sizeBytes = DataUnit.MEBIBYTES.toBytes(fileSizeInMb); try (FileOutputStream outputStream = new FileOutputStream(file)) { writeData(outputStream, sizeBytes); } long durationNs = 0; while (mState.keepRunning(durationNs)) { dropCache(); try (FileInputStream inputStream = new FileInputStream(file)) { final long startTimeNs = System.nanoTime(); readData(inputStream, sizeBytes); durationNs = System.nanoTime() - startTimeNs; } } } @Test public void testBlobStoreReads() throws Exception { final FakeBlobData blobData = prepareDataBlob(fileSizeInMb); commitBlob(blobData); acquireLease(mContext, blobData.getBlobHandle(), "Test Desc"); final long sizeBytes = DataUnit.MEBIBYTES.toBytes(fileSizeInMb); long durationNs = 0; while (mState.keepRunning(durationNs)) { dropCache(); try (FileInputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream( mBlobStoreManager.openBlob(blobData.getBlobHandle()))) { final long startTimeNs = System.nanoTime(); readData(inputStream, sizeBytes); durationNs = System.nanoTime() - startTimeNs; } } deleteBlob(blobData.getBlobHandle()); } @Test public void testDirectWrites() throws Exception { final File file = new File(mContext.getDataDir(), "test_write_file"); final long sizeBytes = DataUnit.MEBIBYTES.toBytes(fileSizeInMb); long durationNs = 0; while (mState.keepRunning(durationNs)) { file.delete(); dropCache(); try (FileOutputStream outputStream = new FileOutputStream(file)) { final long startTimeNs = System.nanoTime(); writeData(outputStream, sizeBytes); durationNs = System.nanoTime() - startTimeNs; } } } @Test public void testBlobStoreWrites() throws Exception { final FakeBlobData blobData = prepareDataBlob(fileSizeInMb); final long sizeBytes = DataUnit.MEBIBYTES.toBytes(fileSizeInMb); long durationNs = 0; while (mState.keepRunning(durationNs)) { final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle()); try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) { dropCache(); try (FileOutputStream outputStream = new ParcelFileDescriptor .AutoCloseOutputStream(session.openWrite(0, sizeBytes))) { final long startTimeNs = System.nanoTime(); writeData(outputStream, sizeBytes); durationNs = System.nanoTime() - startTimeNs; } } mBlobStoreManager.abandonSession(sessionId); } } private void readData(FileInputStream inputStream, long sizeBytes) throws Exception { final byte[] buffer = new byte[BUFFER_SIZE_BYTES]; long bytesRead = 0; while (bytesRead < sizeBytes) { bytesRead += inputStream.read(buffer); } } private void writeData(FileOutputStream outputStream, long sizeBytes) throws Exception { final byte[] buffer = new byte[BUFFER_SIZE_BYTES]; long bytesWritten = 0; final Random random = new Random(0); while (bytesWritten < sizeBytes) { random.nextBytes(buffer); final int toWrite = (bytesWritten + buffer.length <= sizeBytes) ? buffer.length : (int) (sizeBytes - bytesWritten); outputStream.write(buffer, 0, toWrite); bytesWritten += toWrite; } } private void dropCache() { final MacrobenchmarkScope scope = new MacrobenchmarkScope(mContext.getPackageName(), false); scope.dropKernelPageCache(); } private void collectDigestDurationsFromTrace(TraceMarkParser parser, List<Long> durations) { mAtraceUtils.performDump(parser, (key, slices) -> { for (TraceMarkSlice slice : slices) { Loading @@ -119,7 +236,7 @@ public class BlobStorePerfTests { private FakeBlobData prepareDataBlob(int fileSizeInMb) throws Exception { final FakeBlobData blobData = new FakeBlobData.Builder(mContext) .setFileSize(fileSizeInMb * 1024 * 1024 /* bytes */) .setFileSize(DataUnit.MEBIBYTES.toBytes(fileSizeInMb)) .build(); blobData.prepare(); return blobData; Loading tests/BlobStoreTestUtils/src/com/android/utils/blob/FakeBlobData.java +2 −15 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.utils.blob; import static com.android.utils.blob.Utils.BUFFER_SIZE_BYTES; import static com.android.utils.blob.Utils.copy; import static com.android.utils.blob.Utils.writeRandomData; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -123,7 +124,7 @@ public class FakeBlobData { public void prepare() throws Exception { try (RandomAccessFile file = new RandomAccessFile(mFile, "rw")) { writeRandomData(file, mFileSize); writeRandomData(file, mRandom, mFileSize); } mFileDigest = FileUtils.digest(mFile, "SHA-256"); mExpiryTimeMs = System.currentTimeMillis() + mExpiryDurationMs; Loading Loading @@ -239,18 +240,4 @@ public class FakeBlobData { } return digest.digest(); } private void writeRandomData(RandomAccessFile file, long fileSize) throws Exception { long bytesWritten = 0; final byte[] buffer = new byte[BUFFER_SIZE_BYTES]; while (bytesWritten < fileSize) { mRandom.nextBytes(buffer); final int toWrite = (bytesWritten + buffer.length <= fileSize) ? buffer.length : (int) (fileSize - bytesWritten); file.seek(bytesWritten); file.write(buffer, 0, toWrite); bytesWritten += toWrite; } } } tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java +22 −0 Original line number Diff line number Diff line Loading @@ -30,11 +30,14 @@ import android.util.Log; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.uiautomator.UiDevice; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; import java.util.Random; public class Utils { public static final String TAG = "BlobStoreTest"; Loading Loading @@ -164,6 +167,25 @@ public class Utils { runShellCmd("cmd blob_store idle-maintenance"); } public static void writeRandomData(File file, long fileSizeBytes) throws Exception { writeRandomData(new RandomAccessFile(file, "rw"), new Random(0), fileSizeBytes); } public static void writeRandomData(RandomAccessFile file, Random random, long fileSizeBytes) throws Exception { long bytesWritten = 0; final byte[] buffer = new byte[BUFFER_SIZE_BYTES]; while (bytesWritten < fileSizeBytes) { random.nextBytes(buffer); final int toWrite = (bytesWritten + buffer.length <= fileSizeBytes) ? buffer.length : (int) (fileSizeBytes - bytesWritten); file.seek(bytesWritten); file.write(buffer, 0, toWrite); bytesWritten += toWrite; } } public static String runShellCmd(String cmd) throws IOException { final UiDevice uiDevice = UiDevice.getInstance( InstrumentationRegistry.getInstrumentation()); Loading Loading
apct-tests/perftests/blobstore/Android.bp +14 −13 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ android_test { "apct-perftests-utils", "ub-uiautomator", "collector-device-lib-platform", "androidx.benchmark_benchmark-macro", ], platform_apis: true, test_suites: ["device-tests"], Loading
apct-tests/perftests/blobstore/src/com/android/perftests/blob/BlobStorePerfTests.java +118 −1 Original line number Diff line number Diff line Loading @@ -15,15 +15,20 @@ */ package com.android.perftests.blob; import static com.android.utils.blob.Utils.acquireLease; import android.app.blob.BlobHandle; import android.app.blob.BlobStoreManager; import android.content.Context; import android.os.ParcelFileDescriptor; import android.perftests.utils.ManualBenchmarkState; import android.perftests.utils.PerfManualStatusReporter; import android.perftests.utils.TraceMarkParser; import android.perftests.utils.TraceMarkParser.TraceMarkSlice; import android.support.test.uiautomator.UiDevice; import android.util.DataUnit; import androidx.benchmark.macro.MacrobenchmarkScope; import androidx.test.filters.LargeTest; import androidx.test.platform.app.InstrumentationRegistry; Loading @@ -36,12 +41,16 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.Collection; import java.util.List; import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; Loading @@ -53,6 +62,8 @@ public class BlobStorePerfTests { // From f/b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java private static final String ATRACE_COMPUTE_DIGEST_PREFIX = "computeBlobDigest-"; public static final int BUFFER_SIZE_BYTES = 16 * 1024; private Context mContext; private BlobStoreManager mBlobStoreManager; private AtraceUtils mAtraceUtils; Loading Loading @@ -85,6 +96,8 @@ public class BlobStorePerfTests { @After public void tearDown() { mContext.getFilesDir().delete(); runShellCommand("cmd package clear " + mContext.getPackageName()); runShellCommand("cmd blob_store idle-maintenance"); } Loading @@ -109,6 +122,110 @@ public class BlobStorePerfTests { } } @Test public void testDirectReads() throws Exception { final File file = new File(mContext.getDataDir(), "test_read_file"); final long sizeBytes = DataUnit.MEBIBYTES.toBytes(fileSizeInMb); try (FileOutputStream outputStream = new FileOutputStream(file)) { writeData(outputStream, sizeBytes); } long durationNs = 0; while (mState.keepRunning(durationNs)) { dropCache(); try (FileInputStream inputStream = new FileInputStream(file)) { final long startTimeNs = System.nanoTime(); readData(inputStream, sizeBytes); durationNs = System.nanoTime() - startTimeNs; } } } @Test public void testBlobStoreReads() throws Exception { final FakeBlobData blobData = prepareDataBlob(fileSizeInMb); commitBlob(blobData); acquireLease(mContext, blobData.getBlobHandle(), "Test Desc"); final long sizeBytes = DataUnit.MEBIBYTES.toBytes(fileSizeInMb); long durationNs = 0; while (mState.keepRunning(durationNs)) { dropCache(); try (FileInputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream( mBlobStoreManager.openBlob(blobData.getBlobHandle()))) { final long startTimeNs = System.nanoTime(); readData(inputStream, sizeBytes); durationNs = System.nanoTime() - startTimeNs; } } deleteBlob(blobData.getBlobHandle()); } @Test public void testDirectWrites() throws Exception { final File file = new File(mContext.getDataDir(), "test_write_file"); final long sizeBytes = DataUnit.MEBIBYTES.toBytes(fileSizeInMb); long durationNs = 0; while (mState.keepRunning(durationNs)) { file.delete(); dropCache(); try (FileOutputStream outputStream = new FileOutputStream(file)) { final long startTimeNs = System.nanoTime(); writeData(outputStream, sizeBytes); durationNs = System.nanoTime() - startTimeNs; } } } @Test public void testBlobStoreWrites() throws Exception { final FakeBlobData blobData = prepareDataBlob(fileSizeInMb); final long sizeBytes = DataUnit.MEBIBYTES.toBytes(fileSizeInMb); long durationNs = 0; while (mState.keepRunning(durationNs)) { final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle()); try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) { dropCache(); try (FileOutputStream outputStream = new ParcelFileDescriptor .AutoCloseOutputStream(session.openWrite(0, sizeBytes))) { final long startTimeNs = System.nanoTime(); writeData(outputStream, sizeBytes); durationNs = System.nanoTime() - startTimeNs; } } mBlobStoreManager.abandonSession(sessionId); } } private void readData(FileInputStream inputStream, long sizeBytes) throws Exception { final byte[] buffer = new byte[BUFFER_SIZE_BYTES]; long bytesRead = 0; while (bytesRead < sizeBytes) { bytesRead += inputStream.read(buffer); } } private void writeData(FileOutputStream outputStream, long sizeBytes) throws Exception { final byte[] buffer = new byte[BUFFER_SIZE_BYTES]; long bytesWritten = 0; final Random random = new Random(0); while (bytesWritten < sizeBytes) { random.nextBytes(buffer); final int toWrite = (bytesWritten + buffer.length <= sizeBytes) ? buffer.length : (int) (sizeBytes - bytesWritten); outputStream.write(buffer, 0, toWrite); bytesWritten += toWrite; } } private void dropCache() { final MacrobenchmarkScope scope = new MacrobenchmarkScope(mContext.getPackageName(), false); scope.dropKernelPageCache(); } private void collectDigestDurationsFromTrace(TraceMarkParser parser, List<Long> durations) { mAtraceUtils.performDump(parser, (key, slices) -> { for (TraceMarkSlice slice : slices) { Loading @@ -119,7 +236,7 @@ public class BlobStorePerfTests { private FakeBlobData prepareDataBlob(int fileSizeInMb) throws Exception { final FakeBlobData blobData = new FakeBlobData.Builder(mContext) .setFileSize(fileSizeInMb * 1024 * 1024 /* bytes */) .setFileSize(DataUnit.MEBIBYTES.toBytes(fileSizeInMb)) .build(); blobData.prepare(); return blobData; Loading
tests/BlobStoreTestUtils/src/com/android/utils/blob/FakeBlobData.java +2 −15 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.utils.blob; import static com.android.utils.blob.Utils.BUFFER_SIZE_BYTES; import static com.android.utils.blob.Utils.copy; import static com.android.utils.blob.Utils.writeRandomData; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -123,7 +124,7 @@ public class FakeBlobData { public void prepare() throws Exception { try (RandomAccessFile file = new RandomAccessFile(mFile, "rw")) { writeRandomData(file, mFileSize); writeRandomData(file, mRandom, mFileSize); } mFileDigest = FileUtils.digest(mFile, "SHA-256"); mExpiryTimeMs = System.currentTimeMillis() + mExpiryDurationMs; Loading Loading @@ -239,18 +240,4 @@ public class FakeBlobData { } return digest.digest(); } private void writeRandomData(RandomAccessFile file, long fileSize) throws Exception { long bytesWritten = 0; final byte[] buffer = new byte[BUFFER_SIZE_BYTES]; while (bytesWritten < fileSize) { mRandom.nextBytes(buffer); final int toWrite = (bytesWritten + buffer.length <= fileSize) ? buffer.length : (int) (fileSize - bytesWritten); file.seek(bytesWritten); file.write(buffer, 0, toWrite); bytesWritten += toWrite; } } }
tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java +22 −0 Original line number Diff line number Diff line Loading @@ -30,11 +30,14 @@ import android.util.Log; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.uiautomator.UiDevice; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; import java.util.Random; public class Utils { public static final String TAG = "BlobStoreTest"; Loading Loading @@ -164,6 +167,25 @@ public class Utils { runShellCmd("cmd blob_store idle-maintenance"); } public static void writeRandomData(File file, long fileSizeBytes) throws Exception { writeRandomData(new RandomAccessFile(file, "rw"), new Random(0), fileSizeBytes); } public static void writeRandomData(RandomAccessFile file, Random random, long fileSizeBytes) throws Exception { long bytesWritten = 0; final byte[] buffer = new byte[BUFFER_SIZE_BYTES]; while (bytesWritten < fileSizeBytes) { random.nextBytes(buffer); final int toWrite = (bytesWritten + buffer.length <= fileSizeBytes) ? buffer.length : (int) (fileSizeBytes - bytesWritten); file.seek(bytesWritten); file.write(buffer, 0, toWrite); bytesWritten += toWrite; } } public static String runShellCmd(String cmd) throws IOException { final UiDevice uiDevice = UiDevice.getInstance( InstrumentationRegistry.getInstrumentation()); Loading