Skip to content

Commit

Permalink
Merge pull request #1679 from bugsnag/PLAT-8390-concurrency
Browse files Browse the repository at this point in the history
Fixed concurrency bug that could be triggered via the React Native plugin
  • Loading branch information
kstenerud authored May 11, 2022
2 parents 28359da + a29c9d4 commit 9e1da59
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

### Bug fixes

* Fixed concurrency bug that could be triggered via the React Native plugin
[#1679](https://github.com/bugsnag/bugsnag-android/pull/1679)
* Correctly report `device.locationStatus` on Android 12 onwards using `LocationManager.isLocationEnabled`
[1683](https://github.com/bugsnag/bugsnag-android/pull/1683)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.bugsnag.android

import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.mockito.junit.MockitoJUnitRunner
import java.io.File
import kotlin.concurrent.thread

@RunWith(MockitoJUnitRunner::class)
class DataCollectorTest {

@Ignore("Disabled until we're able to mock final classes or auto-open classes")
@Test
fun testConcurretAccess() {
val res = Mockito.mock(Resources::class.java)
Mockito.`when`(res.configuration).thenReturn(Configuration())

val collector = DeviceDataCollector(
Mockito.mock(Connectivity::class.java),
Mockito.mock(Context::class.java),
res,
"fakeDevice",
Mockito.mock(DeviceBuildInfo::class.java),
File("/tmp/javatest"),
Mockito.mock(RootDetector::class.java),
Mockito.mock(BackgroundTaskService::class.java),
Mockito.mock(Logger::class.java)
)

repeat(10) { index ->
collector.addRuntimeVersionInfo("key" + index, "value" + index)
}

val count = 500

thread {
repeat(count) { index ->
collector.addRuntimeVersionInfo("key" + index, "value" + index)
}
}

repeat(count) {
collector.generateDevice()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ internal class DeviceDataCollector(
private val screenResolution = getScreenResolution()
private val locale = Locale.getDefault().toString()
private val cpuAbi = getCpuAbi()
private val runtimeVersions: MutableMap<String, Any>
private var runtimeVersions: MutableMap<String, Any>
private val rootedFuture: Future<Boolean>?
private val totalMemoryFuture: Future<Long?>? = retrieveTotalDeviceMemory()
private var orientation = AtomicInteger(resources.configuration.orientation)
Expand Down Expand Up @@ -297,6 +297,9 @@ internal class DeviceDataCollector(
}

fun addRuntimeVersionInfo(key: String, value: String) {
runtimeVersions[key] = value
// Use copy-on-write to avoid a ConcurrentModificationException in generateDeviceWithState
val newRuntimeVersions = runtimeVersions.toMutableMap()
newRuntimeVersions[key] = value
runtimeVersions = newRuntimeVersions
}
}

0 comments on commit 9e1da59

Please sign in to comment.