[benchmark] Add benchmarks for authfs seq/rand write
This CL adds benchmarks for authfs remote write in sequential
and random modes.
Test: atest AuthFsBenchmarks
Bug: 236123069
Change-Id: Ib13aa46a0e8bf17f89d80ff88d6dc1ca02582be2
diff --git a/authfs/tests/java/src/com/android/fs/AuthFsBenchmarks.java b/authfs/tests/java/src/com/android/fs/AuthFsBenchmarks.java
index fb8c0cc..f84785b 100644
--- a/authfs/tests/java/src/com/android/fs/AuthFsBenchmarks.java
+++ b/authfs/tests/java/src/com/android/fs/AuthFsBenchmarks.java
@@ -47,7 +47,6 @@
@RunWith(DeviceJUnit4ClassRunner.class)
public class AuthFsBenchmarks extends BaseHostJUnit4Test {
private static final int TRIAL_COUNT = 5;
- private static final int FILE_SIZE_IN_MB = 4;
/** Name of the measure_io binary on host. */
private static final String MEASURE_IO_BIN_NAME = "measure_io";
@@ -92,6 +91,16 @@
readRemoteFile("rand");
}
+ @Test
+ public void seqWriteRemoteFile() throws Exception {
+ writeRemoteFile("seq");
+ }
+
+ @Test
+ public void randWriteRemoteFile() throws Exception {
+ writeRemoteFile("rand");
+ }
+
private void readRemoteFile(String mode) throws DeviceNotAvailableException {
pushMeasureIoBinToMicrodroid();
// Cache the file in memory for the host.
@@ -100,7 +109,8 @@
.run("cat " + mAuthFsTestRule.TEST_DIR + "/input.4m > /dev/null");
String filePath = mAuthFsTestRule.MOUNT_DIR + "/3";
- String cmd = MEASURE_IO_BIN_PATH + " " + filePath + " " + FILE_SIZE_IN_MB + " " + mode;
+ int fileSizeMb = 4;
+ String cmd = MEASURE_IO_BIN_PATH + " " + filePath + " " + fileSizeMb + " " + mode + " r";
List<Double> rates = new ArrayList<>(TRIAL_COUNT);
for (int i = 0; i < TRIAL_COUNT + 1; ++i) {
mAuthFsTestRule.runFdServerOnAndroid(
@@ -113,6 +123,23 @@
reportMetrics(rates, mode + "_read", "mb_per_sec");
}
+ private void writeRemoteFile(String mode) throws DeviceNotAvailableException {
+ pushMeasureIoBinToMicrodroid();
+ String filePath = mAuthFsTestRule.MOUNT_DIR + "/5";
+ int fileSizeMb = 8;
+ String cmd = MEASURE_IO_BIN_PATH + " " + filePath + " " + fileSizeMb + " " + mode + " w";
+ List<Double> rates = new ArrayList<>(TRIAL_COUNT);
+ for (int i = 0; i < TRIAL_COUNT + 1; ++i) {
+ mAuthFsTestRule.runFdServerOnAndroid(
+ "--open-rw 5:" + mAuthFsTestRule.TEST_OUTPUT_DIR + "/out.file", "--rw-fds 5");
+ mAuthFsTestRule.runAuthFsOnMicrodroid("--remote-new-rw-file 5");
+
+ String rate = mAuthFsTestRule.getMicrodroid().run(cmd);
+ rates.add(Double.parseDouble(rate));
+ }
+ reportMetrics(rates, mode + "_write", "mb_per_sec");
+ }
+
private void pushMeasureIoBinToMicrodroid() throws DeviceNotAvailableException {
File measureReadBin = mAuthFsTestRule.findTestFile(getBuild(), MEASURE_IO_BIN_NAME);
assertThat(measureReadBin.exists()).isTrue();
diff --git a/authfs/tests/java/src/com/android/fs/AuthFsTestRule.java b/authfs/tests/java/src/com/android/fs/AuthFsTestRule.java
index ebeac4f..045ecc0 100644
--- a/authfs/tests/java/src/com/android/fs/AuthFsTestRule.java
+++ b/authfs/tests/java/src/com/android/fs/AuthFsTestRule.java
@@ -62,7 +62,7 @@
private static final String TEST_APK_NAME = "MicrodroidTestApp.apk";
/** Output directory where the test can generate output on Android */
- private static final String TEST_OUTPUT_DIR = "/data/local/tmp/authfs/output_dir";
+ static final String TEST_OUTPUT_DIR = "/data/local/tmp/authfs/output_dir";
/** Mount point of authfs on Microdroid during the test */
static final String MOUNT_DIR = "/data/local/tmp/mnt";
diff --git a/authfs/tests/measure_io.cpp b/authfs/tests/measure_io.cpp
index e9548ae..e1f2fb8 100644
--- a/authfs/tests/measure_io.cpp
+++ b/authfs/tests/measure_io.cpp
@@ -15,6 +15,7 @@
*/
#include <android-base/unique_fd.h>
+#include <assert.h>
#include <err.h>
#include <fcntl.h>
#include <string.h>
@@ -32,11 +33,13 @@
constexpr int kNumBytesPerMB = 1024 * 1024;
int main(int argc, const char *argv[]) {
- if (argc != 4 || !(strcmp(argv[3], "rand") == 0 || strcmp(argv[3], "seq") == 0)) {
- errx(EXIT_FAILURE, "Usage: %s <filename> <file_size_mb> <rand|seq>", argv[0]);
+ if (argc != 5 || !(strcmp(argv[3], "rand") == 0 || strcmp(argv[3], "seq") == 0) ||
+ !(strcmp(argv[4], "r") == 0 || strcmp(argv[4], "w") == 0)) {
+ errx(EXIT_FAILURE, "Usage: %s <filename> <file_size_mb> <rand|seq> <r|w>", argv[0]);
}
int file_size_mb = std::stoi(argv[2]);
bool is_rand = (strcmp(argv[3], "rand") == 0);
+ bool is_read = (strcmp(argv[4], "r") == 0);
const int block_count = file_size_mb * kNumBytesPerMB / kBlockSizeBytes;
std::vector<int> offsets(block_count);
for (auto i = 0; i < block_count; ++i) {
@@ -46,7 +49,7 @@
std::mt19937 rd{std::random_device{}()};
std::shuffle(offsets.begin(), offsets.end(), rd);
}
- unique_fd fd(open(argv[1], O_RDONLY | O_CLOEXEC));
+ unique_fd fd(open(argv[1], (is_read ? O_RDONLY : O_WRONLY) | O_CLOEXEC));
if (fd.get() == -1) {
errx(EXIT_FAILURE, "failed to open file: %s", argv[1]);
}
@@ -54,13 +57,18 @@
char buf[kBlockSizeBytes];
clock_t start = clock();
for (auto i = 0; i < block_count; ++i) {
- auto bytes = pread(fd, buf, kBlockSizeBytes, offsets[i]);
+ auto bytes = is_read ? pread(fd, buf, kBlockSizeBytes, offsets[i])
+ : pwrite(fd, buf, kBlockSizeBytes, offsets[i]);
if (bytes == 0) {
errx(EXIT_FAILURE, "unexpected end of file");
} else if (bytes == -1) {
errx(EXIT_FAILURE, "failed to read");
}
}
+ if (!is_read) {
+ // Writes all the buffered modifications to the open file.
+ assert(syncfs(fd) == 0);
+ }
double elapsed_seconds = ((double)clock() - start) / CLOCKS_PER_SEC;
double rate = (double)file_size_mb / elapsed_seconds;
std::cout << std::setprecision(12) << rate << std::endl;