-
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add sentry integration & e2e tests (#78)
* poc * poc for integration test * add Sentry integration test * setup basic e2e test for jvm and android * add working e2e test without auth token * use real dsn for e2e test * change e2e test names * add elvis operator for auth token * add env secret to build * embed SENTRY_AUTH_TOKEN and add docs why apple e2e tests are disabled for now * use SENTRY_AUTH_TOKEN instead of AUTH_TOKEN * remove unused code * fix typo * remove resources * remove unused code * revert code * add auth token assert with message * refactor deps to buildSrc * add more serializable fields * use darwing ktor client * improve fakeDsn and test * omit roboelectric config * add improvements
- Loading branch information
Showing
12 changed files
with
479 additions
and
2 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
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
15 changes: 15 additions & 0 deletions
15
...multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt
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 |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package io.sentry.kotlin.multiplatform | ||
|
||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import androidx.test.platform.app.InstrumentationRegistry | ||
import org.junit.runner.RunWith | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
actual abstract class BaseSentryTest { | ||
actual val platform: String = "Android" | ||
actual val authToken: String? = System.getenv("SENTRY_AUTH_TOKEN") | ||
actual fun sentryInit(optionsConfiguration: OptionsConfiguration) { | ||
val context = InstrumentationRegistry.getInstrumentation().targetContext | ||
Sentry.init(context, optionsConfiguration) | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
...multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt
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 |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package io.sentry.kotlin.multiplatform | ||
|
||
actual abstract class BaseSentryTest { | ||
actual val platform: String = "Apple" | ||
actual val authToken: String? = "fake-auth-token" | ||
actual fun sentryInit(optionsConfiguration: OptionsConfiguration) { | ||
Sentry.init(optionsConfiguration) | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
...tlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt
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 |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package io.sentry.kotlin.multiplatform | ||
|
||
expect abstract class BaseSentryTest() { | ||
val platform: String | ||
val authToken: String? | ||
fun sentryInit(optionsConfiguration: OptionsConfiguration) | ||
} |
129 changes: 129 additions & 0 deletions
129
...otlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryE2ETest.kt
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 |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package io.sentry.kotlin.multiplatform | ||
|
||
import io.ktor.client.HttpClient | ||
import io.ktor.client.request.get | ||
import io.ktor.client.request.headers | ||
import io.ktor.client.statement.bodyAsText | ||
import io.ktor.http.HttpHeaders | ||
import io.sentry.kotlin.multiplatform.utils.org | ||
import io.sentry.kotlin.multiplatform.utils.projectSlug | ||
import io.sentry.kotlin.multiplatform.utils.realDsn | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.delay | ||
import kotlinx.coroutines.test.runTest | ||
import kotlinx.coroutines.withContext | ||
import kotlinx.serialization.Serializable | ||
import kotlinx.serialization.decodeFromString | ||
import kotlinx.serialization.json.Json | ||
import kotlin.test.AfterTest | ||
import kotlin.test.BeforeTest | ||
import kotlin.test.Test | ||
import kotlin.test.assertEquals | ||
import kotlin.test.assertFalse | ||
import kotlin.test.assertNotNull | ||
import kotlin.test.assertTrue | ||
import kotlin.time.Duration.Companion.seconds | ||
|
||
@Serializable | ||
private data class SentryEventSerializable( | ||
val id: String? = null, | ||
val project: Long? = null, | ||
val release: String? = null, | ||
val platform: String? = null, | ||
val message: String? = "", | ||
val tags: List<Map<String, String>> = listOf(), | ||
val fingerprint: List<String> = listOf(), | ||
val level: String? = null, | ||
val logger: String? = null, | ||
val title: String? = null | ||
) | ||
|
||
class SentryE2ETest : BaseSentryTest() { | ||
private val client = HttpClient() | ||
private val jsonDecoder = Json { ignoreUnknownKeys = true } | ||
private var sentEvent: SentryEvent? = null | ||
|
||
@BeforeTest | ||
fun setup() { | ||
assertNotNull(authToken) | ||
assertTrue(authToken.isNotEmpty()) | ||
sentryInit { options -> | ||
options.dsn = realDsn | ||
options.beforeSend = { event -> | ||
sentEvent = event | ||
event | ||
} | ||
} | ||
} | ||
|
||
private suspend fun fetchEvent(eventId: String): String { | ||
val url = | ||
"https://sentry.io/api/0/projects/$org/$projectSlug/events/$eventId/" | ||
val response = client.get(url) { | ||
headers { | ||
append( | ||
HttpHeaders.Authorization, | ||
"Bearer $authToken" | ||
) | ||
} | ||
} | ||
return response.bodyAsText() | ||
} | ||
|
||
private suspend fun waitForEventRetrieval(eventId: String): SentryEventSerializable { | ||
var json = "" | ||
val result: SentryEventSerializable = withContext(Dispatchers.Default) { | ||
while (json.isEmpty() || json.contains("Event not found")) { | ||
delay(5000) | ||
json = fetchEvent(eventId) | ||
assertFalse(json.contains("Invalid token"), "Invalid auth token") | ||
} | ||
jsonDecoder.decodeFromString(json) | ||
} | ||
return result | ||
} | ||
|
||
// TODO: e2e tests are currently disabled for Apple targets as there are SSL issues that prevent sending events in tests | ||
// See: https://github.com/getsentry/sentry-kotlin-multiplatform/issues/17 | ||
|
||
@Test | ||
fun `capture message and fetch event from Sentry`() = runTest(timeout = 30.seconds) { | ||
if (platform != "Apple") { | ||
val message = "Test running on $platform" | ||
val eventId = Sentry.captureMessage(message) | ||
val fetchedEvent = waitForEventRetrieval(eventId.toString()) | ||
fetchedEvent.tags.forEach { println(it["value"]) } | ||
assertEquals(eventId.toString(), fetchedEvent.id) | ||
assertEquals(sentEvent?.message?.formatted, fetchedEvent.message) | ||
assertEquals(message, fetchedEvent.title) | ||
assertEquals(sentEvent?.release, fetchedEvent.release) | ||
assertEquals(2, fetchedEvent.tags.find { it["value"] == sentEvent?.environment }?.size) | ||
assertEquals(sentEvent?.fingerprint?.toList(), fetchedEvent.fingerprint) | ||
assertEquals(2, fetchedEvent.tags.find { it["value"] == sentEvent?.level?.name?.lowercase() }?.size) | ||
assertEquals(sentEvent?.logger, fetchedEvent.logger) | ||
} | ||
} | ||
|
||
@Test | ||
fun `capture exception and fetch event from Sentry`() = runTest(timeout = 30.seconds) { | ||
if (platform != "Apple") { | ||
val exceptionMessage = "Test exception on platform $platform" | ||
val eventId = | ||
Sentry.captureException(IllegalArgumentException(exceptionMessage)) | ||
val fetchedEvent = waitForEventRetrieval(eventId.toString()) | ||
assertEquals(eventId.toString(), fetchedEvent.id) | ||
assertEquals("IllegalArgumentException: $exceptionMessage", fetchedEvent.title) | ||
assertEquals(sentEvent?.release, fetchedEvent.release) | ||
assertEquals(2, fetchedEvent.tags.find { it["value"] == sentEvent?.environment }?.size) | ||
assertEquals(sentEvent?.fingerprint?.toList(), fetchedEvent.fingerprint) | ||
assertEquals(2, fetchedEvent.tags.find { it["value"] == SentryLevel.ERROR.toString().lowercase() }?.size) | ||
assertEquals(sentEvent?.logger, fetchedEvent.logger) | ||
} | ||
} | ||
|
||
@AfterTest | ||
fun tearDown() { | ||
sentEvent = null | ||
Sentry.close() | ||
} | ||
} |
Oops, something went wrong.