Skip to content

Commit e993340

Browse files
committed
Updating android tests
1 parent d3e1be9 commit e993340

File tree

4 files changed

+163
-6
lines changed

4 files changed

+163
-6
lines changed

platform/jvm/capture/src/test/kotlin/io/bitdrift/capture/CaptureTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class CaptureTest {
117117
whenever(appExitInfo.reason).thenReturn(ApplicationExitInfo.REASON_CRASH)
118118
val provider = ILatestAppExitInfoProvider { LatestAppExitReasonResult.Valid(appExitInfo) }
119119

120-
val previousRunInfo = PreviousRunInfoResolver(".", provider).get(activityManager)
120+
val previousRunInfo = PreviousRunInfoResolver(mock(), provider).get(activityManager)
121121

122122
assertThat(previousRunInfo).isEqualTo(
123123
PreviousRunInfo(hasFatallyTerminated = true, reason = ExitReason.JvmCrash),
@@ -132,7 +132,7 @@ class CaptureTest {
132132
whenever(appExitInfo.reason).thenReturn(ApplicationExitInfo.REASON_EXIT_SELF)
133133
val provider = ILatestAppExitInfoProvider { LatestAppExitReasonResult.Valid(appExitInfo) }
134134

135-
val previousRunInfo = PreviousRunInfoResolver(".", provider).get(activityManager)
135+
val previousRunInfo = PreviousRunInfoResolver(mock(), provider).get(activityManager)
136136

137137
assertThat(previousRunInfo).isEqualTo(
138138
PreviousRunInfo(hasFatallyTerminated = false, reason = ExitReason.ExitSelf),
@@ -145,7 +145,7 @@ class CaptureTest {
145145
val activityManager: ActivityManager = mock()
146146
val provider = ILatestAppExitInfoProvider { LatestAppExitReasonResult.None }
147147

148-
val previousRunInfo = PreviousRunInfoResolver(".", provider).get(activityManager)
148+
val previousRunInfo = PreviousRunInfoResolver(mock(), provider).get(activityManager)
149149

150150
assertThat(previousRunInfo).isEqualTo(PreviousRunInfo(hasFatallyTerminated = false, reason = null))
151151
}
@@ -162,7 +162,7 @@ class CaptureTest {
162162
)
163163
}
164164

165-
val previousRunInfo = PreviousRunInfoResolver(".", provider).get(activityManager)
165+
val previousRunInfo = PreviousRunInfoResolver(mock(), provider).get(activityManager)
166166

167167
assertThat(previousRunInfo).isNull()
168168
}

platform/jvm/capture/src/test/kotlin/io/bitdrift/capture/events/lifecycle/AppExitLoggerTest.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import io.bitdrift.capture.providers.ArrayFields
3434
import io.bitdrift.capture.providers.combineFields
3535
import io.bitdrift.capture.providers.fieldsOf
3636
import io.bitdrift.capture.reports.IssueReporterState
37+
import io.bitdrift.capture.reports.exitinfo.IPreviousRunInfoResolver
3738
import io.bitdrift.capture.reports.exitinfo.LatestAppExitInfoProvider.EXIT_REASON_EXCEPTION_MESSAGE
3839
import io.bitdrift.capture.reports.jvmcrash.ICaptureUncaughtExceptionHandler
3940
import io.bitdrift.capture.utils.BuildVersionChecker
@@ -49,6 +50,7 @@ class AppExitLoggerTest {
4950
private val runtime: Runtime = mock()
5051
private val versionChecker: BuildVersionChecker = mock()
5152
private val captureUncaughtExceptionHandler: ICaptureUncaughtExceptionHandler = mock()
53+
private val previousRunInfoResolver: IPreviousRunInfoResolver = mock()
5254
private val memoryMetricsProvider = FakeMemoryMetricsProvider()
5355
private val lastExitInfo = FakeLatestAppExitInfoProvider()
5456

@@ -201,6 +203,22 @@ class AppExitLoggerTest {
201203
verify(logger).flush(true)
202204
}
203205

206+
@Test
207+
fun onJvmCrash_shouldCallPersistJvmCrashState() {
208+
appExitLogger.onJvmCrash(Thread.currentThread(), RuntimeException("crash"))
209+
210+
verify(previousRunInfoResolver).persistJvmCrashState()
211+
}
212+
213+
@Test
214+
fun onJvmCrash_whenBuiltInFatalIssueMechanism_shouldNotCallPersistJvmCrashState() {
215+
val appExitLogger = buildAppExitLogger(IssueReporterState.Initialized)
216+
217+
appExitLogger.onJvmCrash(Thread.currentThread(), RuntimeException("crash"))
218+
219+
verify(previousRunInfoResolver, never()).persistJvmCrashState()
220+
}
221+
204222
@Test
205223
fun onJvmCrash_whenBuiltInFatalIssueMechanism_shouldNotSendAppExitCrashLog() {
206224
val appExitLogger = buildAppExitLogger(IssueReporterState.Initialized)
@@ -303,6 +321,7 @@ class AppExitLoggerTest {
303321
lastExitInfo,
304322
captureUncaughtExceptionHandler,
305323
FakeIssueReporter(fatalReporterInitState),
324+
previousRunInfoResolver,
306325
)
307326

308327
private fun fieldsMatchExpectedAnr(arrayFields: ArrayFields): Boolean {

platform/jvm/capture/src/test/kotlin/io/bitdrift/capture/reports/IssueReporterTest.kt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import io.bitdrift.capture.attributes.ClientAttributes
2323
import io.bitdrift.capture.fakes.FakeBackgroundThreadHandler
2424
import io.bitdrift.capture.fakes.FakeDateProvider
2525
import io.bitdrift.capture.reports.exitinfo.ILatestAppExitInfoProvider
26-
import io.bitdrift.capture.reports.exitinfo.PreviousRunInfoResolver
26+
import io.bitdrift.capture.reports.exitinfo.IPreviousRunInfoResolver
2727
import io.bitdrift.capture.reports.jvmcrash.ICaptureUncaughtExceptionHandler
2828
import io.bitdrift.capture.reports.processor.ICompletedReportsProcessor
2929
import io.bitdrift.capture.reports.processor.IssueReporterProcessor
@@ -54,6 +54,8 @@ class IssueReporterTest {
5454

5555
private val latestAppExitInfoProvider: ILatestAppExitInfoProvider = mock()
5656

57+
private val previousRunInfoResolver: IPreviousRunInfoResolver = mock()
58+
5759
private val internalLogger: IInternalLogger = mock()
5860
private val appContext = ApplicationProvider.getApplicationContext<Context>()
5961
private val clientAttributes = ClientAttributes(appContext, lifecycleOwner)
@@ -215,6 +217,20 @@ class IssueReporterTest {
215217
assertThat(processor).isNull()
216218
}
217219

220+
@Test
221+
fun onJvmCrash_shouldCallPersistJvmCrashState() {
222+
issueReporter.init(
223+
activityManager,
224+
sdkDirectory,
225+
clientAttributes,
226+
completedReportsProcessor,
227+
)
228+
229+
issueReporter.onJvmCrash(Thread.currentThread(), RuntimeException("test crash"))
230+
231+
verify(previousRunInfoResolver).persistJvmCrashState()
232+
}
233+
218234
private fun assertCrashFile(crashFileExist: Boolean) {
219235
val crashFile = File(reportsDir, "/new/latest_crash_info.json")
220236
assertThat(crashFile.exists()).isEqualTo(crashFileExist)
@@ -225,7 +241,7 @@ class IssueReporterTest {
225241
internalLogger = internalLogger,
226242
backgroundThreadHandler = FakeBackgroundThreadHandler(),
227243
latestAppExitInfoProvider = latestAppExitInfoProvider,
228-
previousRunInfoResolver = PreviousRunInfoResolver(sdkDirectory),
244+
previousRunInfoResolver = previousRunInfoResolver,
229245
captureUncaughtExceptionHandler = captureUncaughtExceptionHandler,
230246
dateProvider = FakeDateProvider,
231247
)
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// capture-sdk - bitdrift's client SDK
2+
// Copyright Bitdrift, Inc. All rights reserved.
3+
//
4+
// Use of this source code is governed by a source available license that can be found in the
5+
// LICENSE file or at:
6+
// https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt
7+
8+
package io.bitdrift.capture.reports.exitinfo
9+
10+
import android.app.ActivityManager
11+
import com.nhaarman.mockitokotlin2.any
12+
import com.nhaarman.mockitokotlin2.eq
13+
import com.nhaarman.mockitokotlin2.mock
14+
import com.nhaarman.mockitokotlin2.never
15+
import com.nhaarman.mockitokotlin2.verify
16+
import io.bitdrift.capture.IInternalLogger
17+
import org.assertj.core.api.Assertions.assertThat
18+
import org.junit.Before
19+
import org.junit.Rule
20+
import org.junit.Test
21+
import org.junit.rules.TemporaryFolder
22+
import org.junit.runner.RunWith
23+
import org.robolectric.RobolectricTestRunner
24+
import org.robolectric.annotation.Config
25+
26+
@RunWith(RobolectricTestRunner::class)
27+
@Config(sdk = [24])
28+
class PreviousRunInfoResolverTest {
29+
@get:Rule
30+
val tempFolder = TemporaryFolder()
31+
32+
private val internalLogger: IInternalLogger = mock()
33+
private val activityManager: ActivityManager = mock()
34+
private lateinit var resolver: PreviousRunInfoResolver
35+
36+
@Before
37+
fun setUp() {
38+
resolver = PreviousRunInfoResolver(internalLogger)
39+
}
40+
41+
@Test
42+
fun initLegacyWatcher_whenNoStateFile_returnsNoCrash() {
43+
resolver.initLegacyWatcher(tempFolder.root.absolutePath)
44+
45+
val result = resolver.get(activityManager)
46+
47+
assertThat(result).isNull()
48+
}
49+
50+
@Test
51+
fun get_afterPersistJvmCrashState_returnsCrashOnNextInit() {
52+
val sdkDir = tempFolder.root.absolutePath
53+
54+
resolver.initLegacyWatcher(sdkDir)
55+
resolver.persistJvmCrashState()
56+
57+
val nextRunResolver = PreviousRunInfoResolver(internalLogger)
58+
nextRunResolver.initLegacyWatcher(sdkDir)
59+
val result = nextRunResolver.get(activityManager)
60+
61+
assertThat(result).isEqualTo(
62+
PreviousRunInfo(hasFatallyTerminated = true, reason = ExitReason.JvmCrash),
63+
)
64+
}
65+
66+
@Test
67+
fun initLegacyWatcher_resetsStateForCurrentRun() {
68+
val sdkDir = tempFolder.root.absolutePath
69+
70+
resolver.initLegacyWatcher(sdkDir)
71+
resolver.persistJvmCrashState()
72+
73+
val secondResolver = PreviousRunInfoResolver(internalLogger)
74+
secondResolver.initLegacyWatcher(sdkDir)
75+
76+
val thirdResolver = PreviousRunInfoResolver(internalLogger)
77+
thirdResolver.initLegacyWatcher(sdkDir)
78+
val result = thirdResolver.get(activityManager)
79+
80+
assertThat(result).isEqualTo(
81+
PreviousRunInfo(hasFatallyTerminated = false),
82+
)
83+
}
84+
85+
@Test
86+
fun get_beforeInitLegacyWatcher_returnsNull() {
87+
val result = resolver.get(activityManager)
88+
89+
assertThat(result).isNull()
90+
}
91+
92+
@Test
93+
fun persistJvmCrashState_beforeInit_logsInternalError() {
94+
resolver.persistJvmCrashState()
95+
96+
verify(internalLogger).logInternalError(
97+
eq(null),
98+
eq(false),
99+
any(),
100+
)
101+
}
102+
103+
@Test
104+
@Config(sdk = [30])
105+
fun initLegacyWatcher_isNoopOnApi30() {
106+
val sdkDir = tempFolder.root.absolutePath
107+
resolver.initLegacyWatcher(sdkDir)
108+
109+
assertThat(tempFolder.root.resolve("reports/previous_run_info.state").exists()).isFalse()
110+
}
111+
112+
@Test
113+
@Config(sdk = [30])
114+
fun persistJvmCrashState_isNoopOnApi30() {
115+
val sdkDir = tempFolder.root.absolutePath
116+
resolver.initLegacyWatcher(sdkDir)
117+
resolver.persistJvmCrashState()
118+
119+
assertThat(tempFolder.root.resolve("reports/previous_run_info.state").exists()).isFalse()
120+
verify(internalLogger, never()).logInternalError(any(), any(), any())
121+
}
122+
}

0 commit comments

Comments
 (0)