-
-
Notifications
You must be signed in to change notification settings - Fork 243
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into ci/dart-only-metrics
- Loading branch information
Showing
34 changed files
with
460 additions
and
182 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
* @krystofwoldrich @stefanosiano @buenaflor @martinhaintz | ||
* @krystofwoldrich @stefanosiano @buenaflor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ on: | |
- "flutter/**" | ||
|
||
env: | ||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | ||
SENTRY_AUTH_TOKEN_E2E: ${{ secrets.SENTRY_AUTH_TOKEN_E2E }} | ||
|
||
jobs: | ||
cancel-previous-workflow: | ||
|
@@ -25,7 +25,7 @@ jobs: | |
access_token: ${{ github.token }} | ||
|
||
test-android: | ||
runs-on: macos-13 | ||
runs-on: ubuntu-latest | ||
timeout-minutes: 30 | ||
defaults: | ||
run: | ||
|
@@ -38,6 +38,12 @@ jobs: | |
- name: checkout | ||
uses: actions/checkout@v4 | ||
|
||
- name: Enable KVM group perms | ||
run: | | ||
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules | ||
sudo udevadm control --reload-rules | ||
sudo udevadm trigger --name-match=kvm | ||
- uses: actions/setup-java@v4 | ||
with: | ||
distribution: "adopt" | ||
|
@@ -56,28 +62,7 @@ jobs: | |
- name: Gradle cache | ||
uses: gradle/gradle-build-action@ac2d340dc04d9e1113182899e983b5400c17cda1 # [email protected] | ||
|
||
- name: AVD cache | ||
uses: actions/cache@v4 | ||
id: avd-cache | ||
with: | ||
path: | | ||
~/.android/avd/* | ||
~/.android/adb* | ||
key: avd-31 | ||
|
||
- name: create AVD and generate snapshot for caching | ||
if: steps.avd-cache.outputs.cache-hit != 'true' | ||
uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d #[email protected] | ||
with: | ||
working-directory: ./flutter/example | ||
api-level: 31 | ||
profile: Nexus 6 | ||
arch: x86_64 | ||
force-avd-creation: false | ||
avd-name: macOS-avd-x86_64-31 | ||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||
disable-animations: true | ||
script: echo 'Generated AVD snapshot for caching.' | ||
# TODO: fix emulator caching, in ubuntu-latest emulator won't boot: https://github.com/ReactiveCircus/android-emulator-runner/issues/278 | ||
|
||
- name: build apk | ||
working-directory: ./flutter/example/android | ||
|
@@ -91,8 +76,8 @@ jobs: | |
profile: Nexus 6 | ||
arch: x86_64 | ||
force-avd-creation: false | ||
avd-name: macOS-avd-x86_64-31 | ||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||
avd-name: avd-x86_64-31 | ||
emulator-options: -no-snapshot-save -no-window -accel on -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||
disable-animations: true | ||
script: ./gradlew testDebugUnitTest | ||
|
||
|
@@ -104,10 +89,23 @@ jobs: | |
profile: Nexus 6 | ||
arch: x86_64 | ||
force-avd-creation: false | ||
avd-name: macOS-avd-x86_64-31 | ||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||
avd-name: avd-x86_64-31 | ||
emulator-options: -no-snapshot-save -no-window -accel on -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||
disable-animations: true | ||
script: flutter test integration_test/all.dart --verbose | ||
script: flutter test integration_test/all.dart --dart-define SENTRY_AUTH_TOKEN_E2E=$SENTRY_AUTH_TOKEN_E2E --verbose | ||
|
||
- name: launch android emulator & run android integration test in profile mode | ||
uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d #[email protected] | ||
with: | ||
working-directory: ./flutter/example | ||
api-level: 31 | ||
profile: Nexus 6 | ||
arch: x86_64 | ||
force-avd-creation: false | ||
avd-name: avd-x86_64-31 | ||
emulator-options: -no-snapshot-save -no-window -accel on -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||
disable-animations: true | ||
script: flutter drive --driver=integration_test/test_driver/driver.dart --target=integration_test/sentry_widgets_flutter_binding_test.dart --profile -d emulator-5554 | ||
|
||
cocoa: | ||
name: "${{ matrix.target }} | ${{ matrix.sdk }}" | ||
|
@@ -158,7 +156,9 @@ jobs: | |
- name: run integration test | ||
# Disable flutter integration tests for iOS for now (https://github.com/getsentry/sentry-dart/issues/1605#issuecomment-1695809346) | ||
if: ${{ matrix.target != 'ios' }} | ||
run: flutter test -d "${{ steps.device.outputs.name }}" integration_test/all.dart --verbose | ||
run: | | ||
flutter test -d "${{ steps.device.outputs.name }}" integration_test/all.dart --dart-define SENTRY_AUTH_TOKEN_E2E=$SENTRY_AUTH_TOKEN_E2E --verbose | ||
flutter drive --driver=integration_test/test_driver/driver.dart --target=integration_test/sentry_widgets_flutter_binding_test.dart --profile -d "${{ steps.device.outputs.name }}" | ||
- name: run native test | ||
# We only have the native unit test package in the iOS xcodeproj at the moment. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,7 @@ jobs: | |
- uses: actions/checkout@v4 | ||
- uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff # [email protected] | ||
- run: xcodes select 15.0.1 | ||
- uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc # pin@v1.202.0 | ||
- uses: ruby/setup-ruby@401c19e14f474b54450cd3905bb8b86e2c8509cf # pin@v1.204.0 | ||
with: | ||
ruby-version: '2.7.5' | ||
bundler-cache: true | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,16 +7,19 @@ import 'dart:convert'; | |
import 'package:flutter/widgets.dart'; | ||
import 'package:flutter_test/flutter_test.dart'; | ||
import 'package:http/http.dart'; | ||
import 'package:integration_test/integration_test.dart'; | ||
import 'package:sentry_flutter/sentry_flutter.dart'; | ||
import 'package:sentry_flutter_example/main.dart'; | ||
|
||
import 'utils.dart'; | ||
|
||
void main() { | ||
// const org = 'sentry-sdks'; | ||
// const slug = 'sentry-flutter'; | ||
// const authToken = String.fromEnvironment('SENTRY_AUTH_TOKEN'); | ||
const org = 'sentry-sdks'; | ||
const slug = 'sentry-flutter'; | ||
const authToken = String.fromEnvironment('SENTRY_AUTH_TOKEN_E2E'); | ||
const fakeDsn = 'https://[email protected]/1234567'; | ||
|
||
TestWidgetsFlutterBinding.ensureInitialized(); | ||
IntegrationTestWidgetsFlutterBinding.ensureInitialized(); | ||
|
||
tearDown(() async { | ||
await Sentry.close(); | ||
|
@@ -98,7 +101,7 @@ void main() { | |
|
||
// ignore: deprecated_member_use_from_same_package | ||
// ignore: deprecated_member_use | ||
final associatedEventId = await Sentry.captureMessage("Associated"); | ||
final associatedEventId = await Sentry.captureMessage('Associated'); | ||
final feedback = SentryFeedback( | ||
message: 'message', | ||
contactEmail: '[email protected]', | ||
|
@@ -162,66 +165,76 @@ void main() { | |
await transaction.finish(); | ||
}); | ||
|
||
// group('e2e', () { | ||
// var output = find.byKey(const Key('output')); | ||
// late Fixture fixture; | ||
// | ||
// setUp(() { | ||
// fixture = Fixture(); | ||
// }); | ||
// | ||
// testWidgets('captureException', (tester) async { | ||
// await setupSentryAndApp(tester, | ||
// dsn: exampleDsn, beforeSendCallback: fixture.beforeSend); | ||
// | ||
// await tester.tap(find.text('captureException')); | ||
// await tester.pumpAndSettle(); | ||
// | ||
// final text = output.evaluate().single.widget as Text; | ||
// final id = text.data!; | ||
// | ||
// final uri = Uri.parse( | ||
// 'https://sentry.io/api/0/projects/$org/$slug/events/$id/', | ||
// ); | ||
// expect(authToken, isNotEmpty); | ||
// | ||
// final event = await fixture.poll(uri, authToken); | ||
// expect(event, isNotNull); | ||
// | ||
// final sentEvent = fixture.sentEvent; | ||
// expect(sentEvent, isNotNull); | ||
// | ||
// final tags = event!["tags"] as List<dynamic>; | ||
// | ||
// expect(sentEvent!.eventId.toString(), event["id"]); | ||
// expect("_Exception: Exception: captureException", event["title"]); | ||
// expect(sentEvent.release, event["release"]["version"]); | ||
// expect( | ||
// 2, | ||
// (tags.firstWhere((e) => e["value"] == sentEvent.environment) as Map) | ||
// .length); | ||
// expect(sentEvent.fingerprint, event["fingerprint"] ?? []); | ||
// expect( | ||
// 2, | ||
// (tags.firstWhere((e) => e["value"] == SentryLevel.error.name) as Map) | ||
// .length); | ||
// expect(sentEvent.logger, event["logger"]); | ||
// | ||
// final dist = tags.firstWhere((element) => element['key'] == 'dist'); | ||
// expect('1', dist['value']); | ||
// | ||
// final environment = | ||
// tags.firstWhere((element) => element['key'] == 'environment'); | ||
// expect('integration', environment['value']); | ||
// }); | ||
// }); | ||
group('e2e', () { | ||
var output = find.byKey(const Key('output')); | ||
late Fixture fixture; | ||
|
||
setUp(() { | ||
fixture = Fixture(); | ||
}); | ||
|
||
testWidgets('captureException', (tester) async { | ||
late Uri uri; | ||
|
||
await restoreFlutterOnErrorAfter(() async { | ||
await setupSentryAndApp(tester, | ||
dsn: exampleDsn, beforeSendCallback: fixture.beforeSend); | ||
|
||
await tester.tap(find.text('captureException')); | ||
await tester.pumpAndSettle(); | ||
|
||
final text = output.evaluate().single.widget as Text; | ||
final id = text.data!; | ||
|
||
uri = Uri.parse( | ||
'https://sentry.io/api/0/projects/$org/$slug/events/$id/', | ||
); | ||
}); | ||
|
||
expect(authToken, isNotEmpty); | ||
|
||
final event = await fixture.poll(uri, authToken); | ||
expect(event, isNotNull); | ||
|
||
final sentEvents = fixture.sentEvents | ||
.where((el) => el!.eventId.toString() == event!['id']); | ||
expect( | ||
sentEvents.length, 1); // one button click should only send one error | ||
final sentEvent = sentEvents.first; | ||
|
||
final tags = event!['tags'] as List<dynamic>; | ||
|
||
print('event id: ${event['id']}'); | ||
print('event title: ${event['title']}'); | ||
expect(sentEvent!.eventId.toString(), event['id']); | ||
expect('_Exception: Exception: captureException', event['title']); | ||
expect(sentEvent.release, event['release']['version']); | ||
expect( | ||
2, | ||
(tags.firstWhere((e) => e['value'] == sentEvent.environment) as Map) | ||
.length); | ||
expect(sentEvent.fingerprint, event['fingerprint'] ?? []); | ||
expect( | ||
2, | ||
(tags.firstWhere((e) => e['value'] == SentryLevel.error.name) as Map) | ||
.length); | ||
expect(sentEvent.logger, event['logger']); | ||
|
||
final dist = tags.firstWhere((element) => element['key'] == 'dist'); | ||
expect('1', dist['value']); | ||
|
||
final environment = | ||
tags.firstWhere((element) => element['key'] == 'environment'); | ||
expect('integration', environment['value']); | ||
}); | ||
}); | ||
} | ||
|
||
class Fixture { | ||
SentryEvent? sentEvent; | ||
List<SentryEvent?> sentEvents = []; | ||
|
||
FutureOr<SentryEvent?> beforeSend(SentryEvent event, Hint hint) async { | ||
sentEvent = event; | ||
sentEvents.add(event); | ||
return event; | ||
} | ||
|
||
|
@@ -237,16 +250,16 @@ class Fixture { | |
|
||
while (retries < maxRetries) { | ||
try { | ||
print("Trying to fetch $url [try $retries/$maxRetries]"); | ||
print('Trying to fetch $url [try $retries/$maxRetries]'); | ||
final response = await client.get( | ||
url, | ||
headers: <String, String>{'Authorization': 'Bearer $authToken'}, | ||
); | ||
print("Response status code: ${response.statusCode}"); | ||
print('Response status code: ${response.statusCode}'); | ||
if (response.statusCode == 200) { | ||
return jsonDecode(utf8.decode(response.bodyBytes)); | ||
} else if (response.statusCode == 401) { | ||
print("Cannot fetch $url - invalid auth token."); | ||
print('Cannot fetch $url - invalid auth token.'); | ||
break; | ||
} | ||
} catch (e) { | ||
|
Oops, something went wrong.