Skip to content

Commit 01b938d

Browse files
jpnurmiclaude
andcommitted
fix(tests): replace pm clear with force-stop + run-as on Android
`pm clear` requires `CLEAR_APP_USER_DATA` permission which is denied on some OEM devices (e.g. OnePlus) even in developer mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d8e92a1 commit 01b938d

1 file changed

Lines changed: 65 additions & 55 deletions

File tree

tests/test_dotnet_signals.py

Lines changed: 65 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,10 @@ def run_android(args=None, timeout=30):
284284
if args is None:
285285
args = []
286286
adb("logcat", "-c")
287-
adb("shell", "pm", "clear", ANDROID_PACKAGE)
287+
adb("shell", "am", "force-stop", ANDROID_PACKAGE)
288+
adb(
289+
"shell", "run-as {} sh -c 'rm -rf files/.sentry-native'".format(ANDROID_PACKAGE)
290+
)
288291
intent_args = []
289292
for arg in args:
290293
intent_args += ["--es", "arg", arg]
@@ -328,7 +331,7 @@ def run_android_native_crash():
328331
not is_android or int(is_android) < 26,
329332
reason="needs Android API 26+ (tombstoned)",
330333
)
331-
def test_android_signals_inproc(cmake):
334+
def test_android_signals_inproc(cmake, request, __pytest_repeat_step_number):
332335
if shutil.which("dotnet") is None:
333336
pytest.skip("dotnet is not installed")
334337

@@ -346,57 +349,62 @@ def test_android_signals_inproc(cmake):
346349
{"SENTRY_BACKEND": "inproc", "SENTRY_TRANSPORT": "none"},
347350
)
348351

349-
# build libcrash.so with NDK clang
350-
ndk_prebuilt = pathlib.Path(
351-
"{}/ndk/{}/toolchains/llvm/prebuilt".format(
352-
os.environ["ANDROID_HOME"], os.environ["ANDROID_NDK"]
352+
if __pytest_repeat_step_number == 0:
353+
# build libcrash.so with NDK clang
354+
ndk_prebuilt = pathlib.Path(
355+
"{}/ndk/{}/toolchains/llvm/prebuilt".format(
356+
os.environ["ANDROID_HOME"], os.environ["ANDROID_NDK"]
357+
)
358+
)
359+
triples = {
360+
"x86_64": "x86_64-linux-android",
361+
"x86": "i686-linux-android",
362+
"arm64-v8a": "aarch64-linux-android",
363+
"armeabi-v7a": "armv7a-linux-androideabi",
364+
}
365+
ndk_clang = str(
366+
next(ndk_prebuilt.iterdir())
367+
/ "bin"
368+
/ "{}{}-clang".format(triples[arch], os.environ["ANDROID_API"])
369+
)
370+
native_lib_dir = project_fixture_path / "native" / arch
371+
native_lib_dir.mkdir(parents=True, exist_ok=True)
372+
shutil.copy2(tmp_path / "libsentry.so", native_lib_dir / "libsentry.so")
373+
subprocess.run(
374+
[
375+
ndk_clang,
376+
"-Wall",
377+
"-Wextra",
378+
"-fPIC",
379+
"-shared",
380+
str(project_fixture_path / "crash.c"),
381+
"-o",
382+
str(native_lib_dir / "libcrash.so"),
383+
],
384+
check=True,
353385
)
354-
)
355-
triples = {
356-
"x86_64": "x86_64-linux-android",
357-
"x86": "i686-linux-android",
358-
"arm64-v8a": "aarch64-linux-android",
359-
"armeabi-v7a": "armv7a-linux-androideabi",
360-
}
361-
ndk_clang = str(
362-
next(ndk_prebuilt.iterdir())
363-
/ "bin"
364-
/ "{}{}-clang".format(triples[arch], os.environ["ANDROID_API"])
365-
)
366-
native_lib_dir = project_fixture_path / "native" / arch
367-
native_lib_dir.mkdir(parents=True, exist_ok=True)
368-
shutil.copy2(tmp_path / "libsentry.so", native_lib_dir / "libsentry.so")
369-
subprocess.run(
370-
[
371-
ndk_clang,
372-
"-Wall",
373-
"-Wextra",
374-
"-fPIC",
375-
"-shared",
376-
str(project_fixture_path / "crash.c"),
377-
"-o",
378-
str(native_lib_dir / "libcrash.so"),
379-
],
380-
check=True,
381-
)
382386

383-
# build and install the APK
384-
subprocess.run(
385-
[
386-
"dotnet",
387-
"build",
388-
"-f:net10.0-android",
389-
"-p:RuntimeIdentifier={}".format(rid_map[arch]),
390-
"-p:Configuration=Release",
391-
],
392-
cwd=project_fixture_path,
393-
check=True,
394-
)
395-
apk_dir = (
396-
project_fixture_path / "bin" / "Release" / "net10.0-android" / rid_map[arch]
397-
)
398-
apk_path = next(apk_dir.glob("*-Signed.apk"))
399-
adb("install", "-r", str(apk_path), check=True)
387+
# build and install the APK
388+
subprocess.run(
389+
[
390+
"dotnet",
391+
"build",
392+
"-f:net10.0-android",
393+
"-p:RuntimeIdentifier={}".format(rid_map[arch]),
394+
"-p:Configuration=Release",
395+
],
396+
cwd=project_fixture_path,
397+
check=True,
398+
)
399+
apk_dir = (
400+
project_fixture_path
401+
/ "bin"
402+
/ "Release"
403+
/ "net10.0-android"
404+
/ rid_map[arch]
405+
)
406+
apk_path = next(apk_dir.glob("*-Signed.apk"))
407+
adb("install", "-r", str(apk_path), check=True)
400408

401409
def run_as(cmd, **kwargs):
402410
return adb(
@@ -445,7 +453,9 @@ def has_envelope():
445453
assert wait_for(has_envelope), "Crash envelope is missing"
446454

447455
finally:
448-
shutil.rmtree(project_fixture_path / "native", ignore_errors=True)
449-
shutil.rmtree(project_fixture_path / "bin", ignore_errors=True)
450-
shutil.rmtree(project_fixture_path / "obj", ignore_errors=True)
451-
adb("uninstall", ANDROID_PACKAGE, check=False)
456+
repeat_count = getattr(request.config.option, "count", 1)
457+
if __pytest_repeat_step_number == repeat_count - 1:
458+
shutil.rmtree(project_fixture_path / "native", ignore_errors=True)
459+
shutil.rmtree(project_fixture_path / "bin", ignore_errors=True)
460+
shutil.rmtree(project_fixture_path / "obj", ignore_errors=True)
461+
adb("uninstall", ANDROID_PACKAGE, check=False)

0 commit comments

Comments
 (0)