Verify repeated JNI delivery and log subscription changes
This commit is contained in:
1 parent
269d09815b
commit
1c705e64ca
2 files changed
+46
-4
No files matched your search
@@ -1998,6 +1998,9 @@ JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeInit(
|
||||
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI log callback configured=%d; UTF-8 byte arrays", logCb != NULL);
|
||||
|
||||
const char* db = dbPath ? (*env)->GetStringUTFChars(env, dbPath, NULL) : NULL;
|
||||
if (dbPath && !db) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "JNI log: nativeInit db path access failed"); return JNI_FALSE;
|
||||
}
|
||||
if (db) { strncpy(g_db_path, db, sizeof(g_db_path) - 1); g_db_path[sizeof(g_db_path) - 1] = '\0'; }
|
||||
|
||||
utun_log_fn log_cb = logCb ? jni_on_log : NULL;
|
||||
|
||||
@@ -9,14 +9,18 @@ static struct ref refs[16], global_ref;
|
||||
static enum fault fault;
|
||||
static int pending, throw_on_failure, illegal_calls, calls, attaches, detaches, descriptions, diagnostics, nested;
|
||||
static int already_attached, arrays, copies, legacy_strings, payload_ok;
|
||||
static int normal_logs;
|
||||
static char last_diagnostic[512], method_signature[128];
|
||||
static JNIEnv test_env;
|
||||
static const char category[] = "чат", message[] = "Ошибка 😀";
|
||||
static const char* expected_category;
|
||||
static const char* expected_message;
|
||||
|
||||
#define CHECK(test) do { if (!(test)) { fprintf(stderr, "[FAIL] %s:%d: %s\n", __func__, __LINE__, #test); return 1; } } while (0)
|
||||
|
||||
int __android_log_print(int priority, const char* tag, const char* format, ...) {
|
||||
(void)tag;
|
||||
if (priority == ANDROID_LOG_INFO || priority == ANDROID_LOG_DEBUG) { normal_logs++; return 0; }
|
||||
if (priority != ANDROID_LOG_ERROR && priority != ANDROID_LOG_WARN) illegal_calls++;
|
||||
va_list ap; va_start(ap, format);
|
||||
vsnprintf(last_diagnostic, sizeof(last_diagnostic), format, ap);
|
||||
@@ -90,6 +94,7 @@ static void JNICALL copy_bytes(JNIEnv* env, jbyteArray array, jsize start, jsize
|
||||
static jstring JNICALL legacy_string(JNIEnv* env, const char* text) {
|
||||
(void)env; check_pending(); legacy_strings++;
|
||||
struct ref* ref = (struct ref*)new_ref(4);
|
||||
if (!ref) return NULL;
|
||||
ref->length = (jsize)strlen(text); memcpy(ref->bytes, text, (size_t)ref->length);
|
||||
return (jstring)ref;
|
||||
}
|
||||
@@ -103,8 +108,9 @@ static void JNICALL call(JNIEnv* env, jobject object, jmethodID mid, ...) {
|
||||
struct ref* msg = (struct ref*)va_arg(ap, jobject);
|
||||
va_end(ap);
|
||||
payload_ok = level == BLEV_ERROR && cat && msg && cat->kind == 2 && msg->kind == 2 &&
|
||||
cat->length == (jsize)strlen(category) && msg->length == (jsize)strlen(message) &&
|
||||
!memcmp(cat->bytes, category, strlen(category)) && !memcmp(msg->bytes, message, strlen(message));
|
||||
cat->length == (jsize)strlen(expected_category) && msg->length == (jsize)strlen(expected_message) &&
|
||||
!memcmp(cat->bytes, expected_category, strlen(expected_category)) &&
|
||||
!memcmp(msg->bytes, expected_message, strlen(expected_message));
|
||||
if (fault == CALLBACK) pending = 1;
|
||||
if (fault == RECURSION && !nested++) jni_on_log(BLEV_ERROR, category, message);
|
||||
}
|
||||
@@ -140,10 +146,11 @@ static JavaVM test_vm = &vm_functions;
|
||||
static void reset(enum fault next) {
|
||||
memset(refs, 0, sizeof(refs)); memset(&global_ref, 0, sizeof(global_ref)); global_ref.live = 1;
|
||||
pending = illegal_calls = calls = attaches = detaches = descriptions = diagnostics = nested = 0;
|
||||
arrays = copies = legacy_strings = payload_ok = 0;
|
||||
arrays = copies = legacy_strings = payload_ok = normal_logs = 0;
|
||||
last_diagnostic[0] = method_signature[0] = 0;
|
||||
throw_on_failure = already_attached = 1;
|
||||
fault = next; test_env = &functions; g_jvm = &test_vm; g_log_callback = (jobject)&global_ref;
|
||||
expected_category = category; expected_message = message;
|
||||
}
|
||||
|
||||
static int success(int detached) {
|
||||
@@ -192,6 +199,37 @@ static int replaced_callback(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int empty_fields(void) {
|
||||
reset(OK); expected_category = expected_message = "";
|
||||
jni_on_log(BLEV_ERROR, "", "");
|
||||
CHECK(calls == 1 && payload_ok && arrays == 2 && !copies && !illegal_calls && !live_refs() && !diagnostics);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int repeated_callbacks(void) {
|
||||
reset(OK);
|
||||
for (unsigned i = 0; i < 1024; i++) {
|
||||
jni_on_log(BLEV_ERROR, category, message);
|
||||
CHECK(payload_ok && !live_refs() && !illegal_calls && !pending && !diagnostics);
|
||||
}
|
||||
CHECK(calls == 1024 && !attaches && !detaches);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int subscription(void) {
|
||||
reset(OK);
|
||||
Java_com_utun_chat_data_NativeLib_nativeSubscribeLogs(&test_env, NULL, JNI_FALSE);
|
||||
utun_bridge_log(BLEV_ERROR, category, message);
|
||||
CHECK(!calls);
|
||||
Java_com_utun_chat_data_NativeLib_nativeSubscribeLogs(&test_env, NULL, JNI_TRUE);
|
||||
utun_bridge_log(BLEV_ERROR, category, message);
|
||||
CHECK(calls == 1 && payload_ok && !illegal_calls && !live_refs());
|
||||
Java_com_utun_chat_data_NativeLib_nativeSubscribeLogs(&test_env, NULL, JNI_FALSE);
|
||||
utun_bridge_log(BLEV_ERROR, category, message);
|
||||
CHECK(calls == 1 && normal_logs == 3 && !diagnostics);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disabled_and_invalid(void) {
|
||||
reset(OK); g_log_callback = NULL;
|
||||
jni_on_log(BLEV_ERROR, category, message);
|
||||
@@ -215,7 +253,8 @@ int main(void) {
|
||||
{COPY_CATEGORY, "category"}, {COPY_MESSAGE, "message"}, {CALLBACK, "onNativeLog"}, {DETACH, "DetachCurrentThread"}
|
||||
};
|
||||
int failed = success(0) + success(1) + preexisting_exception() + recursive_callback() + replaced_callback() + disabled_and_invalid();
|
||||
int count = 6;
|
||||
failed += empty_fields() + repeated_callbacks() + subscription();
|
||||
int count = 9;
|
||||
for (unsigned i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||
failed += failure(cases[i].fault, cases[i].phase, 1); count++;
|
||||
if (cases[i].fault >= LOCAL_REF && cases[i].fault <= MESSAGE) {
|
||||
|
||||
Reference in new issue
Block a user