1 /*
2  * Copyright (C) 2016 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.mtp;
18 
19 import android.app.Activity;
20 import android.content.Context;
21 import android.os.Bundle;
22 import android.os.ParcelFileDescriptor;
23 import android.os.ProxyFileDescriptorCallback;
24 import android.os.storage.StorageManager;
25 import android.system.ErrnoException;
26 
27 import androidx.test.InstrumentationRegistry;
28 import androidx.test.filters.LargeTest;
29 
30 import org.junit.Test;
31 import org.junit.runner.RunWith;
32 import org.junit.runners.JUnit4;
33 
34 import java.io.IOException;
35 
36 @RunWith(JUnit4.class)
37 public class AppFusePerfTest {
38     final static int SIZE = 10 * 1024 * 1024;  // 10MB
39 
40     @Test
41     @LargeTest
testReadWriteFile()42     public void testReadWriteFile() throws IOException {
43         final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
44         final StorageManager storageManager = context.getSystemService(StorageManager.class);
45 
46         final byte[] bytes = new byte[SIZE];
47         final int SAMPLES = 100;
48         final double[] readTime = new double[SAMPLES];
49         final double[] writeTime = new double[SAMPLES];
50 
51         for (int i = 0; i < SAMPLES; i++) {
52             final ParcelFileDescriptor fd = storageManager.openProxyFileDescriptor(
53                     ParcelFileDescriptor.MODE_READ_ONLY, new TestCallback());
54             try (final ParcelFileDescriptor.AutoCloseInputStream stream =
55                     new ParcelFileDescriptor.AutoCloseInputStream(fd)) {
56                 final long startTime = System.nanoTime();
57                 stream.read(bytes);
58                 readTime[i] = (System.nanoTime() - startTime) / 1000.0 / 1000.0;
59             }
60         }
61 
62         for (int i = 0; i < SAMPLES; i++) {
63             final ParcelFileDescriptor fd = storageManager.openProxyFileDescriptor(
64                     ParcelFileDescriptor.MODE_WRITE_ONLY | ParcelFileDescriptor.MODE_TRUNCATE,
65                     new TestCallback());
66             try (final ParcelFileDescriptor.AutoCloseOutputStream stream =
67                     new ParcelFileDescriptor.AutoCloseOutputStream(fd)) {
68                 final long startTime = System.nanoTime();
69                 stream.write(bytes);
70                 writeTime[i] = (System.nanoTime() - startTime) / 1000.0 / 1000.0;
71             }
72         }
73 
74         double readAverage = 0;
75         double writeAverage = 0;
76         double readSquaredAverage = 0;
77         double writeSquaredAverage = 0;
78         for (int i = 0; i < SAMPLES; i++) {
79             readAverage += readTime[i];
80             writeAverage += writeTime[i];
81             readSquaredAverage += readTime[i] * readTime[i];
82             writeSquaredAverage += writeTime[i] * writeTime[i];
83         }
84 
85         readAverage /= SAMPLES;
86         writeAverage /= SAMPLES;
87         readSquaredAverage /= SAMPLES;
88         writeSquaredAverage /= SAMPLES;
89 
90         final Bundle results = new Bundle();
91         results.putDouble("readAverage", readAverage);
92         results.putDouble("readStandardDeviation",
93                 Math.sqrt(readSquaredAverage - readAverage * readAverage));
94         results.putDouble("writeAverage", writeAverage);
95         results.putDouble("writeStandardDeviation",
96                 Math.sqrt(writeSquaredAverage - writeAverage * writeAverage));
97         InstrumentationRegistry.getInstrumentation().sendStatus(Activity.RESULT_OK, results);
98     }
99 
100     private static class TestCallback extends ProxyFileDescriptorCallback {
101         @Override
onGetSize()102         public long onGetSize() throws ErrnoException {
103             return SIZE;
104         }
105 
106         @Override
onRead(long offset, int size, byte[] data)107         public int onRead(long offset, int size, byte[] data) throws ErrnoException {
108             return size;
109         }
110 
111         @Override
onWrite(long offset, int size, byte[] data)112         public int onWrite(long offset, int size, byte[] data) throws ErrnoException {
113             return size;
114         }
115 
116         @Override
onFsync()117         public void onFsync() throws ErrnoException {}
118 
119         @Override
onRelease()120         public void onRelease() {}
121     }
122 }
123