Merge "Handle test failure better"
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index b3b8816..5c48a41 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -33,6 +33,7 @@
import android.system.virtualmachine.VirtualMachineConfig.DebugLevel;
import android.system.virtualmachine.VirtualMachineException;
import android.system.virtualmachine.VirtualMachineManager;
+import android.util.Log;
import androidx.annotation.CallSuper;
import androidx.test.core.app.ApplicationProvider;
@@ -47,9 +48,13 @@
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
+import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.util.List;
@@ -68,10 +73,27 @@
@RunWith(Parameterized.class)
public class MicrodroidTests {
+ private static final String TAG = "MicrodroidTests";
+
@Rule public Timeout globalTimeout = Timeout.seconds(300);
private static final String KERNEL_VERSION = SystemProperties.get("ro.kernel.version");
+ /** Copy output from the VM to logcat. This is helpful when things go wrong. */
+ private static void logVmOutput(InputStream vmOutputStream, String name) {
+ new Thread(() -> {
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(vmOutputStream));
+ String line;
+ while ((line = reader.readLine()) != null && !Thread.interrupted()) {
+ Log.i(TAG, name + ": " + line);
+ }
+ } catch (Exception e) {
+ Log.w(TAG, name, e);
+ }
+ }).start();
+ }
+
private static class Inner {
public boolean mProtectedVm;
public Context mContext;
@@ -149,6 +171,8 @@
void runToFinish(VirtualMachine vm) throws VirtualMachineException, InterruptedException {
vm.setCallback(mExecutorService, this);
vm.run();
+ logVmOutput(vm.getConsoleOutputStream(), "Console");
+ logVmOutput(vm.getLogOutputStream(), "Log");
mExecutorService.awaitTermination(300, TimeUnit.SECONDS);
}
@@ -238,6 +262,7 @@
@Override
public void onPayloadReady(VirtualMachine vm) {
+ Log.i(TAG, "onPayloadReady");
payloadReady.complete(true);
testVMService(vm);
forceStop(vm);
@@ -245,7 +270,9 @@
@Override
public void onPayloadStarted(VirtualMachine vm, ParcelFileDescriptor stream) {
+ Log.i(TAG, "onPayloadStarted");
payloadStarted.complete(true);
+ logVmOutput(new FileInputStream(stream.getFileDescriptor()), "Payload");
}
};
listener.runToFinish(mInner.mVm);
diff --git a/tests/testapk/src/native/testbinary.cpp b/tests/testapk/src/native/testbinary.cpp
index 89570c0..9493fc7 100644
--- a/tests/testapk/src/native/testbinary.cpp
+++ b/tests/testapk/src/native/testbinary.cpp
@@ -134,16 +134,18 @@
auto callback = []([[maybe_unused]] void* param) {
// Tell microdroid_manager that we're ready.
- // Failing to notify is not a fatal error; the payload can continue.
+ // If we can't, abort in order to fail fast - the host won't proceed without
+ // receiving the onReady signal.
ndk::SpAIBinder binder(
RpcClient(VMADDR_CID_HOST, IVirtualMachineService::VM_BINDER_SERVICE_PORT));
auto virtualMachineService = IVirtualMachineService::fromBinder(binder);
if (virtualMachineService == nullptr) {
- std::cerr << "failed to connect VirtualMachineService";
- return;
+ std::cerr << "failed to connect VirtualMachineService\n";
+ abort();
}
if (!virtualMachineService->notifyPayloadReady().isOk()) {
- std::cerr << "failed to notify payload ready to virtualizationservice";
+ std::cerr << "failed to notify payload ready to virtualizationservice\n";
+ abort();
}
};
@@ -197,7 +199,7 @@
if (auto res = start_test_service(); res.ok()) {
return 0;
} else {
- std::cerr << "starting service failed: " << res.error();
+ std::cerr << "starting service failed: " << res.error() << "\n";
return 1;
}
}