-
-
Notifications
You must be signed in to change notification settings - Fork 443
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
CI: performance impact measurements #2171
Changes from all commits
466d695
be814f5
5de4fcc
3fe51dc
cca02ea
3693a71
93eaf86
dcc86bf
08839af
7413898
d7cb38a
1f2973f
d1f36f7
31259c1
99650f9
b2f337f
d935121
4954245
f4850c6
891f3ee
b4639f5
8b3a72d
facd582
98915c9
88c8e74
5a19276
8c296ef
a6ee6c0
732174d
fdd1386
6a814a7
f557687
b69b9ac
39d3ad0
e49d9ca
e782e80
0163d1c
a10f433
973b876
fdfe700
5793888
01ab854
bd43723
47faa49
acea7c9
95d5c39
7a62adf
86aa314
add51e8
6875b2d
6a3e607
7fc951f
639a9e8
634cdb2
316b5f3
153e2f2
8d31406
bbeb60d
5e9c63a
935e208
9e63c21
f6723f6
3f8cf60
a43974f
ffeb2a5
0e00c1a
da971d2
059f3ea
f40bb1a
fde4c27
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Android performance-impact and integration tests | ||
|
||
* [Sample app without sentry](./test-app-plain) created with Android Studio -> New Project -> Basic Activity | ||
* [Same app, but with Sentry included](./test-app-sentry) - made part of the root project | ||
* [App metrics test specification (yaml)](./metrics-test.yml) | ||
* [Espresso-based benchmarks](./sentry-uitest-android-benchmark) - run within SauceLabs (see /.sauce/*.yml) | ||
* [Espresso-based UI tests](./sentry-uitest-android) - run within SauceLabs (see /.sauce/*.yml) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
apps: | ||
- name: io.sentry.java.tests.perf.appplain | ||
activity: MainActivity | ||
path: ./test-app-plain/build/outputs/apk/release/test-app-plain-release.apk | ||
- name: io.sentry.java.tests.perf.appsentry | ||
activity: MainActivity | ||
path: ./test-app-sentry/build/outputs/apk/release/test-app-sentry-release.apk | ||
|
||
startupTimeTest: | ||
runs: 50 | ||
diffMin: 0 | ||
diffMax: 150 | ||
|
||
binarySizeTest: | ||
diffMin: 500 KiB | ||
diffMax: 700 KiB |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
plugins { | ||
id("com.android.application") | ||
} | ||
|
||
android { | ||
compileSdk = Config.Android.compileSdkVersion | ||
|
||
defaultConfig { | ||
applicationId = "io.sentry.java.tests.perf.appplain" | ||
minSdk = Config.Android.minSdkVersionNdk | ||
targetSdk = Config.Android.targetSdkVersion | ||
versionCode = 1 | ||
versionName = "1.0" | ||
} | ||
|
||
buildTypes { | ||
getByName("release") { | ||
isMinifyEnabled = true | ||
signingConfig = signingConfigs.getByName("debug") // to be able to run release mode | ||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "benchmark-proguard-rules.pro") | ||
ndk { | ||
abiFilters.clear() | ||
abiFilters.add("arm64-v8a") | ||
} | ||
} | ||
} | ||
compileOptions { | ||
sourceCompatibility = JavaVersion.VERSION_1_8 | ||
targetCompatibility = JavaVersion.VERSION_1_8 | ||
} | ||
buildFeatures { | ||
viewBinding = true | ||
} | ||
signingConfigs { | ||
getByName("debug") { | ||
storeFile = rootProject.file("debug.keystore") | ||
storePassword = "android" | ||
keyAlias = "androiddebugkey" | ||
keyPassword = "android" | ||
} | ||
} | ||
|
||
variantFilter { | ||
if (Config.Android.shouldSkipDebugVariant(buildType.name)) { | ||
ignore = true | ||
} | ||
} | ||
} | ||
|
||
dependencies { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Sentry Android Core lib has the dependencies of:
But most if not all Apps also have them as well, what if we add those dependencies in the plain test so they are not counted for the diff in size? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, personally I'm not sure about that - you'd know better. Maybe we can try in a followup PR what's the difference? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sounds good, so we unblock this PR. |
||
implementation("androidx.appcompat:appcompat:1.3.0") | ||
implementation("com.google.android.material:material:1.4.0") | ||
implementation("androidx.constraintlayout:constraintlayout:2.0.4") | ||
implementation("androidx.navigation:navigation-fragment:2.3.5") | ||
implementation("androidx.navigation:navigation-ui:2.3.5") | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Add project specific ProGuard rules here. | ||
# You can control the set of applied configuration files using the | ||
# proguardFiles setting in build.gradle.kts. | ||
# | ||
# For more details, see | ||
# http://developer.android.com/guide/developing/tools/proguard.html | ||
|
||
# If your project uses WebView with JS, uncomment the following | ||
# and specify the fully qualified class name to the JavaScript interface | ||
# class: | ||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
# public *; | ||
#} | ||
|
||
# Uncomment this to preserve the line number information for | ||
# debugging stack traces. | ||
#-keepattributes SourceFile,LineNumberTable | ||
|
||
# If you keep the line number information, uncomment this to | ||
# hide the original source file name. | ||
#-renamesourcefileattribute SourceFile |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:tools="http://schemas.android.com/tools" | ||
package="io.sentry.java.tests.perf.appplain"> | ||
|
||
<application | ||
android:allowBackup="true" | ||
android:dataExtractionRules="@xml/data_extraction_rules" | ||
android:fullBackupContent="@xml/backup_rules" | ||
android:icon="@mipmap/ic_launcher" | ||
android:label="@string/app_name" | ||
android:roundIcon="@mipmap/ic_launcher_round" | ||
android:supportsRtl="true" | ||
android:theme="@style/Theme.TestAppPlain" | ||
tools:targetApi="31"> | ||
<activity | ||
android:name=".MainActivity" | ||
android:exported="true" | ||
android:label="@string/app_name" | ||
android:theme="@style/Theme.TestAppPlain.NoActionBar"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN" /> | ||
|
||
<category android:name="android.intent.category.LAUNCHER" /> | ||
</intent-filter> | ||
</activity> | ||
</application> | ||
|
||
</manifest> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package io.sentry.java.tests.perf.appplain; | ||
|
||
import android.os.Bundle; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import androidx.annotation.NonNull; | ||
import androidx.fragment.app.Fragment; | ||
import androidx.navigation.fragment.NavHostFragment; | ||
import io.sentry.java.tests.perf.appplain.databinding.FragmentFirstBinding; | ||
|
||
public class FirstFragment extends Fragment { | ||
|
||
private FragmentFirstBinding binding; | ||
|
||
@Override | ||
public View onCreateView( | ||
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | ||
|
||
binding = FragmentFirstBinding.inflate(inflater, container, false); | ||
return binding.getRoot(); | ||
} | ||
|
||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { | ||
super.onViewCreated(view, savedInstanceState); | ||
|
||
binding.buttonFirst.setOnClickListener( | ||
new View.OnClickListener() { | ||
@Override | ||
public void onClick(View view) { | ||
NavHostFragment.findNavController(FirstFragment.this) | ||
.navigate(R.id.action_FirstFragment_to_SecondFragment); | ||
} | ||
}); | ||
} | ||
|
||
@Override | ||
public void onDestroyView() { | ||
super.onDestroyView(); | ||
binding = null; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package io.sentry.java.tests.perf.appplain; | ||
|
||
import android.os.Bundle; | ||
import android.view.Menu; | ||
import android.view.MenuItem; | ||
import android.view.View; | ||
import androidx.appcompat.app.AppCompatActivity; | ||
import androidx.navigation.NavController; | ||
import androidx.navigation.Navigation; | ||
import androidx.navigation.ui.AppBarConfiguration; | ||
import androidx.navigation.ui.NavigationUI; | ||
import com.google.android.material.snackbar.Snackbar; | ||
import io.sentry.java.tests.perf.appplain.databinding.ActivityMainBinding; | ||
|
||
public class MainActivity extends AppCompatActivity { | ||
|
||
private AppBarConfiguration appBarConfiguration; | ||
private ActivityMainBinding binding; | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
|
||
binding = ActivityMainBinding.inflate(getLayoutInflater()); | ||
setContentView(binding.getRoot()); | ||
|
||
setSupportActionBar(binding.toolbar); | ||
|
||
NavController navController = | ||
Navigation.findNavController(this, R.id.nav_host_fragment_content_main); | ||
appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build(); | ||
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); | ||
|
||
binding.fab.setOnClickListener( | ||
new View.OnClickListener() { | ||
@Override | ||
public void onClick(View view) { | ||
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) | ||
.setAction("Action", null) | ||
.show(); | ||
} | ||
}); | ||
} | ||
|
||
@Override | ||
public boolean onCreateOptionsMenu(Menu menu) { | ||
// Inflate the menu; this adds items to the action bar if it is present. | ||
getMenuInflater().inflate(R.menu.menu_main, menu); | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean onOptionsItemSelected(MenuItem item) { | ||
// Handle action bar item clicks here. The action bar will | ||
// automatically handle clicks on the Home/Up button, so long | ||
// as you specify a parent activity in AndroidManifest.xml. | ||
int id = item.getItemId(); | ||
|
||
//noinspection SimplifiableIfStatement | ||
if (id == R.id.action_settings) { | ||
return true; | ||
} | ||
|
||
return super.onOptionsItemSelected(item); | ||
} | ||
|
||
@Override | ||
public boolean onSupportNavigateUp() { | ||
NavController navController = | ||
Navigation.findNavController(this, R.id.nav_host_fragment_content_main); | ||
return NavigationUI.navigateUp(navController, appBarConfiguration) | ||
|| super.onSupportNavigateUp(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package io.sentry.java.tests.perf.appplain; | ||
|
||
import android.os.Bundle; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import androidx.annotation.NonNull; | ||
import androidx.fragment.app.Fragment; | ||
import androidx.navigation.fragment.NavHostFragment; | ||
import io.sentry.java.tests.perf.appplain.databinding.FragmentSecondBinding; | ||
|
||
public class SecondFragment extends Fragment { | ||
|
||
private FragmentSecondBinding binding; | ||
|
||
@Override | ||
public View onCreateView( | ||
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | ||
|
||
binding = FragmentSecondBinding.inflate(inflater, container, false); | ||
return binding.getRoot(); | ||
} | ||
|
||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { | ||
super.onViewCreated(view, savedInstanceState); | ||
|
||
binding.buttonSecond.setOnClickListener( | ||
new View.OnClickListener() { | ||
@Override | ||
public void onClick(View view) { | ||
NavHostFragment.findNavController(SecondFragment.this) | ||
.navigate(R.id.action_SecondFragment_to_FirstFragment); | ||
} | ||
}); | ||
} | ||
|
||
@Override | ||
public void onDestroyView() { | ||
super.onDestroyView(); | ||
binding = null; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd avoid using
'**/sentry-android-integration-tests/**'
, since we don't want to run benchmarks if we only add a ui tests (the modulesentry-android-integration-tests/sentry-uitest-android
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess changes in
uitest
alone are so infrequent (to provide any benefit) that it doesn't make that much sense, considering we would need to explicitly white list the other 4 subdirectories instead?