Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration testing for the sentry-native new unwinder #1371

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4b1abd0
Use sentry-native 0.4.7
denrase Mar 30, 2021
6c787d0
Define gradle wrapper the app can be run in android studio
denrase Mar 30, 2021
ce35ab6
add gradle wrapper files
denrase Mar 30, 2021
404d872
Don't enable sentry on startup
denrase Mar 30, 2021
ef56bbe
Add ui test that crashes app and checks for envelope file
denrase Mar 30, 2021
036eb77
Integrate appcenter and update
denrase Mar 30, 2021
90b8a14
Update test
denrase Mar 30, 2021
9393162
Fix warning
denrase Mar 30, 2021
1c2fa29
Remove unused test dependencies
denrase Mar 30, 2021
e6ee342
Setup test orchestrator
denrase Mar 30, 2021
68a5230
Crash in service
denrase Mar 31, 2021
ff96e9f
Init sdk in service and wait, Press back button at end of first test …
denrase Apr 1, 2021
a900ab9
Find a configuration that works
denrase Apr 1, 2021
6d0cd79
add script to build everything and upload to microsoft appcenter
denrase Apr 1, 2021
1120bbd
Merge branch 'main' into feat/automated-android-native-crash
denrase Apr 7, 2021
10fe680
Remove unused build.gradle code
denrase Apr 7, 2021
bcd8224
Remove forceQueryable
denrase Apr 7, 2021
5ec4f9b
Remove sep. gradlew definition
denrase Apr 7, 2021
f75fbb6
Use dep from config
denrase Apr 7, 2021
b323c14
Set dsn in manifest
denrase Apr 7, 2021
cfa3853
Use version 0.4.8 of native sdk
denrase Apr 7, 2021
af7f1df
Update script to use correct gradle wrapper
denrase Apr 7, 2021
132ffe0
Sleep for five seconds before pressing back button, giving the system…
denrase Apr 12, 2021
cc4f6d1
Embed main activity in scrollview, scrollto in in test before click
denrase Apr 15, 2021
f223c8e
Press OK button if there is one
denrase Apr 15, 2021
e1ef03a
Also check for close app button
denrase Apr 15, 2021
513f098
Handle more dialogs
denrase Apr 19, 2021
539f44d
Merge branch 'main' into feat/automated-android-native-crash
denrase Apr 19, 2021
a850fbf
Use latest sentry native master
denrase Apr 19, 2021
c9b95c1
Remove extractNativeLibs
denrase Apr 20, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sentry-android-ndk/sentry-native
Submodule sentry-native updated 39 files
+5 −0 .github/workflows/ci.yml
+11 −2 CMakeLists.txt
+1 −1 external/crashpad
+1 −0 fuzzing-examples/macos-event.json
+1 −0 fuzzing-examples/macos-session.json
+220 −185 src/modulefinder/sentry_modulefinder_linux.c
+31 −12 src/modulefinder/sentry_modulefinder_linux.h
+1 −1 src/path/sentry_path_unix.c
+1 −1 src/sentry_database.c
+22 −9 src/sentry_envelope.c
+38 −57 src/sentry_json.c
+6 −3 src/sentry_json.h
+1 −0 src/sentry_sync.c
+18 −0 src/sentry_sync.h
+22 −3 src/sentry_utils.c
+37 −11 src/sentry_value.c
+8 −0 src/sentry_value.h
+6 −2 src/transports/sentry_transport_curl.c
+10 −3 src/unwinder/sentry_unwinder_libbacktrace.c
+9 −1 tests/__init__.py
+4 −1 tests/cmake.py
+1 −0 tests/fuzzing-failures/id-000000,sig-06,src-000560,op-havoc,rep-2
+ tests/fuzzing-failures/id-000000,sig-11,src-000033+000005,op-splice,rep-16
+ tests/fuzzing-failures/id-000000,sig-11,src-000320,op-havoc,rep-2
+ tests/fuzzing-failures/id-000000,sig-11,src-000494+000073,op-splice,rep-8
+ tests/fuzzing-failures/id-000001,sig-11,src-000052+000222,op-splice,rep-32
+1 −0 tests/fuzzing-failures/id-000001,sig-11,src-000215+000415,op-splice,rep-16
+1 −0 tests/fuzzing-failures/id-000002,sig-11,src-000339+000110,op-splice,rep-16
+ tests/fuzzing-failures/id-000002,sig-11,src-000447+000419,op-splice,rep-32
+ tests/fuzzing-failures/id-000003,sig-11,src-000399+000468,op-splice,rep-32
+ tests/fuzzing-failures/id-000004,sig-11,src-000440+000369,op-splice,rep-2
+2 −0 tests/unit/.gitattributes
+22 −0 tests/unit/CMakeLists.txt
+77 −0 tests/unit/fuzz.c
+66 −0 tests/unit/test_fuzzfailures.c
+59 −29 tests/unit/test_modulefinder.c
+49 −1 tests/unit/test_value.c
+3 −0 tests/unit/tests.inc
+29 −0 tests/valgrind.txt
1 change: 1 addition & 0 deletions sentry-samples/sentry-samples-android/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/build
sentry-samples-android-keystore
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

