-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Stats collector; kotlin; mcumgr test mock framework (#65)
- Loading branch information
Showing
16 changed files
with
709 additions
and
65 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
#Mon Oct 01 11:43:39 CEST 2018 | ||
#Fri Feb 21 15:26:59 PST 2020 | ||
distributionBase=GRADLE_USER_HOME | ||
distributionPath=wrapper/dists | ||
zipStoreBase=GRADLE_USER_HOME | ||
zipStorePath=wrapper/dists | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip |
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,3 +1,3 @@ | ||
POM_ARTIFACT_ID=mcumgr-ble | ||
POM_NAME=McuManager Ble | ||
POM_PACKAGING=aar | ||
POM_PACKAGING=aar |
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
146 changes: 146 additions & 0 deletions
146
mcumgr-core/src/main/java/io/runtime/mcumgr/managers/meta/StatisticsCollector.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,146 @@ | ||
package io.runtime.mcumgr.managers.meta | ||
|
||
import io.runtime.mcumgr.McuMgrCallback | ||
import io.runtime.mcumgr.exception.McuMgrErrorException | ||
import io.runtime.mcumgr.exception.McuMgrException | ||
import io.runtime.mcumgr.managers.StatsManager | ||
import io.runtime.mcumgr.response.stat.McuMgrStatListResponse | ||
import io.runtime.mcumgr.response.stat.McuMgrStatResponse | ||
import java.util.concurrent.atomic.AtomicBoolean | ||
|
||
/** | ||
* Result of statistic collections. | ||
*/ | ||
sealed class StatCollectionResult { | ||
data class Success(val statistics: Map<String, Map<String, Long>>): StatCollectionResult() | ||
data class Cancelled(val statistics: Map<String, Map<String, Long>>): StatCollectionResult() | ||
data class Failure(val throwable: Throwable): StatCollectionResult() | ||
} | ||
|
||
/** | ||
* Callback for statistic collections. | ||
*/ | ||
typealias StatCollectionCallback = (StatCollectionResult) -> Unit | ||
|
||
/** | ||
* Non-blocking cancellable interface for cancelling an ongoing task. | ||
*/ | ||
interface Cancellable { | ||
fun cancel() | ||
} | ||
|
||
/** | ||
* Collects stats from a device. | ||
*/ | ||
class StatisticsCollector(private val statsManager: StatsManager) { | ||
|
||
/** | ||
* Collect stats from a single group by name. | ||
*/ | ||
fun collect(groupName: String, callback: StatCollectionCallback): Cancellable { | ||
return StatCollection(statsManager, callback).start(listOf(groupName)) | ||
} | ||
|
||
/** | ||
* Collect from a list of statistic group names. | ||
*/ | ||
fun collectGroups(groupNames: List<String>, callback: StatCollectionCallback): Cancellable { | ||
return StatCollection(statsManager, callback).start(groupNames) | ||
} | ||
|
||
/** | ||
* List the stat group names from the device and collect each which intersects with the filter. | ||
*/ | ||
fun collectAll(filter: Set<String>? = null, callback: StatCollectionCallback): Cancellable { | ||
val collection = StatCollection(statsManager, callback) | ||
statsManager.list(object: McuMgrCallback<McuMgrStatListResponse> { | ||
|
||
override fun onResponse(response: McuMgrStatListResponse) { | ||
// Check for error response. | ||
if (!response.isSuccess) { | ||
callback(StatCollectionResult.Failure(McuMgrErrorException(response))) | ||
return | ||
} | ||
// Filter statistic group names. | ||
val groupNames = filter?.intersect(response.stat_list.toSet())?.toList() | ||
?: response.stat_list.toList() | ||
// Ensure group names in response. | ||
if (groupNames.isEmpty()) { | ||
callback(StatCollectionResult.Failure( | ||
IllegalStateException("Statistic group list is empty.") | ||
)) | ||
return | ||
} | ||
// Start collection | ||
collection.start(groupNames) | ||
} | ||
|
||
override fun onError(error: McuMgrException) { | ||
callback(StatCollectionResult.Failure(error)) | ||
} | ||
}) | ||
return collection | ||
} | ||
} | ||
|
||
/** | ||
* Manages a single statistics collection. | ||
*/ | ||
private class StatCollection( | ||
private val statsManager: StatsManager, | ||
private val callback: StatCollectionCallback | ||
): Cancellable { | ||
|
||
private val cancelled = AtomicBoolean(false) | ||
private val started = AtomicBoolean(false) | ||
private val result = mutableMapOf<String, Map<String, Long>>() | ||
|
||
/** | ||
* Start the stat collection for a given list of statistics groups. | ||
* | ||
* Start must only be called once per collection and must be provided at least one group to | ||
* collect from. Otherwise this method will throw an error. | ||
* | ||
* @throws IllegalArgumentException If the stat collection has already been started. | ||
*/ | ||
fun start(groupNames: List<String>): Cancellable { | ||
check(started.compareAndSet(false, true)) { "Cannot call start() twice." } | ||
if (groupNames.isEmpty()) { | ||
callback(StatCollectionResult.Failure(IllegalArgumentException("List of group names is empty."))) | ||
return this | ||
} | ||
if (cancelled.get()) { | ||
callback(StatCollectionResult.Cancelled(result)) | ||
return this | ||
} | ||
collect(0, groupNames, callback) | ||
return this | ||
} | ||
|
||
private fun collect(index: Int, groupNames: List<String>, callback: StatCollectionCallback) { | ||
require(index in groupNames.indices) { "Index $index is out of range of groupList." } | ||
statsManager.read(groupNames[index], object: McuMgrCallback<McuMgrStatResponse> { | ||
|
||
override fun onResponse(response: McuMgrStatResponse) { | ||
if (!response.isSuccess) { | ||
callback(StatCollectionResult.Failure(McuMgrErrorException(response))) | ||
return | ||
} | ||
result[response.name] = response.fields | ||
when { | ||
index == groupNames.size - 1 -> callback(StatCollectionResult.Success(result)) | ||
cancelled.get() -> callback(StatCollectionResult.Cancelled(result)) | ||
else -> collect(index + 1, groupNames, callback) | ||
} | ||
} | ||
|
||
override fun onError(error: McuMgrException) { | ||
callback(StatCollectionResult.Failure(error)) | ||
} | ||
}) | ||
} | ||
|
||
override fun cancel() { | ||
cancelled.set(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
44 changes: 0 additions & 44 deletions
44
mcumgr-core/src/test/java/io/runtime/mcumgr/McuMgrImageTest.java
This file was deleted.
Oops, something went wrong.
35 changes: 35 additions & 0 deletions
35
mcumgr-core/src/test/java/io/runtime/mcumgr/McuMgrImageTest.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,35 @@ | ||
package io.runtime.mcumgr | ||
|
||
import io.runtime.mcumgr.image.McuMgrImage | ||
import org.junit.Test | ||
import java.io.ByteArrayOutputStream | ||
import java.io.InputStream | ||
|
||
class McuMgrImageTest { | ||
|
||
@Test | ||
fun `parse image without protected tlvs success`() { | ||
val inputStream = this::class.java.classLoader?.getResourceAsStream("slinky-no-prot-tlv.img")!! | ||
?: throw IllegalStateException("input stream is null") | ||
val imageData = toByteArray(inputStream) | ||
McuMgrImage.fromBytes(imageData) | ||
} | ||
|
||
@Test | ||
fun `parse image with protected tlvs success`() { | ||
val inputStream = this::class.java.classLoader?.getResourceAsStream("slinky-prot-tlv.img") | ||
?: throw IllegalStateException("input stream is null") | ||
val imageData = toByteArray(inputStream) | ||
McuMgrImage.fromBytes(imageData) | ||
} | ||
|
||
private fun toByteArray(inputStream: InputStream): ByteArray { | ||
val os = ByteArrayOutputStream() | ||
val buffer = ByteArray(1024) | ||
var len: Int | ||
while (inputStream.read(buffer).also { len = it } != -1) { | ||
os.write(buffer, 0, len) | ||
} | ||
return os.toByteArray() | ||
} | ||
} |
Oops, something went wrong.