-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1734 from DataDog/xgouchet/RUM-1517/stub_sdk_core
RUM-1517 Create SDKCore stub classes
- Loading branch information
Showing
8 changed files
with
326 additions
and
1 deletion.
There are no files selected for viewing
19 changes: 19 additions & 0 deletions
19
dd-sdk-android-core/src/testFixtures/kotlin/com/datadog/android/api/StubEvent.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,19 @@ | ||
/* | ||
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
* This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
* Copyright 2016-Present Datadog, Inc. | ||
*/ | ||
|
||
package com.datadog.android.api | ||
|
||
/** | ||
* Holds the data and metadata of an event written via the [StubSDKCore]. | ||
* @param eventData the event data | ||
* @param eventMetadata the event metadata | ||
* @param batchMetadata the batch metadata | ||
*/ | ||
data class StubEvent( | ||
val eventData: String, | ||
val eventMetadata: String, | ||
val batchMetadata: String | ||
) |
59 changes: 59 additions & 0 deletions
59
dd-sdk-android-core/src/testFixtures/kotlin/com/datadog/android/api/StubFeatureScope.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,59 @@ | ||
/* | ||
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
* This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
* Copyright 2016-Present Datadog, Inc. | ||
*/ | ||
|
||
package com.datadog.android.api | ||
|
||
import com.datadog.android.api.context.DatadogContext | ||
import com.datadog.android.api.feature.Feature | ||
import com.datadog.android.api.feature.FeatureScope | ||
import com.datadog.android.api.storage.EventBatchWriter | ||
import com.datadog.android.api.storage.RawBatchEvent | ||
import org.mockito.Mockito.mock | ||
import org.mockito.Mockito.mockingDetails | ||
|
||
internal class StubFeatureScope( | ||
private val feature: Feature, | ||
private val datadogContextProvider: () -> DatadogContext, | ||
private val mockFeatureScope: FeatureScope = mock() | ||
) : FeatureScope by mockFeatureScope { | ||
|
||
private val eventBatchWriter: EventBatchWriter = mock() | ||
|
||
// region Stub | ||
|
||
fun eventsWritten(): List<StubEvent> { | ||
val details = mockingDetails(eventBatchWriter) | ||
return details.invocations | ||
.filter { it.method.name == "write" } | ||
.map { invocation -> | ||
val event = invocation.arguments[0] as? RawBatchEvent | ||
val batchMetadata = invocation.arguments[1] as? ByteArray ?: ByteArray(0) | ||
|
||
check(event != null) { "Unexpected null event, arguments were ${invocation.arguments.joinToString()}" } | ||
val eventContent = String(event.data) | ||
val eventMetadata = String(event.metadata) | ||
StubEvent(eventContent, eventMetadata, String(batchMetadata)) | ||
} | ||
} | ||
|
||
// endregion | ||
|
||
// region FeatureScope | ||
|
||
override fun withWriteContext( | ||
forceNewBatch: Boolean, | ||
callback: (DatadogContext, EventBatchWriter) -> Unit | ||
) { | ||
callback(datadogContextProvider(), eventBatchWriter) | ||
} | ||
|
||
override fun <T : Feature> unwrap(): T { | ||
@Suppress("UNCHECKED_CAST") | ||
return feature as T | ||
} | ||
|
||
// endregion | ||
} |
31 changes: 31 additions & 0 deletions
31
...e/src/testFixtures/kotlin/com/datadog/android/api/StubFirstPartyHostHeaderTypeResolver.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,31 @@ | ||
/* | ||
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
* This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
* Copyright 2016-Present Datadog, Inc. | ||
*/ | ||
|
||
package com.datadog.android.api | ||
|
||
import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver | ||
import com.datadog.android.trace.TracingHeaderType | ||
import okhttp3.HttpUrl | ||
|
||
class StubFirstPartyHostHeaderTypeResolver : | ||
FirstPartyHostHeaderTypeResolver { | ||
|
||
// region FirstPartyHostHeaderTypeResolver | ||
|
||
override fun isEmpty(): Boolean = false | ||
|
||
override fun isFirstPartyUrl(url: HttpUrl): Boolean = true | ||
|
||
override fun isFirstPartyUrl(url: String): Boolean = true | ||
|
||
override fun headerTypesForUrl(url: String): Set<TracingHeaderType> = setOf(TracingHeaderType.TRACECONTEXT) | ||
|
||
override fun headerTypesForUrl(url: HttpUrl): Set<TracingHeaderType> = setOf(TracingHeaderType.TRACECONTEXT) | ||
|
||
override fun getAllHeaderTypes(): Set<TracingHeaderType> = setOf(TracingHeaderType.TRACECONTEXT) | ||
|
||
// endregion | ||
} |
49 changes: 49 additions & 0 deletions
49
dd-sdk-android-core/src/testFixtures/kotlin/com/datadog/android/api/StubInternalLogger.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,49 @@ | ||
/* | ||
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
* This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
* Copyright 2016-Present Datadog, Inc. | ||
*/ | ||
|
||
package com.datadog.android.api | ||
|
||
internal class StubInternalLogger : InternalLogger { | ||
override fun log( | ||
level: InternalLogger.Level, | ||
target: InternalLogger.Target, | ||
messageBuilder: () -> String, | ||
throwable: Throwable?, | ||
onlyOnce: Boolean, | ||
additionalProperties: Map<String, Any?>? | ||
) { | ||
println("${level.name.first()} [${target.name.first()}]: ${messageBuilder()}") | ||
additionalProperties?.log() | ||
throwable?.printStackTrace() | ||
} | ||
|
||
override fun log( | ||
level: InternalLogger.Level, | ||
targets: List<InternalLogger.Target>, | ||
messageBuilder: () -> String, | ||
throwable: Throwable?, | ||
onlyOnce: Boolean, | ||
additionalProperties: Map<String, Any?>? | ||
) { | ||
println("${level.name.first()} [${targets.joinToString { it.name.first().toString() }}]: ${messageBuilder()}") | ||
additionalProperties?.log() | ||
throwable?.printStackTrace() | ||
} | ||
|
||
override fun logMetric( | ||
messageBuilder: () -> String, | ||
additionalProperties: Map<String, Any?> | ||
) { | ||
println("M [T]: ${messageBuilder()}") | ||
additionalProperties.log() | ||
} | ||
|
||
private fun <K, T> Map<K, T>.log() { | ||
forEach { | ||
println(" ${it.key}: ${it.value}") | ||
} | ||
} | ||
} |
132 changes: 132 additions & 0 deletions
132
dd-sdk-android-core/src/testFixtures/kotlin/com/datadog/android/api/StubSDKCore.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,132 @@ | ||
/* | ||
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
* This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
* Copyright 2016-Present Datadog, Inc. | ||
*/ | ||
|
||
package com.datadog.android.api | ||
|
||
import android.content.Context | ||
import com.datadog.android.api.context.DatadogContext | ||
import com.datadog.android.api.context.NetworkInfo | ||
import com.datadog.android.api.context.TimeInfo | ||
import com.datadog.android.api.context.UserInfo | ||
import com.datadog.android.api.feature.Feature | ||
import com.datadog.android.api.feature.FeatureScope | ||
import com.datadog.android.core.InternalSdkCore | ||
import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver | ||
import fr.xgouchet.elmyr.Forge | ||
import org.mockito.Mockito.mock | ||
import org.mockito.kotlin.doReturn | ||
import org.mockito.kotlin.whenever | ||
|
||
/** | ||
* A stub implementation of [InternalSdkCore]. | ||
* | ||
* It adds several functions to get info about internal state and usage: | ||
* [eventsWritten], … | ||
*/ | ||
class StubSDKCore( | ||
private val forge: Forge, | ||
val mockContext: Context = mock(), | ||
private val mockSdkCore: InternalSdkCore = mock() | ||
) : InternalSdkCore by mockSdkCore { | ||
|
||
private val featureScopes = mutableMapOf<String, StubFeatureScope>() | ||
|
||
private var datadogContext = forge.getForgery<DatadogContext>().copy(source = "android") | ||
|
||
init { | ||
whenever(mockContext.packageName) doReturn forge.anAlphabeticalString() | ||
} | ||
|
||
// region Stub | ||
|
||
/** | ||
* Lists all the events written by a given feature. | ||
* @param featureName the name of the feature | ||
* @return a list of pairs, each pair holds | ||
*/ | ||
fun eventsWritten(featureName: String): List<StubEvent> { | ||
return featureScopes[featureName]?.eventsWritten() ?: emptyList() | ||
} | ||
|
||
fun stubNetworkInfo(networkInfo: NetworkInfo) { | ||
datadogContext = datadogContext.copy(networkInfo = networkInfo) | ||
} | ||
|
||
fun stubUserInfo(userInfo: UserInfo) { | ||
networkInfo | ||
datadogContext = datadogContext.copy(userInfo = userInfo) | ||
} | ||
|
||
// endregion | ||
|
||
// region InternalSdkCore | ||
|
||
override val firstPartyHostResolver: FirstPartyHostHeaderTypeResolver = | ||
StubFirstPartyHostHeaderTypeResolver() | ||
|
||
override fun getDatadogContext(): DatadogContext { | ||
return datadogContext | ||
} | ||
|
||
override val networkInfo: NetworkInfo | ||
get() = datadogContext.networkInfo | ||
|
||
// endregion | ||
|
||
// region FeatureSdkCore | ||
|
||
override val internalLogger: InternalLogger = StubInternalLogger() | ||
|
||
override fun registerFeature(feature: Feature) { | ||
featureScopes[feature.name] = StubFeatureScope(feature, { datadogContext }) | ||
feature.onInitialize(mockContext) | ||
mockSdkCore.registerFeature(feature) | ||
} | ||
|
||
override fun getFeature(featureName: String): FeatureScope? { | ||
mockSdkCore.getFeature(featureName) | ||
return featureScopes[featureName] | ||
} | ||
|
||
override fun updateFeatureContext( | ||
featureName: String, | ||
updateCallback: (context: MutableMap<String, Any?>) -> Unit | ||
) { | ||
val featureContext = datadogContext.featuresContext[featureName]?.toMutableMap() ?: mutableMapOf() | ||
updateCallback(featureContext) | ||
datadogContext = datadogContext.copy( | ||
featuresContext = datadogContext.featuresContext.toMutableMap().apply { | ||
put(featureName, featureContext) | ||
} | ||
) | ||
} | ||
|
||
// endregion | ||
|
||
// region SdkCore | ||
|
||
override val time: TimeInfo | ||
get() { | ||
val nanos = System.nanoTime() | ||
return TimeInfo( | ||
deviceTimeNs = nanos, | ||
serverTimeNs = nanos, | ||
serverTimeOffsetMs = 0L, | ||
serverTimeOffsetNs = 0L | ||
) | ||
} | ||
|
||
override fun setUserInfo( | ||
id: String?, | ||
name: String?, | ||
email: String?, | ||
extraInfo: Map<String, Any?> | ||
) { | ||
datadogContext = datadogContext.copy(userInfo = UserInfo(id, name, email, extraInfo)) | ||
} | ||
|
||
// endregion | ||
} |
34 changes: 34 additions & 0 deletions
34
dd-sdk-android-core/src/testFixtures/kotlin/com/datadog/android/tests/ktx/JsonObjectExt.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,34 @@ | ||
/* | ||
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
* This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
* Copyright 2016-Present Datadog, Inc. | ||
*/ | ||
|
||
package com.datadog.android.tests.ktx | ||
|
||
import com.google.gson.JsonObject | ||
|
||
/** | ||
* A utility method to retrieve a nested attribute using the dotted notation. | ||
* E.g.: assuming the `this` JsonObject represents the json below, calling | ||
* `getString("foo.bar.spam")` will return the String `"42"`. | ||
* | ||
* { | ||
* "foo": { | ||
* "bar" : { | ||
* "spam": "42" | ||
* } | ||
* } | ||
* } | ||
*/ | ||
fun JsonObject.getString(path: String): String? { | ||
return if (has(path)) { | ||
getAsJsonPrimitive(path)?.asString | ||
} else if (path.contains('.')) { | ||
val head = path.substringBefore('.') | ||
val tail = path.substringAfter('.') | ||
getAsJsonObject(head)?.getString(tail) | ||
} else { | ||
getAsJsonPrimitive(path)?.asString | ||
} | ||
} |
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