27 changes: 27 additions & 0 deletions sentry-samples/sentry-samples-android/appcenter
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


# Usage
# ./appcenter androidBuildToolsVersion keyAlias keyPass appCenterApp appCenterDevice
# Sample
# ./appcenter 29.0.3 keyAlias keyPass denrase/Sentry-Android-Sample e669fa3b # Nexus 5 Andorid 11

# Create Debug APK

../../gradlew :sentry-samples:sentry-samples-android:clean
../../gradlew :sentry-samples:sentry-samples-android:assembleDebug

# Run Tests so Test APK is Built

../../gradlew :sentry-samples:sentry-samples-android:connectedAndroidTest

# Sign APK

~/Library/Android/sdk/build-tools/$1/apksigner sign --ks sentry-samples-android-keystore --ks-pass pass:$2 --key-pass pass:$3 --in build/outputs/apk/debug/sentry-samples-android-debug.apk --out build/outputs/apk/debug/sentry-samples-android-debug.apk

# Sign Test APK

~/Library/Android/sdk/build-tools/$1/apksigner sign --ks sentry-samples-android-keystore --ks-pass pass:$2 --key-pass pass:$3 --in build/outputs/apk/androidTest/debug/sentry-samples-android-debug-androidTest.apk --out build/outputs/apk/androidTest/debug/sentry-samples-android-debug-androidTest.apk

# Upload to AppCenter

