Skip to content

Commit 44d903e

Browse files
committed
Android tests: use AndroidExtensions StdoutLogger for stdout->logcat
Replace the hand-rolled pipe+thread stdout pump (added while bringing up the in-process Node-API harness) with android::StdoutLogger::Start()/Stop() from AndroidExtensions, which the rest of the UnitTests host already uses. Same effect -- the in-process gtest output (incl. failure file:line:message) is visible in logcat (tag StdoutLogger) -- with less bespoke code. Verified on emulator: 8/8 UnitTests pass incl. 4/4 js_native_api, gtest output present in logcat.
1 parent 538fe04 commit 44d903e

1 file changed

Lines changed: 7 additions & 52 deletions

File tree

  • Tests/UnitTests/Android/app/src/main/cpp

Tests/UnitTests/Android/app/src/main/cpp/JNI.cpp

Lines changed: 7 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,13 @@
22
#include <android/log.h>
33
#include <AndroidExtensions/Globals.h>
44
#include <AndroidExtensions/JavaWrappers.h>
5+
#include <AndroidExtensions/StdoutLogger.h>
56
#include <android/asset_manager_jni.h>
67
#include "Babylon/DebugTrace.h"
78
#include <Shared/Shared.h>
89

9-
#include <pthread.h>
10-
#include <unistd.h>
11-
#include <cstdio>
12-
#include <string>
13-
14-
namespace {
15-
16-
// The conformance suite runs gtest in-process and writes results (including failure file/line/message)
17-
// to stdout/stderr, which Android otherwise discards. Pump both to logcat so test output -- and any
18-
// native crash context printed before the process dies -- is actually visible (e.g.
19-
// `adb logcat -s NodeApiTests`). Without this the only signal is the JUnit "expected 0, was 1".
20-
void* PumpStdioToLogcat(void* arg) {
21-
int read_fd = *static_cast<int*>(arg);
22-
char buffer[1024];
23-
std::string line;
24-
ssize_t count;
25-
while ((count = read(read_fd, buffer, sizeof(buffer) - 1)) > 0) {
26-
buffer[count] = '\0';
27-
line += buffer;
28-
std::string::size_type newline;
29-
while ((newline = line.find('\n')) != std::string::npos) {
30-
__android_log_write(ANDROID_LOG_INFO, "NodeApiTests", line.substr(0, newline).c_str());
31-
line.erase(0, newline + 1);
32-
}
33-
}
34-
return nullptr;
35-
}
36-
37-
void RedirectStdioToLogcat() {
38-
static int pipe_fds[2];
39-
static bool installed = false;
40-
if (installed) {
41-
return;
42-
}
43-
installed = true;
44-
setvbuf(stdout, nullptr, _IOLBF, 0);
45-
setvbuf(stderr, nullptr, _IONBF, 0);
46-
if (pipe(pipe_fds) != 0) {
47-
return;
48-
}
49-
dup2(pipe_fds[1], STDOUT_FILENO);
50-
dup2(pipe_fds[1], STDERR_FILENO);
51-
pthread_t thread;
52-
if (pthread_create(&thread, nullptr, PumpStdioToLogcat, &pipe_fds[0]) == 0) {
53-
pthread_detach(thread);
54-
}
55-
}
56-
57-
} // namespace
58-
5910
extern "C" JNIEXPORT jint JNICALL
6011
Java_com_jsruntimehost_unittests_Native_javaScriptTests(JNIEnv* env, jclass clazz, jobject context) {
61-
RedirectStdioToLogcat();
62-
6312
JavaVM* javaVM{};
6413
if (env->GetJavaVM(&javaVM) != JNI_OK)
6514
{
@@ -69,6 +18,10 @@ Java_com_jsruntimehost_unittests_Native_javaScriptTests(JNIEnv* env, jclass claz
6918
jclass webSocketClass{env->FindClass("com/jsruntimehost/unittests/WebSocket")};
7019
java::websocket::WebSocketClient::InitializeJavaWebSocketClass(webSocketClass, env);
7120

21+
// Route stdout (the in-process gtest output -- [RUN]/[OK]/[FAILED] + failure file:line:message)
22+
// to logcat so test results are visible; stopped after RunTests below.
23+
android::StdoutLogger::Start();
24+
7225
jclass contextClass = env->GetObjectClass(context);
7326
jmethodID getApplicationContext = env->GetMethodID(contextClass, "getApplicationContext", "()Landroid/content/Context;");
7427
jobject applicationContext = env->CallObjectMethod(context, getApplicationContext);
@@ -120,6 +73,8 @@ Java_com_jsruntimehost_unittests_Native_javaScriptTests(JNIEnv* env, jclass claz
12073

12174
auto testResult = RunTests();
12275

76+
android::StdoutLogger::Stop();
77+
12378
java::websocket::WebSocketClient::DestructJavaWebSocketClass(env);
12479
return testResult;
12580
}

0 commit comments

Comments
 (0)