appcenter test run espresso --app "$4" --devices $5 --app-path build/outputs/apk/debug/sentry-samples-android-debug.apk --test-series "master" --locale "en_US" --build-dir build/outputs/apk/androidTest/debug
11 changes: 11 additions & 0 deletions sentry-samples/sentry-samples-android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ android {
ndk {
abiFilters.addAll(Config.Android.abiFilters)
}

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

buildFeatures {
Expand Down Expand Up @@ -109,4 +111,13 @@ dependencies {
implementation(Config.Libs.retrofit2Gson)

debugImplementation(Config.Libs.leakCanary)

androidTestImplementation(Config.TestLibs.androidxRunner)
androidTestImplementation(Config.TestLibs.androidxJunit)

androidTestImplementation("androidx.test.espresso:espresso-core:3.3.0")
androidTestImplementation("com.android.support.test.uiautomator:uiautomator-v18:2.1.3")

androidTestImplementation("com.microsoft.appcenter:espresso-test-extension:1.4")

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package io.sentry.samples.android

import android.support.test.uiautomator.UiDevice
import android.support.test.uiautomator.UiSelector
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.scrollTo
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.platform.app.InstrumentationRegistry
import com.microsoft.appcenter.espresso.Factory
import com.microsoft.appcenter.espresso.ReportHelper
import org.junit.Rule
import org.junit.Test

class MainActivityTest {

@get:Rule
var activityRule: ActivityScenarioRule<MainActivity>
= ActivityScenarioRule(MainActivity::class.java)

@get:Rule
val reportHelper: ReportHelper = Factory.getReportHelper()

// Tests are run in alphabetical order...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to be sure that they don't run in parallel


// We crash in a service to test if an envelope was created.
@Test
fun a_initSdkAndCrash() {
reportHelper.label("initSdkAndCrash")
onView(withId(R.id.native_crash)).perform(scrollTo(), click())
Thread.sleep(10000)

// Close either app or android dialog

val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
val okButton = mDevice.findObject(UiSelector().text("OK"))
val closeAppButton = mDevice.findObject(UiSelector().text("Close app"))
val allowButton = mDevice.findObject(UiSelector().text("OK"))
when {
okButton.exists() -> {
okButton.click()
}
closeAppButton.exists() -> {
closeAppButton.click()
}
allowButton.exists() -> {
allowButton.click()
}
else -> {
mDevice.pressBack()
}
}
}

// Check if envelope file is here.
@Test
fun b_checkIfFileExists() {

val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
val okButton = mDevice.findObject(UiSelector().text("OK"))
val closeAppButton = mDevice.findObject(UiSelector().text("Close app"))
val allowButton = mDevice.findObject(UiSelector().text("OK"))
when {
okButton.exists() -> {
okButton.click()
}
closeAppButton.exists() -> {
closeAppButton.click()
}
allowButton.exists() -> {
allowButton.click()
}
}

onView(withId(R.id.button_copy_file)).perform(click())
onView(withId(R.id.text_view_copy_file))
.check(matches(withText("SUCCESS")))

reportHelper.label("checkIfFileExists")
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme"
android:allowNativeHeapPointerTagging="false"
android:extractNativeLibs="true"
tools:ignore="GoogleAppIndexingWarning, UnusedAttribute">

<activity android:name=".MainActivity">
Expand All @@ -35,9 +34,10 @@

<activity android:name=".SecondActivity" />

<!-- NOTE: Replace the test DSN below with YOUR OWN DSN to see the events from this app in your Sentry project/dashboard-->
<!-- NOTE: Replace the test DSN below with YOUR OWN DSN to see the events from this app in your Sentry project/dashboard-->
<meta-data android:name="io.sentry.dsn" android:value="https://1053864c67cc410aa1ffc9701bd6f93d@o447951.ingest.sentry.io/5428559" />
denrase marked this conversation as resolved.
Show resolved Hide resolved

<meta-data android:name="io.sentry.auto-init" android:value="false" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's create a new sample instead of using sentry-samples-android, otherwise, the current sample is totally broken
we could call it sentry-samples-android-e2e or something like that

<!-- how to enable Sentry's debug mode-->
<meta-data android:name="io.sentry.debug" android:value="${sentryDebug}" />

Expand Down Expand Up @@ -101,5 +101,10 @@
<!-- how to disable the app components breadcrumbs integration-->
<!-- <meta-data android:name="io.sentry.breadcrumbs.app-components" android:value="false" />-->

<service
android:name=".NativeCrashService"
android:process=":externalProcess">
</service>

</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
package io.sentry.samples.android;

import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.Bundle;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import io.sentry.Attachment;
import io.sentry.ISpan;
import io.sentry.Sentry;
import io.sentry.SpanStatus;
import io.sentry.UserFeedback;
import io.sentry.android.core.SentryAndroid;
import io.sentry.protocol.SentryId;
import io.sentry.protocol.User;
import io.sentry.samples.android.databinding.ActivityMainBinding;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Calendar;
import java.util.Collections;
import java.util.Locale;
Expand Down Expand Up @@ -51,6 +63,11 @@ protected void onCreate(Bundle savedInstanceState) {
scope.addAttachment(image);
});

binding.buttonCopyFile.setOnClickListener( view -> {
boolean success = moveNativeCrashEnvelopeFile();
binding.textViewCopyFile.setText(success ? "SUCCESS" : "FAILED");
});

binding.crashFromJava.setOnClickListener(
view -> {
throw new RuntimeException("Uncaught Exception from Java.");
Expand Down Expand Up @@ -129,7 +146,11 @@ protected void onCreate(Bundle savedInstanceState) {
Sentry.setUser(user);
});

binding.nativeCrash.setOnClickListener(view -> NativeSample.crash());
binding.nativeCrash.setOnClickListener(view -> {
Intent intent = new Intent(this, NativeCrashService.class);
intent.putExtra("FOOBAR", "FOO");
startService(intent);
});

binding.nativeCapture.setOnClickListener(view -> NativeSample.message());

Expand Down Expand Up @@ -159,6 +180,44 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(binding.getRoot());
}

boolean moveNativeCrashEnvelopeFile() {
File source = nativeCrashEnvelopeFileSource();
File target = nativeCrashEnvelopeFileTarget();
try {
copy(source, target);
return target.exists();
} catch (Exception exception) {
return false;
}
}

File nativeCrashEnvelopeFileTarget() {
return new File(this.getCacheDir(), "android-native-crash.envelope");
}

@Nullable
File nativeCrashEnvelopeFileSource() {
try {
File hiddenFolder = new File(this.getCacheDir(), "/sentry/.sentry-native");
return hiddenFolder.listFiles()[0];
} catch (Exception exception) {
return null;
}
}

private static void copy(File src, File dest) throws IOException {
try (InputStream is = new FileInputStream(src); OutputStream os = new FileOutputStream(dest)) {

// buffer size 1K
byte[] buf = new byte[1024];

int bytesRead;
while ((bytesRead = is.read(buf)) > 0) {
os.write(buf, 0, bytesRead);
}
}
}

@Override
protected void onResume() {
super.onResume();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.sentry.samples.android

import android.app.Service
import android.content.Intent
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.util.Log
import io.sentry.android.core.SentryAndroid
import java.io.File

class NativeCrashService : Service() {

override fun onBind(p0: Intent?): IBinder? {
return null
}

override fun onStart(intent: Intent?, startId: Int) {
handleStart()
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
handleStart()
return START_NOT_STICKY
}

private fun handleStart() {
SentryAndroid.init(this) {
//
}

// Dispatch async so method, and therefore START_NOT_STICKY, can return.
val handler = Handler()
val mainHandler = Handler(Looper.getMainLooper())
mainHandler.post {
handler.post {
NativeSample.crash()
}
}
}
}
Loading