From da5640407c95baee455630b9b657d030a7fa162d Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 29 Jul 2021 15:37:54 +0200 Subject: [PATCH 1/9] Api changes --- .../flank/wrapper/internal/CrashReporter.kt | 2 +- .../wrapper/internal/FlankWrapperAnalytics.kt | 15 ++++--- .../ftl/analytics/InitUsageStatistics.kt | 10 ++--- .../kotlin/ftl/analytics/SendConfiguration.kt | 42 +++++++++---------- .../main/kotlin/ftl/ios/xctest/XcTestData.kt | 7 ++-- .../src/main/kotlin/ftl/mock/MockServer.kt | 8 +++- .../src/main/kotlin/ftl/reports/CostReport.kt | 7 ++-- .../src/main/kotlin/ftl/run/NewTestRun.kt | 12 +++--- .../kotlin/ftl/run/common/SaveSessionId.kt | 2 +- .../ftl/run/platform/RunAndroidTests.kt | 7 ++-- .../src/main/kotlin/ftl/util/CrashReporter.kt | 4 +- test_runner/src/main/kotlin/ftl/util/Utils.kt | 2 +- .../ftl/analytics/UsageStatisticsTest.kt | 11 +++-- .../flank/tool/analytics/mixpanel/Mixpanel.kt | 42 +++++++++++++++++++ .../{ => internal}/AnalyticsReport.kt | 7 ++-- .../{ => internal}/SendConfiguration.kt | 12 +++++- .../{ => internal}/StatisticDataFilters.kt | 2 +- .../{ => internal}/UsageStatisticsClient.kt | 11 +---- .../analytics/mixpanel/{ => internal}/Util.kt | 5 ++- 19 files changed, 124 insertions(+), 84 deletions(-) create mode 100644 tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt rename tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/{ => internal}/AnalyticsReport.kt (75%) rename tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/{ => internal}/SendConfiguration.kt (60%) rename tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/{ => internal}/StatisticDataFilters.kt (96%) rename tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/{ => internal}/UsageStatisticsClient.kt (70%) rename tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/{ => internal}/Util.kt (76%) diff --git a/flank_wrapper/src/main/kotlin/com/github/flank/wrapper/internal/CrashReporter.kt b/flank_wrapper/src/main/kotlin/com/github/flank/wrapper/internal/CrashReporter.kt index 1d42c9b64d..dea81c494d 100644 --- a/flank_wrapper/src/main/kotlin/com/github/flank/wrapper/internal/CrashReporter.kt +++ b/flank_wrapper/src/main/kotlin/com/github/flank/wrapper/internal/CrashReporter.kt @@ -1,7 +1,7 @@ package com.github.flank.wrapper.internal import flank.common.config.isTest -import flank.tool.analytics.mixpanel.sessionId +import flank.tool.analytics.mixpanel.internal.sessionId import io.sentry.Sentry private const val SESSION_ID = "session.id" diff --git a/flank_wrapper/src/main/kotlin/com/github/flank/wrapper/internal/FlankWrapperAnalytics.kt b/flank_wrapper/src/main/kotlin/com/github/flank/wrapper/internal/FlankWrapperAnalytics.kt index 9b8a636199..76be4d0353 100644 --- a/flank_wrapper/src/main/kotlin/com/github/flank/wrapper/internal/FlankWrapperAnalytics.kt +++ b/flank_wrapper/src/main/kotlin/com/github/flank/wrapper/internal/FlankWrapperAnalytics.kt @@ -1,20 +1,19 @@ package com.github.flank.wrapper.internal -import flank.tool.analytics.mixpanel.send -import flank.tool.analytics.mixpanel.toEvent +import flank.tool.analytics.mixpanel.Mixpanel private const val FLANK_WRAPPER = "flank_wrapper" private const val EVENT_RUN = "flank run" private const val EVENT_NEW_FLANK_VERSION_DOWNLOADED = "new_version_downloaded" internal fun sendAnalyticsNewFlankVersionDownloaded() { - eventWithoutProperties(EVENT_NEW_FLANK_VERSION_DOWNLOADED).send() + Mixpanel.configure(FLANK_WRAPPER) + Mixpanel.add(FLANK_WRAPPER, EVENT_NEW_FLANK_VERSION_DOWNLOADED) + Mixpanel.send(FLANK_WRAPPER) } internal fun sendAnalyticsFlankRun() { - eventWithoutProperties(EVENT_RUN).send() + Mixpanel.configure(FLANK_WRAPPER) + Mixpanel.add(FLANK_WRAPPER, EVENT_RUN) + Mixpanel.send(FLANK_WRAPPER) } - -private fun eventWithoutProperties( - eventName: String -) = emptyMap().toEvent(FLANK_WRAPPER, eventName) diff --git a/test_runner/src/main/kotlin/ftl/analytics/InitUsageStatistics.kt b/test_runner/src/main/kotlin/ftl/analytics/InitUsageStatistics.kt index 490b53f7a9..d31db6db39 100644 --- a/test_runner/src/main/kotlin/ftl/analytics/InitUsageStatistics.kt +++ b/test_runner/src/main/kotlin/ftl/analytics/InitUsageStatistics.kt @@ -1,17 +1,17 @@ package ftl.analytics -import flank.tool.analytics.mixpanel.analyticsReport -import flank.tool.analytics.mixpanel.configure -import flank.tool.analytics.mixpanel.initializeStatisticsClient +import flank.common.userHome +import flank.tool.analytics.mixpanel.Mixpanel +import flank.tool.analytics.mixpanel.internal.initializeStatisticsClient import ftl.args.AndroidArgs import ftl.args.IArgs import ftl.args.IosArgs import ftl.util.isGoogleAnalyticsDisabled internal fun IArgs.initUsageStatistics() { - analyticsReport.configure(project) + Mixpanel.configure(project) initializeStatisticsClient( - disableUsageStatistics || isGoogleAnalyticsDisabled(flank.common.userHome), + disableUsageStatistics || isGoogleAnalyticsDisabled(userHome), AndroidArgs::class, IosArgs::class, IArgs::class diff --git a/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt b/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt index d00c48c2e1..602ba89638 100644 --- a/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt +++ b/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt @@ -1,17 +1,14 @@ package ftl.analytics import com.google.common.annotations.VisibleForTesting -import flank.tool.analytics.mixpanel.FIREBASE -import flank.tool.analytics.mixpanel.FLANK_VERSION -import flank.tool.analytics.mixpanel.SESSION_ID -import flank.tool.analytics.mixpanel.TEST_PLATFORM -import flank.tool.analytics.mixpanel.add -import flank.tool.analytics.mixpanel.analyticsReport -import flank.tool.analytics.mixpanel.filterSensitiveValues -import flank.tool.analytics.mixpanel.objectToMap -import flank.tool.analytics.mixpanel.removeNotNeededKeys -import flank.tool.analytics.mixpanel.schemaVersion -import flank.tool.analytics.mixpanel.sessionId +import flank.tool.analytics.mixpanel.Mixpanel +import flank.tool.analytics.mixpanel.Mixpanel.add +import flank.tool.analytics.mixpanel.internal.FIREBASE +import flank.tool.analytics.mixpanel.internal.filterSensitiveValues +import flank.tool.analytics.mixpanel.internal.objectToMap +import flank.tool.analytics.mixpanel.internal.removeNotNeededKeys +import flank.tool.analytics.mixpanel.internal.schemaVersion +import flank.tool.analytics.mixpanel.internal.sessionId import ftl.args.AndroidArgs import ftl.args.IArgs import ftl.args.IosArgs @@ -20,9 +17,11 @@ import ftl.environment.VIRTUAL_DEVICE import ftl.util.readVersion fun AndroidArgs.reportConfiguration() { - addCommonData() - .add("configuration", createEventMap()) - .add("device_types", devices.map { if (it.isVirtual) VIRTUAL_DEVICE else PHYSICAL_DEVICE }.distinct()) + add(Mixpanel.CONFIGURATION, createEventMap()) + add( + Mixpanel.DEVICE_TYPES, + devices.map { if (it.isVirtual) VIRTUAL_DEVICE else PHYSICAL_DEVICE }.distinct() + ) } internal fun AndroidArgs.createEventMap() = @@ -30,18 +29,17 @@ internal fun AndroidArgs.createEventMap() = fun IosArgs.reportConfiguration() { addCommonData() - .add("configuration", createEventMap()) - .add("device_types", listOf(PHYSICAL_DEVICE)) + add(Mixpanel.CONFIGURATION, createEventMap()) + add(Mixpanel.DEVICE_TYPES, listOf(PHYSICAL_DEVICE)) } fun IArgs.addCommonData() = let { initUsageStatistics() - analyticsReport - .add("schema_version", schemaVersion) - .add(FLANK_VERSION, readVersion()) - .add(SESSION_ID, sessionId) - .add(TEST_PLATFORM, FIREBASE) - .add("project_id", project) + add(Mixpanel.SCHEMA_VERSION, schemaVersion) + add(Mixpanel.FLANK_VERSION, readVersion()) + add(Mixpanel.SESSION_ID, sessionId) + add(Mixpanel.TEST_PLATFORM, FIREBASE) + add(Mixpanel.PROJECT_ID, project) } private fun IosArgs.createEventMap() = diff --git a/test_runner/src/main/kotlin/ftl/ios/xctest/XcTestData.kt b/test_runner/src/main/kotlin/ftl/ios/xctest/XcTestData.kt index fdbd4a4841..e77c8675f5 100644 --- a/test_runner/src/main/kotlin/ftl/ios/xctest/XcTestData.kt +++ b/test_runner/src/main/kotlin/ftl/ios/xctest/XcTestData.kt @@ -1,9 +1,8 @@ package ftl.ios.xctest import com.dd.plist.NSDictionary -import flank.tool.analytics.mixpanel.APP_ID -import flank.tool.analytics.mixpanel.add -import flank.tool.analytics.mixpanel.analyticsReport +import flank.tool.analytics.mixpanel.Mixpanel +import flank.tool.analytics.mixpanel.internal.APP_ID import ftl.args.ArgsHelper.calculateShards import ftl.args.IosArgs import ftl.args.isXcTest @@ -61,7 +60,7 @@ private fun IosArgs.calculateXcTest(): XcTestRunData { ) } -private fun IosArgs.reportBundleId() = analyticsReport.add(APP_ID, getBundleId()) +private fun IosArgs.reportBundleId() = Mixpanel.add(APP_ID, getBundleId()) private inline fun createCustomSharding(shardingJsonPath: String) = fromJson(Paths.get(shardingJsonPath).toFile().readText()) diff --git a/test_runner/src/main/kotlin/ftl/mock/MockServer.kt b/test_runner/src/main/kotlin/ftl/mock/MockServer.kt index b74f3c78f4..de6a0c4064 100644 --- a/test_runner/src/main/kotlin/ftl/mock/MockServer.kt +++ b/test_runner/src/main/kotlin/ftl/mock/MockServer.kt @@ -1,6 +1,9 @@ package ftl.mock +import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.jsonMapper +import com.fasterxml.jackson.module.kotlin.kotlinModule import com.fasterxml.jackson.module.kotlin.readValue import com.google.api.services.toolresults.model.AppStartTime import com.google.api.services.toolresults.model.CPUInfo @@ -41,7 +44,6 @@ import com.google.testing.model.TestExecution import com.google.testing.model.TestMatrix import com.google.testing.model.ToolResultsExecution import com.google.testing.model.ToolResultsStep -import flank.tool.analytics.mixpanel.objectToMap import ftl.client.google.run.toClientInfoDetailList import ftl.config.FtlConstants import ftl.config.FtlConstants.JSON_FACTORY @@ -405,6 +407,10 @@ object MockServer { .setClientInfoDetails(allClientDetails.toClientInfoDetailList()) } + private fun Any.objectToMap(): Map = objectMapper.convertValue(this, object : TypeReference>() {}) + + private val objectMapper by lazy { jsonMapper { addModule(kotlinModule()) } } + fun start() { if (isStarted) return val loggingEnabled = LogbackLogger.Root.isEnabled diff --git a/test_runner/src/main/kotlin/ftl/reports/CostReport.kt b/test_runner/src/main/kotlin/ftl/reports/CostReport.kt index f3ff267f03..3d8648fba3 100644 --- a/test_runner/src/main/kotlin/ftl/reports/CostReport.kt +++ b/test_runner/src/main/kotlin/ftl/reports/CostReport.kt @@ -1,8 +1,7 @@ package ftl.reports import flank.common.println -import flank.tool.analytics.mixpanel.add -import flank.tool.analytics.mixpanel.analyticsReport +import flank.tool.analytics.mixpanel.Mixpanel import ftl.api.JUnitTest import ftl.args.IArgs import ftl.config.FtlConstants.indent @@ -32,7 +31,7 @@ object CostReport : IReport { val physicalCost = calculatePhysicalCost(totalBillablePhysicalMinutes.toBigDecimal()) val total = calculateTotalCost(virtualCost, physicalCost) - analyticsReport.add( + Mixpanel.add( "cost", mapOf( "virtual" to virtualCost, @@ -41,7 +40,7 @@ object CostReport : IReport { ) ) - analyticsReport.add( + Mixpanel.add( "test_duration", mapOf( "virtual" to totalBillableVirtualMinutes, diff --git a/test_runner/src/main/kotlin/ftl/run/NewTestRun.kt b/test_runner/src/main/kotlin/ftl/run/NewTestRun.kt index da5d92a811..d12aaad554 100644 --- a/test_runner/src/main/kotlin/ftl/run/NewTestRun.kt +++ b/test_runner/src/main/kotlin/ftl/run/NewTestRun.kt @@ -1,8 +1,6 @@ package ftl.run -import flank.tool.analytics.mixpanel.add -import flank.tool.analytics.mixpanel.analyticsReport -import flank.tool.analytics.mixpanel.send +import flank.tool.analytics.mixpanel.Mixpanel import ftl.api.TestMatrix import ftl.args.AndroidArgs import ftl.args.IArgs @@ -47,7 +45,7 @@ suspend fun IArgs.newTestRun() = withTimeoutOrNull(parsedTimeout) { matrixMap.printMatricesWebLinks(project) outputReport.log(matrixMap) matrixMap.reportTestResults() - analyticsReport.send() + Mixpanel.send() matrixMap.validate(ignoreFailedTests) addStepTime("Generating reports", duration) } @@ -66,12 +64,12 @@ private fun MatrixMap.reportTestResults() { overheadTime = result.overheadTime + overview.overheadTime ) } - analyticsReport.add( + Mixpanel.add( "shards_count", map.values.flatMap { it.testExecutions }.maxOf { testExecution -> testExecution.shardIndex ?: 0 } + 1 ) - analyticsReport.add("outcome", outcomes) - analyticsReport.add( + Mixpanel.add("outcome", outcomes) + Mixpanel.add( "tests", mapOf( "total" to testsSummary.total, diff --git a/test_runner/src/main/kotlin/ftl/run/common/SaveSessionId.kt b/test_runner/src/main/kotlin/ftl/run/common/SaveSessionId.kt index 2ae513acd2..94bf63024c 100644 --- a/test_runner/src/main/kotlin/ftl/run/common/SaveSessionId.kt +++ b/test_runner/src/main/kotlin/ftl/run/common/SaveSessionId.kt @@ -1,6 +1,6 @@ package ftl.run.common -import flank.tool.analytics.mixpanel.sessionId +import flank.tool.analytics.mixpanel.internal.sessionId import ftl.args.IArgs import java.nio.file.Paths diff --git a/test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt b/test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt index a928312d35..ff8794ed16 100644 --- a/test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt +++ b/test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt @@ -2,9 +2,8 @@ package ftl.run.platform import flank.common.join import flank.common.logLn -import flank.tool.analytics.mixpanel.APP_ID -import flank.tool.analytics.mixpanel.add -import flank.tool.analytics.mixpanel.analyticsReport +import flank.tool.analytics.mixpanel.Mixpanel +import flank.tool.analytics.mixpanel.internal.APP_ID import ftl.api.RemoteStorage import ftl.api.TestMatrixAndroid import ftl.api.executeTestMatrixAndroid @@ -105,4 +104,4 @@ private fun AndroidTestContext.reportPackageName() = when (this) { is GameLoopContext -> getAndroidAppDetails(app.remote) }.sendPackageName() -private fun String.sendPackageName() = analyticsReport.add(APP_ID, this) +private fun String.sendPackageName() = Mixpanel.add(APP_ID, this) diff --git a/test_runner/src/main/kotlin/ftl/util/CrashReporter.kt b/test_runner/src/main/kotlin/ftl/util/CrashReporter.kt index a3d9956499..bc06656ce7 100644 --- a/test_runner/src/main/kotlin/ftl/util/CrashReporter.kt +++ b/test_runner/src/main/kotlin/ftl/util/CrashReporter.kt @@ -1,8 +1,8 @@ package ftl.util import flank.common.config.isTest -import flank.tool.analytics.mixpanel.SESSION_ID -import flank.tool.analytics.mixpanel.sessionId +import flank.tool.analytics.mixpanel.internal.SESSION_ID +import flank.tool.analytics.mixpanel.internal.sessionId import io.sentry.Sentry import io.sentry.SentryLevel import java.io.File diff --git a/test_runner/src/main/kotlin/ftl/util/Utils.kt b/test_runner/src/main/kotlin/ftl/util/Utils.kt index 81f8382864..55c8e54cc7 100644 --- a/test_runner/src/main/kotlin/ftl/util/Utils.kt +++ b/test_runner/src/main/kotlin/ftl/util/Utils.kt @@ -4,7 +4,7 @@ package ftl.util import com.fasterxml.jackson.annotation.JsonProperty import flank.common.logLn -import flank.tool.analytics.mixpanel.sessionId +import flank.tool.analytics.mixpanel.internal.sessionId import ftl.run.exception.FlankGeneralError import java.io.File import java.io.InputStream diff --git a/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt b/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt index 29ffda5686..89fde50e69 100644 --- a/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt +++ b/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt @@ -1,7 +1,7 @@ package ftl.analytics import com.google.common.truth.Truth.assertThat -import flank.tool.analytics.mixpanel.send +import flank.tool.analytics.mixpanel.Mixpanel import ftl.args.AndroidArgs import ftl.test.util.FlankTestRunner import ftl.util.readVersion @@ -9,7 +9,6 @@ import io.mockk.every import io.mockk.mockkStatic import io.mockk.unmockkAll import io.mockk.verify -import org.json.JSONObject import org.junit.After import org.junit.Test import org.junit.runner.RunWith @@ -38,16 +37,16 @@ class UsageStatisticsTest { @Test fun `should not run send configuration if unit tests`() { - mockkStatic(JSONObject::send) + mockkStatic(Mixpanel::send) AndroidArgs.default().reportConfiguration() - verify(inverse = true) { any().send() } + verify(inverse = true) { any().send() } } @Test fun `should not run send configuration if disable statistic param set`() { - mockkStatic(JSONObject::send) + mockkStatic(Mixpanel::send) mockkStatic(::readVersion) every { readVersion() } returns "test" @@ -57,6 +56,6 @@ class UsageStatisticsTest { .reportConfiguration() } - verify(inverse = true) { any().send() } + verify(inverse = true) { any().send() } } } diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt new file mode 100644 index 0000000000..8546532293 --- /dev/null +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt @@ -0,0 +1,42 @@ +package flank.tool.analytics.mixpanel + +import flank.tool.analytics.mixpanel.internal.add +import flank.tool.analytics.mixpanel.internal.analyticsReport +import flank.tool.analytics.mixpanel.internal.configure +import flank.tool.analytics.mixpanel.internal.objectToMap +import flank.tool.analytics.mixpanel.internal.send + +object Mixpanel { + const val FIREBASE_TEST_LAB_RUN = "firebase test lab run" + const val APP_ID = "app_id" + const val DEVICE_TYPE = "device_type" + const val FLANK_VERSION = "flank_version" + const val FLANK_VERSION_PROPERTY = "version" + const val TEST_PLATFORM = "test_platform" + + const val FIREBASE = "firebase" + const val CORELLIUM = "corellium" + + const val ANDROID = "android" + const val IOS = "ios" + + const val SCHEMA_VERSION = "schema_version" + const val PROJECT_ID = "project_id" + + const val DEVICE_TYPES = "device_types" + const val CONFIGURATION = "configuration" + const val SESSION_ID = "session.id" + + fun configure(projectName: String) { + analyticsReport.configure(projectName) + } + + fun add(key: String, reportNode: Any) { + analyticsReport.add(key, reportNode) + } + + fun send(eventName: String = FIREBASE_TEST_LAB_RUN) = + analyticsReport.send(eventName) +} + +internal fun Any.objectToMap(): Map = objectToMap() diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/AnalyticsReport.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/AnalyticsReport.kt similarity index 75% rename from tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/AnalyticsReport.kt rename to tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/AnalyticsReport.kt index c8e87b4a27..c02a4b262d 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/AnalyticsReport.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/AnalyticsReport.kt @@ -1,9 +1,9 @@ -package flank.tool.analytics.mixpanel +package flank.tool.analytics.mixpanel.internal const val schemaVersion = "1.0" var analyticsReport = AnalyticsReport() - private set + internal set data class AnalyticsReport( val projectName: String = "", @@ -22,4 +22,5 @@ fun AnalyticsReport.add(key: String, reportNode: Any) = also { } } -fun AnalyticsReport.send() = sendConfiguration(analyticsReport.projectName, data) +fun AnalyticsReport.send(eventName: String) = + sendConfiguration(analyticsReport.projectName, data, eventName) diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/SendConfiguration.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/SendConfiguration.kt similarity index 60% rename from tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/SendConfiguration.kt rename to tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/SendConfiguration.kt index 5898090012..2f324344ff 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/SendConfiguration.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/SendConfiguration.kt @@ -1,6 +1,7 @@ -package flank.tool.analytics.mixpanel +package flank.tool.analytics.mixpanel.internal import flank.common.toJSONObject +import org.json.JSONObject private const val PROJECT_ID = "project_id" private const val NAME_KEY = "name" @@ -8,7 +9,7 @@ private const val NAME_KEY = "name" fun sendConfiguration( project: String, events: Map, - eventName: String = FIREBASE_TEST_LAB_RUN + eventName: String ) = project.takeUnless { blockSendUsageStatistics || project.isBlank() }?.run { registerUser(project) @@ -22,3 +23,10 @@ private fun registerUser(project: String) { project, mapOf(PROJECT_ID to project, NAME_KEY to project).toJSONObject() ).send() } + +private fun JSONObject.send() = apiClient.sendMessage(this) + +private fun Map.toEvent(projectId: String, eventName: String): JSONObject = + (this + Pair(SESSION_ID, sessionId)).run { + messageBuilder.event(projectId, eventName, toJSONObject()) + } diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/StatisticDataFilters.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/StatisticDataFilters.kt similarity index 96% rename from tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/StatisticDataFilters.kt rename to tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/StatisticDataFilters.kt index e36d044268..39b7349923 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/StatisticDataFilters.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/StatisticDataFilters.kt @@ -1,4 +1,4 @@ -package flank.tool.analytics.mixpanel +package flank.tool.analytics.mixpanel.internal import flank.tool.analytics.AnonymizeInStatistics import flank.tool.analytics.IgnoreInStatistics diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/UsageStatisticsClient.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/UsageStatisticsClient.kt similarity index 70% rename from tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/UsageStatisticsClient.kt rename to tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/UsageStatisticsClient.kt index f2330d3834..da50a34b66 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/UsageStatisticsClient.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/UsageStatisticsClient.kt @@ -1,11 +1,9 @@ -package flank.tool.analytics.mixpanel +package flank.tool.analytics.mixpanel.internal import com.fasterxml.jackson.module.kotlin.jsonMapper import com.fasterxml.jackson.module.kotlin.kotlinModule import com.mixpanel.mixpanelapi.MessageBuilder import com.mixpanel.mixpanelapi.MixpanelAPI -import flank.common.toJSONObject -import org.json.JSONObject import kotlin.reflect.KClass private const val MIXPANEL_API_TOKEN = "d9728b2c8e6ca9fd6de1fcd32dd8cdc2" @@ -32,10 +30,3 @@ fun initializeStatisticsClient(blockUsageStatistics: Boolean, vararg statisticCl blockSendUsageStatistics = blockUsageStatistics classesForStatistics = statisticClasses.asList() } - -fun JSONObject.send() = apiClient.sendMessage(this) - -fun Map.toEvent(projectId: String, eventName: String): JSONObject = - (this + Pair(SESSION_ID, sessionId)).run { - messageBuilder.event(projectId, eventName, toJSONObject()) - } diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Util.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Util.kt similarity index 76% rename from tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Util.kt rename to tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Util.kt index ce63992703..daf1e97e5c 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Util.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Util.kt @@ -1,4 +1,4 @@ -package flank.tool.analytics.mixpanel +package flank.tool.analytics.mixpanel.internal import com.fasterxml.jackson.core.type.TypeReference import java.util.UUID @@ -22,4 +22,5 @@ val sessionId by lazy { UUID.randomUUID().toString() } -fun Any.objectToMap(): Map = objectMapper.convertValue(this, object : TypeReference>() {}) +fun Any.objectToMap(): Map = + objectMapper.convertValue(this, object : TypeReference>() {}) From 360bf2d0a791460948775bcf31cfac55d3a018f8 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 3 Aug 2021 09:54:03 +0200 Subject: [PATCH 2/9] FIxed tests --- flank_wrapper/build.gradle.kts | 2 +- flank_wrapper/src/main/resources/version.txt | 2 +- .../main/kotlin/ftl/analytics/SendConfiguration.kt | 1 + .../test/kotlin/ftl/analytics/UsageStatisticsTest.kt | 12 ++++++++---- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/flank_wrapper/build.gradle.kts b/flank_wrapper/build.gradle.kts index e5cb9cff8f..baa319e835 100644 --- a/flank_wrapper/build.gradle.kts +++ b/flank_wrapper/build.gradle.kts @@ -24,7 +24,7 @@ shadowJar.apply { } } // .. -version = "1.2.1" +version = "1.2.2" group = "com.github.flank" repositories { diff --git a/flank_wrapper/src/main/resources/version.txt b/flank_wrapper/src/main/resources/version.txt index cb174d58a5..d2d61a7e8e 100644 --- a/flank_wrapper/src/main/resources/version.txt +++ b/flank_wrapper/src/main/resources/version.txt @@ -1 +1 @@ -1.2.1 \ No newline at end of file +1.2.2 \ No newline at end of file diff --git a/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt b/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt index 602ba89638..263a7e5dce 100644 --- a/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt +++ b/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt @@ -17,6 +17,7 @@ import ftl.environment.VIRTUAL_DEVICE import ftl.util.readVersion fun AndroidArgs.reportConfiguration() { + addCommonData() add(Mixpanel.CONFIGURATION, createEventMap()) add( Mixpanel.DEVICE_TYPES, diff --git a/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt b/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt index 89fde50e69..eb8a3dea3b 100644 --- a/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt +++ b/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt @@ -6,6 +6,7 @@ import ftl.args.AndroidArgs import ftl.test.util.FlankTestRunner import ftl.util.readVersion import io.mockk.every +import io.mockk.mockkObject import io.mockk.mockkStatic import io.mockk.unmockkAll import io.mockk.verify @@ -37,25 +38,28 @@ class UsageStatisticsTest { @Test fun `should not run send configuration if unit tests`() { - mockkStatic(Mixpanel::send) + mockkObject(Mixpanel) + + every { Mixpanel.send(any()) } AndroidArgs.default().reportConfiguration() - verify(inverse = true) { any().send() } + verify(inverse = true) { Mixpanel.send(any()) } } @Test fun `should not run send configuration if disable statistic param set`() { - mockkStatic(Mixpanel::send) + mockkObject(Mixpanel) mockkStatic(::readVersion) every { readVersion() } returns "test" + every { Mixpanel.send(any()) } AndroidArgs.default().run { copy(commonArgs = commonArgs.copy(disableUsageStatistics = true)) .reportConfiguration() } - verify(inverse = true) { any().send() } + verify(inverse = true) { Mixpanel.send(any()) } } } From efece019adb1dfca68b215e6a2515d0bfff71d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janek=20G=C3=B3ral?= Date: Tue, 3 Aug 2021 13:18:57 +0200 Subject: [PATCH 3/9] Refactor --- .../flank/wrapper/internal/CrashReporter.kt | 4 +- .../adapter/google/GoogleTestMatrixAdapter.kt | 4 +- .../ftl/analytics/InitUsageStatistics.kt | 3 +- .../kotlin/ftl/analytics/SendConfiguration.kt | 38 ++++--------- .../main/kotlin/ftl/ios/xctest/XcTestData.kt | 3 +- .../src/main/kotlin/ftl/run/NewTestRun.kt | 4 +- .../kotlin/ftl/run/common/SaveSessionId.kt | 4 +- .../ftl/run/platform/RunAndroidTests.kt | 3 +- .../src/main/kotlin/ftl/util/CrashReporter.kt | 5 +- test_runner/src/main/kotlin/ftl/util/Utils.kt | 4 +- .../flank/tool/analytics/mixpanel/Mixpanel.kt | 54 ++++++++++--------- .../mixpanel/internal/AnalyticsReport.kt | 36 +++++++------ .../mixpanel/internal/ObjectMapper.kt | 10 ++++ .../mixpanel/internal/SendConfiguration.kt | 32 ----------- .../mixpanel/internal/StatisticDataFilters.kt | 21 ++++---- .../internal/UsageStatisticsClient.kt | 32 ----------- .../tool/analytics/mixpanel/internal/Util.kt | 26 --------- .../internal/send/SendConfiguration.kt | 51 ++++++++++++++++++ 18 files changed, 144 insertions(+), 190 deletions(-) create mode 100644 tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/ObjectMapper.kt delete mode 100644 tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/SendConfiguration.kt delete mode 100644 tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/UsageStatisticsClient.kt delete mode 100644 tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Util.kt create mode 100644 tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/SendConfiguration.kt diff --git a/flank_wrapper/src/main/kotlin/com/github/flank/wrapper/internal/CrashReporter.kt b/flank_wrapper/src/main/kotlin/com/github/flank/wrapper/internal/CrashReporter.kt index dea81c494d..e975d9a06d 100644 --- a/flank_wrapper/src/main/kotlin/com/github/flank/wrapper/internal/CrashReporter.kt +++ b/flank_wrapper/src/main/kotlin/com/github/flank/wrapper/internal/CrashReporter.kt @@ -1,7 +1,7 @@ package com.github.flank.wrapper.internal import flank.common.config.isTest -import flank.tool.analytics.mixpanel.internal.sessionId +import flank.tool.analytics.mixpanel.Mixpanel import io.sentry.Sentry private const val SESSION_ID = "session.id" @@ -17,7 +17,7 @@ fun setupCrashReporter() { } logTags( - SESSION_ID to sessionId, + SESSION_ID to Mixpanel.sessionId, OS_NAME to osName, FLANK_WRAPPER_VERSION to flankWrapperVersion, ) diff --git a/test_runner/src/main/kotlin/ftl/adapter/google/GoogleTestMatrixAdapter.kt b/test_runner/src/main/kotlin/ftl/adapter/google/GoogleTestMatrixAdapter.kt index bb31be0710..6c76314996 100644 --- a/test_runner/src/main/kotlin/ftl/adapter/google/GoogleTestMatrixAdapter.kt +++ b/test_runner/src/main/kotlin/ftl/adapter/google/GoogleTestMatrixAdapter.kt @@ -3,7 +3,6 @@ package ftl.adapter.google import com.google.testing.model.FileReference import com.google.testing.model.TestExecution import com.google.testing.model.TestMatrix -import flank.common.toJSONObject import ftl.api.TestMatrix.Data import ftl.api.TestMatrix.Outcome import ftl.api.TestMatrix.SuiteOverview @@ -18,6 +17,7 @@ import ftl.util.getGcsRootBucket import ftl.util.timeoutToSeconds import ftl.util.webLink import ftl.util.webLinkWithoutExecutionDetails +import org.json.JSONObject fun TestMatrix.toApiModel(identity: ftl.api.TestMatrix.Identity? = null) = Data( projectId = projectId.orEmpty(), @@ -95,7 +95,7 @@ private fun TestMatrix.extractFileName(fileName: TestFilesPathWrapper.() -> Stri iosTestLoop ) .firstOrNull { it != null } - ?.toJSONObject() + ?.let(::JSONObject) ?.let { prettyPrint.fromJson(it.toString(), TestFilesPathWrapper::class.java).fileName() } ?.substringAfterLast('/') } diff --git a/test_runner/src/main/kotlin/ftl/analytics/InitUsageStatistics.kt b/test_runner/src/main/kotlin/ftl/analytics/InitUsageStatistics.kt index d31db6db39..df6bb86c61 100644 --- a/test_runner/src/main/kotlin/ftl/analytics/InitUsageStatistics.kt +++ b/test_runner/src/main/kotlin/ftl/analytics/InitUsageStatistics.kt @@ -2,7 +2,6 @@ package ftl.analytics import flank.common.userHome import flank.tool.analytics.mixpanel.Mixpanel -import flank.tool.analytics.mixpanel.internal.initializeStatisticsClient import ftl.args.AndroidArgs import ftl.args.IArgs import ftl.args.IosArgs @@ -10,7 +9,7 @@ import ftl.util.isGoogleAnalyticsDisabled internal fun IArgs.initUsageStatistics() { Mixpanel.configure(project) - initializeStatisticsClient( + Mixpanel.initializeStatisticsClient( disableUsageStatistics || isGoogleAnalyticsDisabled(userHome), AndroidArgs::class, IosArgs::class, diff --git a/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt b/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt index 263a7e5dce..76cded774d 100644 --- a/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt +++ b/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt @@ -1,14 +1,9 @@ package ftl.analytics -import com.google.common.annotations.VisibleForTesting import flank.tool.analytics.mixpanel.Mixpanel import flank.tool.analytics.mixpanel.Mixpanel.add -import flank.tool.analytics.mixpanel.internal.FIREBASE -import flank.tool.analytics.mixpanel.internal.filterSensitiveValues -import flank.tool.analytics.mixpanel.internal.objectToMap -import flank.tool.analytics.mixpanel.internal.removeNotNeededKeys -import flank.tool.analytics.mixpanel.internal.schemaVersion -import flank.tool.analytics.mixpanel.internal.sessionId +import flank.tool.analytics.mixpanel.filterSensitiveValues +import flank.tool.analytics.mixpanel.objectToMap import ftl.args.AndroidArgs import ftl.args.IArgs import ftl.args.IosArgs @@ -17,38 +12,27 @@ import ftl.environment.VIRTUAL_DEVICE import ftl.util.readVersion fun AndroidArgs.reportConfiguration() { + initUsageStatistics() addCommonData() - add(Mixpanel.CONFIGURATION, createEventMap()) - add( - Mixpanel.DEVICE_TYPES, - devices.map { if (it.isVirtual) VIRTUAL_DEVICE else PHYSICAL_DEVICE }.distinct() - ) + add(Mixpanel.CONFIGURATION, (toArgsMap() + commonArgs.toArgsMap()).filterSensitiveValues()) + add(Mixpanel.DEVICE_TYPES, devices.map { if (it.isVirtual) VIRTUAL_DEVICE else PHYSICAL_DEVICE }.distinct()) } -internal fun AndroidArgs.createEventMap() = - toArgsMap().plus(commonArgs.toArgsMap()).removeNotNeededKeys().filterSensitiveValues() - fun IosArgs.reportConfiguration() { + initUsageStatistics() addCommonData() - add(Mixpanel.CONFIGURATION, createEventMap()) + add(Mixpanel.CONFIGURATION, (toArgsMap() + commonArgs.toArgsMap()).filterSensitiveValues()) add(Mixpanel.DEVICE_TYPES, listOf(PHYSICAL_DEVICE)) } fun IArgs.addCommonData() = let { - initUsageStatistics() - add(Mixpanel.SCHEMA_VERSION, schemaVersion) + add(Mixpanel.SCHEMA_VERSION, Mixpanel.schemaVersion) add(Mixpanel.FLANK_VERSION, readVersion()) - add(Mixpanel.SESSION_ID, sessionId) - add(Mixpanel.TEST_PLATFORM, FIREBASE) + add(Mixpanel.SESSION_ID, Mixpanel.sessionId) + add(Mixpanel.TEST_PLATFORM, Mixpanel.Platform.FIREBASE) add(Mixpanel.PROJECT_ID, project) } -private fun IosArgs.createEventMap() = - toArgsMap().plus(commonArgs.toArgsMap()).removeNotNeededKeys().filterSensitiveValues() - -private fun IArgs.toArgsMap() = objectToMap().filterNonCommonArgs() - -@VisibleForTesting -internal fun Map.filterNonCommonArgs() = filter { it.key != COMMON_ARGS } +private fun IArgs.toArgsMap() = objectToMap().filter { it.key != COMMON_ARGS } private const val COMMON_ARGS = "commonArgs" diff --git a/test_runner/src/main/kotlin/ftl/ios/xctest/XcTestData.kt b/test_runner/src/main/kotlin/ftl/ios/xctest/XcTestData.kt index e77c8675f5..89b313fe05 100644 --- a/test_runner/src/main/kotlin/ftl/ios/xctest/XcTestData.kt +++ b/test_runner/src/main/kotlin/ftl/ios/xctest/XcTestData.kt @@ -2,7 +2,6 @@ package ftl.ios.xctest import com.dd.plist.NSDictionary import flank.tool.analytics.mixpanel.Mixpanel -import flank.tool.analytics.mixpanel.internal.APP_ID import ftl.args.ArgsHelper.calculateShards import ftl.args.IosArgs import ftl.args.isXcTest @@ -60,7 +59,7 @@ private fun IosArgs.calculateXcTest(): XcTestRunData { ) } -private fun IosArgs.reportBundleId() = Mixpanel.add(APP_ID, getBundleId()) +private fun IosArgs.reportBundleId() = Mixpanel.add(Mixpanel.APP_ID, getBundleId()) private inline fun createCustomSharding(shardingJsonPath: String) = fromJson(Paths.get(shardingJsonPath).toFile().readText()) diff --git a/test_runner/src/main/kotlin/ftl/run/NewTestRun.kt b/test_runner/src/main/kotlin/ftl/run/NewTestRun.kt index d12aaad554..57d9971a99 100644 --- a/test_runner/src/main/kotlin/ftl/run/NewTestRun.kt +++ b/test_runner/src/main/kotlin/ftl/run/NewTestRun.kt @@ -45,12 +45,14 @@ suspend fun IArgs.newTestRun() = withTimeoutOrNull(parsedTimeout) { matrixMap.printMatricesWebLinks(project) outputReport.log(matrixMap) matrixMap.reportTestResults() - Mixpanel.send() + Mixpanel.send(FIREBASE_TEST_LAB_RUN) matrixMap.validate(ignoreFailedTests) addStepTime("Generating reports", duration) } } +private const val FIREBASE_TEST_LAB_RUN = "firebase test lab run" + private fun MatrixMap.reportTestResults() { val outcomes = map.flatMap { it.value.axes } val testsSummary = outcomes.map { it.suiteOverview }.fold(TestMatrix.SuiteOverview()) { result, overview -> diff --git a/test_runner/src/main/kotlin/ftl/run/common/SaveSessionId.kt b/test_runner/src/main/kotlin/ftl/run/common/SaveSessionId.kt index 94bf63024c..e045b8cace 100644 --- a/test_runner/src/main/kotlin/ftl/run/common/SaveSessionId.kt +++ b/test_runner/src/main/kotlin/ftl/run/common/SaveSessionId.kt @@ -1,9 +1,9 @@ package ftl.run.common -import flank.tool.analytics.mixpanel.internal.sessionId +import flank.tool.analytics.mixpanel.Mixpanel import ftl.args.IArgs import java.nio.file.Paths const val SESSION_ID_FILE = "session_id.txt" -fun IArgs.saveSessionId() = Paths.get(localResultDir, SESSION_ID_FILE).toFile().writeText(sessionId) +fun IArgs.saveSessionId() = Paths.get(localResultDir, SESSION_ID_FILE).toFile().writeText(Mixpanel.sessionId) diff --git a/test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt b/test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt index ff8794ed16..9cef1cde40 100644 --- a/test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt +++ b/test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt @@ -3,7 +3,6 @@ package ftl.run.platform import flank.common.join import flank.common.logLn import flank.tool.analytics.mixpanel.Mixpanel -import flank.tool.analytics.mixpanel.internal.APP_ID import ftl.api.RemoteStorage import ftl.api.TestMatrixAndroid import ftl.api.executeTestMatrixAndroid @@ -104,4 +103,4 @@ private fun AndroidTestContext.reportPackageName() = when (this) { is GameLoopContext -> getAndroidAppDetails(app.remote) }.sendPackageName() -private fun String.sendPackageName() = Mixpanel.add(APP_ID, this) +private fun String.sendPackageName() = Mixpanel.add(Mixpanel.APP_ID, this) diff --git a/test_runner/src/main/kotlin/ftl/util/CrashReporter.kt b/test_runner/src/main/kotlin/ftl/util/CrashReporter.kt index bc06656ce7..a26a960e9a 100644 --- a/test_runner/src/main/kotlin/ftl/util/CrashReporter.kt +++ b/test_runner/src/main/kotlin/ftl/util/CrashReporter.kt @@ -1,8 +1,7 @@ package ftl.util import flank.common.config.isTest -import flank.tool.analytics.mixpanel.internal.SESSION_ID -import flank.tool.analytics.mixpanel.internal.sessionId +import flank.tool.analytics.mixpanel.Mixpanel import io.sentry.Sentry import io.sentry.SentryLevel import java.io.File @@ -53,7 +52,7 @@ private fun initializeCrashReportWrapper() { it.release = readRevision() } setCrashReportTag( - SESSION_ID to sessionId, + Mixpanel.SESSION_ID to Mixpanel.sessionId, OS_NAME to System.getProperty("os.name"), FLANK_VERSION to readVersion(), FLANK_REVISION to readRevision() diff --git a/test_runner/src/main/kotlin/ftl/util/Utils.kt b/test_runner/src/main/kotlin/ftl/util/Utils.kt index 55c8e54cc7..41b94f9cbb 100644 --- a/test_runner/src/main/kotlin/ftl/util/Utils.kt +++ b/test_runner/src/main/kotlin/ftl/util/Utils.kt @@ -4,7 +4,7 @@ package ftl.util import com.fasterxml.jackson.annotation.JsonProperty import flank.common.logLn -import flank.tool.analytics.mixpanel.internal.sessionId +import flank.tool.analytics.mixpanel.Mixpanel import ftl.run.exception.FlankGeneralError import java.io.File import java.io.InputStream @@ -74,7 +74,7 @@ private fun getResource(name: String): InputStream { fun printVersionInfo() { logLn("version: ${readVersion()}") logLn("revision: ${readRevision()}") - logLn("session id: $sessionId") + logLn("session id: ${Mixpanel.sessionId}") logLn() } diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt index 8546532293..be2e65daa3 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt @@ -1,42 +1,44 @@ package flank.tool.analytics.mixpanel -import flank.tool.analytics.mixpanel.internal.add -import flank.tool.analytics.mixpanel.internal.analyticsReport -import flank.tool.analytics.mixpanel.internal.configure +import flank.tool.analytics.mixpanel.internal.addToReport +import flank.tool.analytics.mixpanel.internal.configureReport +import flank.tool.analytics.mixpanel.internal.filterSensitiveValues import flank.tool.analytics.mixpanel.internal.objectToMap -import flank.tool.analytics.mixpanel.internal.send +import flank.tool.analytics.mixpanel.internal.removeNotNeededKeys +import flank.tool.analytics.mixpanel.internal.initStatisticsClient +import flank.tool.analytics.mixpanel.internal.sendReport +import java.util.UUID +import kotlin.reflect.KClass object Mixpanel { - const val FIREBASE_TEST_LAB_RUN = "firebase test lab run" - const val APP_ID = "app_id" - const val DEVICE_TYPE = "device_type" + const val SESSION_ID = "session.id" + const val PROJECT_ID = "project_id" + const val PROJECT_NAME = "name" + const val SCHEMA_VERSION = "schema_version" const val FLANK_VERSION = "flank_version" - const val FLANK_VERSION_PROPERTY = "version" const val TEST_PLATFORM = "test_platform" + const val CONFIGURATION = "configuration" + const val DEVICE_TYPES = "device_types" + const val APP_ID = "app_id" - const val FIREBASE = "firebase" - const val CORELLIUM = "corellium" + object Platform { + const val FIREBASE = "firebase" + } - const val ANDROID = "android" - const val IOS = "ios" + const val schemaVersion = "1.0" - const val SCHEMA_VERSION = "schema_version" - const val PROJECT_ID = "project_id" + val sessionId by lazy { UUID.randomUUID().toString() } - const val DEVICE_TYPES = "device_types" - const val CONFIGURATION = "configuration" - const val SESSION_ID = "session.id" + fun configure(projectName: String): Unit = configureReport(projectName) - fun configure(projectName: String) { - analyticsReport.configure(projectName) - } + fun add(key: String, reportNode: Any): Unit = addToReport(key, reportNode) - fun add(key: String, reportNode: Any) { - analyticsReport.add(key, reportNode) - } + fun send(eventName: String): Unit = sendReport(eventName) - fun send(eventName: String = FIREBASE_TEST_LAB_RUN) = - analyticsReport.send(eventName) + fun initializeStatisticsClient(blockUsageStatistics: Boolean, vararg statisticClasses: KClass<*>): Unit = + initStatisticsClient(blockUsageStatistics, statisticClasses) } -internal fun Any.objectToMap(): Map = objectToMap() +fun Any.objectToMap(): Map = objectToMap() + +fun Map.filterSensitiveValues() = removeNotNeededKeys().filterSensitiveValues() diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/AnalyticsReport.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/AnalyticsReport.kt index c02a4b262d..2df3c3b836 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/AnalyticsReport.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/AnalyticsReport.kt @@ -1,26 +1,28 @@ package flank.tool.analytics.mixpanel.internal -const val schemaVersion = "1.0" +import kotlin.reflect.KClass -var analyticsReport = AnalyticsReport() - internal set - -data class AnalyticsReport( - val projectName: String = "", - val data: AnalyticsData = mapOf() -) +internal object AnalyticsReport { + var projectName: String = "" + var blockSendUsageStatistics: Boolean = false + var classesForStatistics: List>? = null + val data: MutableMap = mutableMapOf() +} -private typealias AnalyticsData = Map +internal fun initStatisticsClient(blockUsageStatistics: Boolean, statisticClasses: Array>) { + if (AnalyticsReport.classesForStatistics != null) return + AnalyticsReport.blockSendUsageStatistics = blockUsageStatistics + AnalyticsReport.classesForStatistics = statisticClasses.asList() +} -fun AnalyticsReport.configure(projectName: String) { - analyticsReport = copy(projectName = projectName) +internal fun configureReport(projectName: String) { + AnalyticsReport.projectName = projectName } -fun AnalyticsReport.add(key: String, reportNode: Any) = also { - if (blockSendUsageStatistics.not()) { - analyticsReport = copy(data = analyticsReport.data + (key to reportNode)) - } +internal fun addToReport(key: String, reportNode: Any) { + AnalyticsReport.data[key] = reportNode } -fun AnalyticsReport.send(eventName: String) = - sendConfiguration(analyticsReport.projectName, data, eventName) +internal fun sendReport(eventName: String) { + sendConfiguration(AnalyticsReport.projectName, AnalyticsReport.data, eventName) +} diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/ObjectMapper.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/ObjectMapper.kt new file mode 100644 index 0000000000..1405a734b5 --- /dev/null +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/ObjectMapper.kt @@ -0,0 +1,10 @@ +package flank.tool.analytics.mixpanel.internal + +import com.fasterxml.jackson.core.type.TypeReference +import com.fasterxml.jackson.module.kotlin.jsonMapper +import com.fasterxml.jackson.module.kotlin.kotlinModule + +internal fun Any.objectToMap(): Map = + objectMapper.convertValue(this, object : TypeReference>() {}) + +private val objectMapper by lazy { jsonMapper { addModule(kotlinModule()) } } diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/SendConfiguration.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/SendConfiguration.kt deleted file mode 100644 index 2f324344ff..0000000000 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/SendConfiguration.kt +++ /dev/null @@ -1,32 +0,0 @@ -package flank.tool.analytics.mixpanel.internal - -import flank.common.toJSONObject -import org.json.JSONObject - -private const val PROJECT_ID = "project_id" -private const val NAME_KEY = "name" - -fun sendConfiguration( - project: String, - events: Map, - eventName: String -) = - project.takeUnless { blockSendUsageStatistics || project.isBlank() }?.run { - registerUser(project) - events - .toEvent(project, eventName) - .send() - } - -private fun registerUser(project: String) { - messageBuilder.set( - project, mapOf(PROJECT_ID to project, NAME_KEY to project).toJSONObject() - ).send() -} - -private fun JSONObject.send() = apiClient.sendMessage(this) - -private fun Map.toEvent(projectId: String, eventName: String): JSONObject = - (this + Pair(SESSION_ID, sessionId)).run { - messageBuilder.event(projectId, eventName, toJSONObject()) - } diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/StatisticDataFilters.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/StatisticDataFilters.kt index 39b7349923..1a2e082522 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/StatisticDataFilters.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/StatisticDataFilters.kt @@ -4,18 +4,22 @@ import flank.tool.analytics.AnonymizeInStatistics import flank.tool.analytics.IgnoreInStatistics import kotlin.reflect.KClass -internal val keysToRemove by lazy { +internal fun Map.removeNotNeededKeys(): Map = + filterNot { (key, _) -> key in keysToRemove } + +internal fun Map.filterSensitiveValues(): Map = + mapValues { it.anonymousSensitiveValues() } + +private val keysToRemove by lazy { getClassesForStatisticsOrThrow().map(findMembersWithAnnotation(IgnoreInStatistics::class)).flatten() } -internal val keysToAnonymize by lazy { +private val keysToAnonymize by lazy { getClassesForStatisticsOrThrow().map(findMembersWithAnnotation(AnonymizeInStatistics::class)).flatten() } private fun getClassesForStatisticsOrThrow() = - (classesForStatistics ?: throw NullPointerException("Analytics client should be initialized first")) - -internal var classesForStatistics: List>? = null + (AnalyticsReport.classesForStatistics ?: throw NullPointerException("Analytics client should be initialized first")) private fun findMembersWithAnnotation( annotationType: KClass<*> @@ -27,13 +31,6 @@ private fun findMembersWithAnnotation( } } -fun Map.removeNotNeededKeys() = - filterNot { (key, _) -> - key in keysToRemove - } - -fun Map.filterSensitiveValues() = mapValues { it.anonymousSensitiveValues() } - private fun Map.Entry.anonymousSensitiveValues() = if (keysToAnonymize.contains(key)) value.toAnonymous() else value diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/UsageStatisticsClient.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/UsageStatisticsClient.kt deleted file mode 100644 index da50a34b66..0000000000 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/UsageStatisticsClient.kt +++ /dev/null @@ -1,32 +0,0 @@ -package flank.tool.analytics.mixpanel.internal - -import com.fasterxml.jackson.module.kotlin.jsonMapper -import com.fasterxml.jackson.module.kotlin.kotlinModule -import com.mixpanel.mixpanelapi.MessageBuilder -import com.mixpanel.mixpanelapi.MixpanelAPI -import kotlin.reflect.KClass - -private const val MIXPANEL_API_TOKEN = "d9728b2c8e6ca9fd6de1fcd32dd8cdc2" - -internal var blockSendUsageStatistics: Boolean = false - -internal val messageBuilder by lazy { - MessageBuilder(MIXPANEL_API_TOKEN) -} - -internal val apiClient by lazy { - MixpanelAPI() -} - -internal val objectMapper by lazy { - jsonMapper { - addModule(kotlinModule()) - } -} - -fun initializeStatisticsClient(blockUsageStatistics: Boolean, vararg statisticClasses: KClass<*>) { - if (classesForStatistics != null) return - - blockSendUsageStatistics = blockUsageStatistics - classesForStatistics = statisticClasses.asList() -} diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Util.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Util.kt deleted file mode 100644 index daf1e97e5c..0000000000 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Util.kt +++ /dev/null @@ -1,26 +0,0 @@ -package flank.tool.analytics.mixpanel.internal - -import com.fasterxml.jackson.core.type.TypeReference -import java.util.UUID - -const val FIREBASE_TEST_LAB_RUN = "firebase test lab run" -const val APP_ID = "app_id" -const val DEVICE_TYPE = "device_type" -const val FLANK_VERSION = "flank_version" -const val FLANK_VERSION_PROPERTY = "version" -const val TEST_PLATFORM = "test_platform" - -const val FIREBASE = "firebase" -const val CORELLIUM = "corellium" - -const val ANDROID = "android" -const val IOS = "ios" - -const val SESSION_ID = "session.id" - -val sessionId by lazy { - UUID.randomUUID().toString() -} - -fun Any.objectToMap(): Map = - objectMapper.convertValue(this, object : TypeReference>() {}) diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/SendConfiguration.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/SendConfiguration.kt new file mode 100644 index 0000000000..b7e1baba12 --- /dev/null +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/SendConfiguration.kt @@ -0,0 +1,51 @@ +package flank.tool.analytics.mixpanel.internal + +import com.mixpanel.mixpanelapi.MessageBuilder +import com.mixpanel.mixpanelapi.MixpanelAPI +import flank.tool.analytics.mixpanel.Mixpanel +import org.json.JSONObject + +internal fun sendConfiguration( + project: String, + events: Map, + eventName: String +) { + !AnalyticsReport.blockSendUsageStatistics || return + project.isNotBlank() || return + listOf( + createUser(project), + createEvent(project, eventName, events), + ).forEach(apiClient::sendMessage) +} + +private fun createUser( + project: String +): JSONObject = + messageBuilder.set( + project, + JSONObject( + mapOf( + Mixpanel.PROJECT_ID to project, + Mixpanel.PROJECT_NAME to project + ) + ) + ) + +private fun createEvent( + projectId: String, + eventName: String, + data: Map +): JSONObject = + messageBuilder.event( + projectId, + eventName, + JSONObject(data.plus(Mixpanel.SESSION_ID to Mixpanel.sessionId)) + ) + +internal val messageBuilder by lazy { MessageBuilder(MIXPANEL_API_TOKEN) } + +internal val apiClient by lazy { MixpanelAPI() } + +private const val MIXPANEL_API_TOKEN = "d9728b2c8e6ca9fd6de1fcd32dd8cdc2" + + From 7c0dfd6bb9878e0507487088e324e90221f2a866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janek=20G=C3=B3ral?= Date: Tue, 3 Aug 2021 14:19:52 +0200 Subject: [PATCH 4/9] Refactor --- .../ftl/analytics/InitUsageStatistics.kt | 8 ++-- .../kotlin/ftl/analytics/SendConfiguration.kt | 19 ++++---- .../src/main/kotlin/ftl/args/AndroidArgs.kt | 2 + .../src/main/kotlin/ftl/args/IosArgs.kt | 1 + .../flank/tool/analytics/mixpanel/Mixpanel.kt | 22 +++++---- .../mixpanel/internal/AnalyticsReport.kt | 28 ----------- .../analytics/mixpanel/internal/Filter.kt | 46 +++++++++++++++++++ .../internal/{ObjectMapper.kt => Mapper.kt} | 5 +- .../analytics/mixpanel/internal/Report.kt | 36 +++++++++++++++ .../mixpanel/internal/StatisticDataFilters.kt | 44 ------------------ .../send/{SendConfiguration.kt => Send.kt} | 16 ++++--- 11 files changed, 126 insertions(+), 101 deletions(-) delete mode 100644 tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/AnalyticsReport.kt create mode 100644 tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt rename tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/{ObjectMapper.kt => Mapper.kt} (63%) create mode 100644 tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Report.kt delete mode 100644 tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/StatisticDataFilters.kt rename tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/{SendConfiguration.kt => Send.kt} (65%) diff --git a/test_runner/src/main/kotlin/ftl/analytics/InitUsageStatistics.kt b/test_runner/src/main/kotlin/ftl/analytics/InitUsageStatistics.kt index df6bb86c61..fd3c2a5277 100644 --- a/test_runner/src/main/kotlin/ftl/analytics/InitUsageStatistics.kt +++ b/test_runner/src/main/kotlin/ftl/analytics/InitUsageStatistics.kt @@ -1,16 +1,14 @@ package ftl.analytics -import flank.common.userHome import flank.tool.analytics.mixpanel.Mixpanel import ftl.args.AndroidArgs import ftl.args.IArgs import ftl.args.IosArgs -import ftl.util.isGoogleAnalyticsDisabled internal fun IArgs.initUsageStatistics() { - Mixpanel.configure(project) - Mixpanel.initializeStatisticsClient( - disableUsageStatistics || isGoogleAnalyticsDisabled(userHome), + Mixpanel.configure( + projectName = project, + blockUsageStatistics = disableUsageStatistics, AndroidArgs::class, IosArgs::class, IArgs::class diff --git a/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt b/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt index 76cded774d..c41393fadb 100644 --- a/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt +++ b/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt @@ -1,9 +1,11 @@ package ftl.analytics import flank.tool.analytics.mixpanel.Mixpanel +import flank.tool.analytics.mixpanel.Mixpanel.CONFIGURATION +import flank.tool.analytics.mixpanel.Mixpanel.DEVICE_TYPES import flank.tool.analytics.mixpanel.Mixpanel.add -import flank.tool.analytics.mixpanel.filterSensitiveValues -import flank.tool.analytics.mixpanel.objectToMap +import flank.tool.analytics.mixpanel.Mixpanel.removeSensitiveValues +import flank.tool.analytics.mixpanel.toMap import ftl.args.AndroidArgs import ftl.args.IArgs import ftl.args.IosArgs @@ -14,15 +16,15 @@ import ftl.util.readVersion fun AndroidArgs.reportConfiguration() { initUsageStatistics() addCommonData() - add(Mixpanel.CONFIGURATION, (toArgsMap() + commonArgs.toArgsMap()).filterSensitiveValues()) - add(Mixpanel.DEVICE_TYPES, devices.map { if (it.isVirtual) VIRTUAL_DEVICE else PHYSICAL_DEVICE }.distinct()) + add(CONFIGURATION, removeSensitiveValues(toMap() + commonArgs.toMap()/* - COMMON_ARGS*/)) // TODO verify JsonIgnore + add(DEVICE_TYPES, devices.map { if (it.isVirtual) VIRTUAL_DEVICE else PHYSICAL_DEVICE }.distinct()) } fun IosArgs.reportConfiguration() { initUsageStatistics() addCommonData() - add(Mixpanel.CONFIGURATION, (toArgsMap() + commonArgs.toArgsMap()).filterSensitiveValues()) - add(Mixpanel.DEVICE_TYPES, listOf(PHYSICAL_DEVICE)) + add(CONFIGURATION, removeSensitiveValues(toMap() + commonArgs.toMap()/* - COMMON_ARGS*/)) // TODO verify JsonIgnore + add(DEVICE_TYPES, listOf(PHYSICAL_DEVICE)) } fun IArgs.addCommonData() = let { @@ -33,6 +35,7 @@ fun IArgs.addCommonData() = let { add(Mixpanel.PROJECT_ID, project) } -private fun IArgs.toArgsMap() = objectToMap().filter { it.key != COMMON_ARGS } - +/** + * String name of [AndroidArgs.commonArgs] and [IosArgs.commonArgs], used to remove redundant nested data + */ private const val COMMON_ARGS = "commonArgs" diff --git a/test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt b/test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt index 571c445552..6a9da98ffa 100644 --- a/test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt +++ b/test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt @@ -1,5 +1,6 @@ package ftl.args +import com.fasterxml.jackson.annotation.JsonIgnore import flank.tool.analytics.AnonymizeInStatistics import flank.tool.analytics.IgnoreInStatistics import ftl.api.ShardChunks @@ -10,6 +11,7 @@ import ftl.run.model.AndroidTestShards import java.nio.file.Paths data class AndroidArgs( + @get:JsonIgnore val commonArgs: CommonArgs, @property:AnonymizeInStatistics diff --git a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt index 14fd195d55..e4ef41ef9d 100644 --- a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt +++ b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt @@ -12,6 +12,7 @@ import ftl.run.exception.FlankConfigurationError import java.nio.file.Paths data class IosArgs( + @get:JsonIgnore val commonArgs: CommonArgs, @property:AnonymizeInStatistics diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt index be2e65daa3..35b3b7324a 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt @@ -2,10 +2,9 @@ package flank.tool.analytics.mixpanel import flank.tool.analytics.mixpanel.internal.addToReport import flank.tool.analytics.mixpanel.internal.configureReport -import flank.tool.analytics.mixpanel.internal.filterSensitiveValues +import flank.tool.analytics.mixpanel.internal.removeSensitiveValues import flank.tool.analytics.mixpanel.internal.objectToMap import flank.tool.analytics.mixpanel.internal.removeNotNeededKeys -import flank.tool.analytics.mixpanel.internal.initStatisticsClient import flank.tool.analytics.mixpanel.internal.sendReport import java.util.UUID import kotlin.reflect.KClass @@ -29,16 +28,23 @@ object Mixpanel { val sessionId by lazy { UUID.randomUUID().toString() } - fun configure(projectName: String): Unit = configureReport(projectName) + fun configure( + projectName: String, + blockUsageStatistics: Boolean = false, + vararg statisticClasses: KClass<*> + ): Unit = configureReport( + projectName = projectName, + blockUsageStatistics = blockUsageStatistics, + statisticClasses = statisticClasses + ) + + fun removeSensitiveValues(map: ObjectMap): ObjectMap = map.removeNotNeededKeys().removeSensitiveValues() fun add(key: String, reportNode: Any): Unit = addToReport(key, reportNode) fun send(eventName: String): Unit = sendReport(eventName) - - fun initializeStatisticsClient(blockUsageStatistics: Boolean, vararg statisticClasses: KClass<*>): Unit = - initStatisticsClient(blockUsageStatistics, statisticClasses) } -fun Any.objectToMap(): Map = objectToMap() +fun Any.toMap(): ObjectMap = objectToMap() -fun Map.filterSensitiveValues() = removeNotNeededKeys().filterSensitiveValues() +typealias ObjectMap = Map diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/AnalyticsReport.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/AnalyticsReport.kt deleted file mode 100644 index 2df3c3b836..0000000000 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/AnalyticsReport.kt +++ /dev/null @@ -1,28 +0,0 @@ -package flank.tool.analytics.mixpanel.internal - -import kotlin.reflect.KClass - -internal object AnalyticsReport { - var projectName: String = "" - var blockSendUsageStatistics: Boolean = false - var classesForStatistics: List>? = null - val data: MutableMap = mutableMapOf() -} - -internal fun initStatisticsClient(blockUsageStatistics: Boolean, statisticClasses: Array>) { - if (AnalyticsReport.classesForStatistics != null) return - AnalyticsReport.blockSendUsageStatistics = blockUsageStatistics - AnalyticsReport.classesForStatistics = statisticClasses.asList() -} - -internal fun configureReport(projectName: String) { - AnalyticsReport.projectName = projectName -} - -internal fun addToReport(key: String, reportNode: Any) { - AnalyticsReport.data[key] = reportNode -} - -internal fun sendReport(eventName: String) { - sendConfiguration(AnalyticsReport.projectName, AnalyticsReport.data, eventName) -} diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt new file mode 100644 index 0000000000..7cc5568e7f --- /dev/null +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt @@ -0,0 +1,46 @@ +package flank.tool.analytics.mixpanel.internal + +import flank.tool.analytics.AnonymizeInStatistics +import flank.tool.analytics.IgnoreInStatistics +import flank.tool.analytics.mixpanel.ObjectMap +import kotlin.reflect.KCallable +import kotlin.reflect.KClass + +// ============================Remove not needed ============================ + +internal fun ObjectMap.removeNotNeededKeys(): ObjectMap = filterNot { (key, _) -> key in keysToRemove } + +private val keysToRemove by lazy { + getClassesForStatisticsOrThrow() + .map(findMembersWithAnnotation(IgnoreInStatistics::class)) + .flatten() +} + +// ============================ Remove sensitive ============================ + +internal fun ObjectMap.removeSensitiveValues(): ObjectMap = mapValues { (key, value) -> + when { + key !in keysToAnonymize -> value + value is Map<*, *> -> value.mapValues { ANONYMIZE_VALUE } + value is List<*> -> "Count: $size" + else -> ANONYMIZE_VALUE + } +} + +private val keysToAnonymize by lazy { + getClassesForStatisticsOrThrow() + .map(findMembersWithAnnotation(AnonymizeInStatistics::class)) + .flatten() +} + +private const val ANONYMIZE_VALUE = "..." + +// ============================ Common ============================ + +private fun getClassesForStatisticsOrThrow() = + (Report.classesForStatistics ?: throw NullPointerException("Analytics client should be initialized first")) + +private fun findMembersWithAnnotation(annotationType: KClass<*>) = fun KClass<*>.() = members + .filter { member -> member.annotations.any { annotation -> annotation.annotationClass == annotationType } } + .map(KCallable<*>::name) + diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/ObjectMapper.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Mapper.kt similarity index 63% rename from tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/ObjectMapper.kt rename to tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Mapper.kt index 1405a734b5..e7eeb3eb48 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/ObjectMapper.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Mapper.kt @@ -3,8 +3,9 @@ package flank.tool.analytics.mixpanel.internal import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.module.kotlin.jsonMapper import com.fasterxml.jackson.module.kotlin.kotlinModule +import flank.tool.analytics.mixpanel.ObjectMap -internal fun Any.objectToMap(): Map = - objectMapper.convertValue(this, object : TypeReference>() {}) +internal fun Any.objectToMap(): ObjectMap = + objectMapper.convertValue(this, object : TypeReference() {}) private val objectMapper by lazy { jsonMapper { addModule(kotlinModule()) } } diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Report.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Report.kt new file mode 100644 index 0000000000..064aed86d7 --- /dev/null +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Report.kt @@ -0,0 +1,36 @@ +package flank.tool.analytics.mixpanel.internal + +import flank.tool.analytics.mixpanel.internal.send.sendConfiguration +import kotlin.reflect.KClass + +internal object Report { + var projectName: String = "" + var blockSendUsageStatistics: Boolean = false + var classesForStatistics: List>? = null + val data: MutableMap = mutableMapOf() +} + +internal fun initStatisticsClient(blockUsageStatistics: Boolean, statisticClasses: Array>) { + // TODO Verify if condition is needed + if (Report.classesForStatistics != null) return + Report.blockSendUsageStatistics = blockUsageStatistics + Report.classesForStatistics = statisticClasses.asList() +} + +internal fun configureReport( + projectName: String, + blockUsageStatistics: Boolean, + statisticClasses: Array> +) { + Report.projectName = projectName + Report.blockSendUsageStatistics = blockUsageStatistics + Report.classesForStatistics = statisticClasses.asList() +} + +internal fun addToReport(key: String, reportNode: Any) { + Report.data[key] = reportNode +} + +internal fun sendReport(eventName: String) { + sendConfiguration(Report.projectName, Report.data, eventName) +} diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/StatisticDataFilters.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/StatisticDataFilters.kt deleted file mode 100644 index 1a2e082522..0000000000 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/StatisticDataFilters.kt +++ /dev/null @@ -1,44 +0,0 @@ -package flank.tool.analytics.mixpanel.internal - -import flank.tool.analytics.AnonymizeInStatistics -import flank.tool.analytics.IgnoreInStatistics -import kotlin.reflect.KClass - -internal fun Map.removeNotNeededKeys(): Map = - filterNot { (key, _) -> key in keysToRemove } - -internal fun Map.filterSensitiveValues(): Map = - mapValues { it.anonymousSensitiveValues() } - -private val keysToRemove by lazy { - getClassesForStatisticsOrThrow().map(findMembersWithAnnotation(IgnoreInStatistics::class)).flatten() -} - -private val keysToAnonymize by lazy { - getClassesForStatisticsOrThrow().map(findMembersWithAnnotation(AnonymizeInStatistics::class)).flatten() -} - -private fun getClassesForStatisticsOrThrow() = - (AnalyticsReport.classesForStatistics ?: throw NullPointerException("Analytics client should be initialized first")) - -private fun findMembersWithAnnotation( - annotationType: KClass<*> -): KClass<*>.() -> List = { - members.filter { member -> - member.annotations.any { annotation -> annotation.annotationClass == annotationType } - }.map { - it.name - } -} - -private fun Map.Entry.anonymousSensitiveValues() = - if (keysToAnonymize.contains(key)) value.toAnonymous() - else value - -private fun Any.toAnonymous(): Any = when (this) { - is Map<*, *> -> mapValues { ANONYMIZE_VALUE } - is List<*> -> "Count: $size" - else -> ANONYMIZE_VALUE -} - -private const val ANONYMIZE_VALUE = "..." diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/SendConfiguration.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/Send.kt similarity index 65% rename from tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/SendConfiguration.kt rename to tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/Send.kt index b7e1baba12..7c713b6fe5 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/SendConfiguration.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/Send.kt @@ -1,8 +1,12 @@ -package flank.tool.analytics.mixpanel.internal +package flank.tool.analytics.mixpanel.internal.send import com.mixpanel.mixpanelapi.MessageBuilder import com.mixpanel.mixpanelapi.MixpanelAPI -import flank.tool.analytics.mixpanel.Mixpanel +import flank.tool.analytics.mixpanel.Mixpanel.PROJECT_ID +import flank.tool.analytics.mixpanel.Mixpanel.PROJECT_NAME +import flank.tool.analytics.mixpanel.Mixpanel.SESSION_ID +import flank.tool.analytics.mixpanel.Mixpanel.sessionId +import flank.tool.analytics.mixpanel.internal.Report import org.json.JSONObject internal fun sendConfiguration( @@ -10,7 +14,7 @@ internal fun sendConfiguration( events: Map, eventName: String ) { - !AnalyticsReport.blockSendUsageStatistics || return + !Report.blockSendUsageStatistics || return project.isNotBlank() || return listOf( createUser(project), @@ -25,8 +29,8 @@ private fun createUser( project, JSONObject( mapOf( - Mixpanel.PROJECT_ID to project, - Mixpanel.PROJECT_NAME to project + PROJECT_ID to project, + PROJECT_NAME to project ) ) ) @@ -39,7 +43,7 @@ private fun createEvent( messageBuilder.event( projectId, eventName, - JSONObject(data.plus(Mixpanel.SESSION_ID to Mixpanel.sessionId)) + JSONObject(data + (SESSION_ID to sessionId)) ) internal val messageBuilder by lazy { MessageBuilder(MIXPANEL_API_TOKEN) } From 3a8ab090f17902e2a82909df0ff4b29651c32ed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janek=20G=C3=B3ral?= Date: Thu, 5 Aug 2021 09:27:31 +0200 Subject: [PATCH 5/9] Refactor --- .../flank/tool/analytics/mixpanel/Mixpanel.kt | 4 +- .../tool/analytics/mixpanel/internal/Add.kt | 5 ++ .../analytics/mixpanel/internal/Configure.kt | 29 +++++++++ .../analytics/mixpanel/internal/Filter.kt | 59 ++++++------------- .../analytics/mixpanel/internal/Report.kt | 34 ++--------- .../mixpanel/internal/{send => }/Send.kt | 22 +++---- 6 files changed, 67 insertions(+), 86 deletions(-) create mode 100644 tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Add.kt create mode 100644 tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Configure.kt rename tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/{send => }/Send.kt (69%) diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt index 35b3b7324a..1824f916f8 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt @@ -1,8 +1,8 @@ package flank.tool.analytics.mixpanel import flank.tool.analytics.mixpanel.internal.addToReport +import flank.tool.analytics.mixpanel.internal.anonymizeSensitiveValues import flank.tool.analytics.mixpanel.internal.configureReport -import flank.tool.analytics.mixpanel.internal.removeSensitiveValues import flank.tool.analytics.mixpanel.internal.objectToMap import flank.tool.analytics.mixpanel.internal.removeNotNeededKeys import flank.tool.analytics.mixpanel.internal.sendReport @@ -38,7 +38,7 @@ object Mixpanel { statisticClasses = statisticClasses ) - fun removeSensitiveValues(map: ObjectMap): ObjectMap = map.removeNotNeededKeys().removeSensitiveValues() + fun removeSensitiveValues(map: ObjectMap): ObjectMap = map.removeNotNeededKeys().anonymizeSensitiveValues() fun add(key: String, reportNode: Any): Unit = addToReport(key, reportNode) diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Add.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Add.kt new file mode 100644 index 0000000000..792128df91 --- /dev/null +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Add.kt @@ -0,0 +1,5 @@ +package flank.tool.analytics.mixpanel.internal + +internal fun addToReport(key: String, reportNode: Any) { + Report.data[key] = reportNode +} diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Configure.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Configure.kt new file mode 100644 index 0000000000..49bb60d4e5 --- /dev/null +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Configure.kt @@ -0,0 +1,29 @@ +package flank.tool.analytics.mixpanel.internal + +import flank.tool.analytics.AnonymizeInStatistics +import flank.tool.analytics.IgnoreInStatistics +import kotlin.reflect.KClass + +internal fun configureReport( + projectName: String, + blockUsageStatistics: Boolean, + statisticClasses: Array> +) { + Report.projectName = projectName + Report.blockSendUsageStatistics = blockUsageStatistics + Report.keysToRemove = statisticClasses getMembersWith AnonymizeInStatistics::class + Report.keysToAnonymize = statisticClasses getMembersWith IgnoreInStatistics::class +} + +private infix fun Array>.getMembersWith( + annotationType: KClass<*> +): Set = + flatMap { type -> + type.members.filter { member -> + member.annotations.any { annotation -> + annotation.annotationClass == annotationType + } + } + }.map { member -> + member.name + }.toSet() diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt index 7cc5568e7f..52e6f5fb9f 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt @@ -1,46 +1,23 @@ package flank.tool.analytics.mixpanel.internal -import flank.tool.analytics.AnonymizeInStatistics -import flank.tool.analytics.IgnoreInStatistics import flank.tool.analytics.mixpanel.ObjectMap -import kotlin.reflect.KCallable -import kotlin.reflect.KClass -// ============================Remove not needed ============================ - -internal fun ObjectMap.removeNotNeededKeys(): ObjectMap = filterNot { (key, _) -> key in keysToRemove } - -private val keysToRemove by lazy { - getClassesForStatisticsOrThrow() - .map(findMembersWithAnnotation(IgnoreInStatistics::class)) - .flatten() -} - -// ============================ Remove sensitive ============================ - -internal fun ObjectMap.removeSensitiveValues(): ObjectMap = mapValues { (key, value) -> - when { - key !in keysToAnonymize -> value - value is Map<*, *> -> value.mapValues { ANONYMIZE_VALUE } - value is List<*> -> "Count: $size" - else -> ANONYMIZE_VALUE +internal fun ObjectMap.removeNotNeededKeys( + keysToRemove: Set = Report.keysToAnonymize +): ObjectMap = + if (keysToRemove.isEmpty()) this + else filterNot { (key, _) -> key in Report.keysToRemove } + +internal fun ObjectMap.anonymizeSensitiveValues( + keysToAnonymize: Set = Report.keysToAnonymize, + anonymousValue: String = "...", +): ObjectMap = + if (keysToAnonymize.isEmpty()) this + else mapValues { (key, value) -> + when { + key !in keysToAnonymize -> value + value is Map<*, *> -> value.mapValues { anonymousValue } + value is List<*> -> "Count: ${value.size}" + else -> anonymousValue + } } -} - -private val keysToAnonymize by lazy { - getClassesForStatisticsOrThrow() - .map(findMembersWithAnnotation(AnonymizeInStatistics::class)) - .flatten() -} - -private const val ANONYMIZE_VALUE = "..." - -// ============================ Common ============================ - -private fun getClassesForStatisticsOrThrow() = - (Report.classesForStatistics ?: throw NullPointerException("Analytics client should be initialized first")) - -private fun findMembersWithAnnotation(annotationType: KClass<*>) = fun KClass<*>.() = members - .filter { member -> member.annotations.any { annotation -> annotation.annotationClass == annotationType } } - .map(KCallable<*>::name) - diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Report.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Report.kt index 064aed86d7..65a19fdb6c 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Report.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Report.kt @@ -1,36 +1,12 @@ package flank.tool.analytics.mixpanel.internal -import flank.tool.analytics.mixpanel.internal.send.sendConfiguration -import kotlin.reflect.KClass - internal object Report { + // Configuration var projectName: String = "" var blockSendUsageStatistics: Boolean = false - var classesForStatistics: List>? = null - val data: MutableMap = mutableMapOf() -} - -internal fun initStatisticsClient(blockUsageStatistics: Boolean, statisticClasses: Array>) { - // TODO Verify if condition is needed - if (Report.classesForStatistics != null) return - Report.blockSendUsageStatistics = blockUsageStatistics - Report.classesForStatistics = statisticClasses.asList() -} + var keysToRemove: Set = emptySet() + var keysToAnonymize: Set = emptySet() -internal fun configureReport( - projectName: String, - blockUsageStatistics: Boolean, - statisticClasses: Array> -) { - Report.projectName = projectName - Report.blockSendUsageStatistics = blockUsageStatistics - Report.classesForStatistics = statisticClasses.asList() -} - -internal fun addToReport(key: String, reportNode: Any) { - Report.data[key] = reportNode -} - -internal fun sendReport(eventName: String) { - sendConfiguration(Report.projectName, Report.data, eventName) + // Accumulated data + val data: MutableMap = mutableMapOf() } diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/Send.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Send.kt similarity index 69% rename from tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/Send.kt rename to tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Send.kt index 7c713b6fe5..b3143952b5 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/send/Send.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Send.kt @@ -1,4 +1,4 @@ -package flank.tool.analytics.mixpanel.internal.send +package flank.tool.analytics.mixpanel.internal import com.mixpanel.mixpanelapi.MessageBuilder import com.mixpanel.mixpanelapi.MixpanelAPI @@ -6,19 +6,16 @@ import flank.tool.analytics.mixpanel.Mixpanel.PROJECT_ID import flank.tool.analytics.mixpanel.Mixpanel.PROJECT_NAME import flank.tool.analytics.mixpanel.Mixpanel.SESSION_ID import flank.tool.analytics.mixpanel.Mixpanel.sessionId -import flank.tool.analytics.mixpanel.internal.Report import org.json.JSONObject -internal fun sendConfiguration( - project: String, - events: Map, - eventName: String +internal fun sendReport( + eventName: String, ) { !Report.blockSendUsageStatistics || return - project.isNotBlank() || return + Report.projectName.isNotBlank() || return listOf( - createUser(project), - createEvent(project, eventName, events), + createUser(Report.projectName), + createEvent(Report.projectName, eventName, Report.data), ).forEach(apiClient::sendMessage) } @@ -46,10 +43,7 @@ private fun createEvent( JSONObject(data + (SESSION_ID to sessionId)) ) -internal val messageBuilder by lazy { MessageBuilder(MIXPANEL_API_TOKEN) } - -internal val apiClient by lazy { MixpanelAPI() } +private val messageBuilder by lazy { MessageBuilder(MIXPANEL_API_TOKEN) } +private val apiClient by lazy { MixpanelAPI() } private const val MIXPANEL_API_TOKEN = "d9728b2c8e6ca9fd6de1fcd32dd8cdc2" - - From 9162a977f4d2220bbabe1fad85b67d4e5e3f857e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janek=20G=C3=B3ral?= Date: Thu, 5 Aug 2021 09:41:06 +0200 Subject: [PATCH 6/9] Revert unneeded change --- .../main/kotlin/ftl/adapter/google/GoogleTestMatrixAdapter.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/adapter/google/GoogleTestMatrixAdapter.kt b/test_runner/src/main/kotlin/ftl/adapter/google/GoogleTestMatrixAdapter.kt index 6c76314996..bb31be0710 100644 --- a/test_runner/src/main/kotlin/ftl/adapter/google/GoogleTestMatrixAdapter.kt +++ b/test_runner/src/main/kotlin/ftl/adapter/google/GoogleTestMatrixAdapter.kt @@ -3,6 +3,7 @@ package ftl.adapter.google import com.google.testing.model.FileReference import com.google.testing.model.TestExecution import com.google.testing.model.TestMatrix +import flank.common.toJSONObject import ftl.api.TestMatrix.Data import ftl.api.TestMatrix.Outcome import ftl.api.TestMatrix.SuiteOverview @@ -17,7 +18,6 @@ import ftl.util.getGcsRootBucket import ftl.util.timeoutToSeconds import ftl.util.webLink import ftl.util.webLinkWithoutExecutionDetails -import org.json.JSONObject fun TestMatrix.toApiModel(identity: ftl.api.TestMatrix.Identity? = null) = Data( projectId = projectId.orEmpty(), @@ -95,7 +95,7 @@ private fun TestMatrix.extractFileName(fileName: TestFilesPathWrapper.() -> Stri iosTestLoop ) .firstOrNull { it != null } - ?.let(::JSONObject) + ?.toJSONObject() ?.let { prettyPrint.fromJson(it.toString(), TestFilesPathWrapper::class.java).fileName() } ?.substringAfterLast('/') } From 90d2a8bd7d60d3ae180762825dbf2e47f2435420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janek=20G=C3=B3ral?= Date: Thu, 5 Aug 2021 11:35:20 +0200 Subject: [PATCH 7/9] Fix test --- .../src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt b/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt index eb8a3dea3b..a1cba33785 100644 --- a/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt +++ b/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt @@ -2,6 +2,7 @@ package ftl.analytics import com.google.common.truth.Truth.assertThat import flank.tool.analytics.mixpanel.Mixpanel +import flank.tool.analytics.mixpanel.toMap import ftl.args.AndroidArgs import ftl.test.util.FlankTestRunner import ftl.util.readVersion @@ -27,7 +28,7 @@ class UsageStatisticsTest { val default = AndroidArgs.default() val args = default.copy(environmentVariables = mapOf("testKey" to "testValue", "testKey2" to "testValue2")) args.initUsageStatistics() - val nonDefaultArgs = args.createEventMap() + val nonDefaultArgs = args.toMap() (nonDefaultArgs["environmentVariables"] as? Map<*, *>)?.let { environmentVariables -> assertThat(environmentVariables.count()).isEqualTo(2) assertThat(environmentVariables.values.all { it == "..." }).isTrue() From f842654e66a928a54aa8d464663a05d26f4de388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janek=20G=C3=B3ral?= Date: Thu, 5 Aug 2021 11:45:55 +0200 Subject: [PATCH 8/9] * Verify ignored value in unit test * Expand Mixpanel API --- .../kotlin/ftl/analytics/SendConfiguration.kt | 9 ++----- .../ftl/analytics/UsageStatisticsTest.kt | 26 +++++++++++++++++++ .../flank/tool/analytics/mixpanel/Mixpanel.kt | 5 ++++ .../tool/analytics/mixpanel/internal/Add.kt | 6 +++++ 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt b/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt index c41393fadb..a706483659 100644 --- a/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt +++ b/test_runner/src/main/kotlin/ftl/analytics/SendConfiguration.kt @@ -16,14 +16,14 @@ import ftl.util.readVersion fun AndroidArgs.reportConfiguration() { initUsageStatistics() addCommonData() - add(CONFIGURATION, removeSensitiveValues(toMap() + commonArgs.toMap()/* - COMMON_ARGS*/)) // TODO verify JsonIgnore + add(CONFIGURATION, removeSensitiveValues(toMap() + commonArgs.toMap())) add(DEVICE_TYPES, devices.map { if (it.isVirtual) VIRTUAL_DEVICE else PHYSICAL_DEVICE }.distinct()) } fun IosArgs.reportConfiguration() { initUsageStatistics() addCommonData() - add(CONFIGURATION, removeSensitiveValues(toMap() + commonArgs.toMap()/* - COMMON_ARGS*/)) // TODO verify JsonIgnore + add(CONFIGURATION, removeSensitiveValues(toMap() + commonArgs.toMap())) add(DEVICE_TYPES, listOf(PHYSICAL_DEVICE)) } @@ -34,8 +34,3 @@ fun IArgs.addCommonData() = let { add(Mixpanel.TEST_PLATFORM, Mixpanel.Platform.FIREBASE) add(Mixpanel.PROJECT_ID, project) } - -/** - * String name of [AndroidArgs.commonArgs] and [IosArgs.commonArgs], used to remove redundant nested data - */ -private const val COMMON_ARGS = "commonArgs" diff --git a/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt b/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt index a1cba33785..ae6e6fcdf9 100644 --- a/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt +++ b/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt @@ -4,6 +4,7 @@ import com.google.common.truth.Truth.assertThat import flank.tool.analytics.mixpanel.Mixpanel import flank.tool.analytics.mixpanel.toMap import ftl.args.AndroidArgs +import ftl.args.IosArgs import ftl.test.util.FlankTestRunner import ftl.util.readVersion import io.mockk.every @@ -12,6 +13,7 @@ import io.mockk.mockkStatic import io.mockk.unmockkAll import io.mockk.verify import org.junit.After +import org.junit.Assert.assertTrue import org.junit.Test import org.junit.runner.RunWith @@ -63,4 +65,28 @@ class UsageStatisticsTest { verify(inverse = true) { Mixpanel.send(any()) } } + + @Test + fun `should ignore commonArgs from AndroidArgs`() { + // given + val args = AndroidArgs.default() + + // when + val data = args.toMap() + + // then + assertTrue(args::commonArgs.name !in data) + } + + @Test + fun `should ignore commonArgs from IosArgs`() { + // given + val args = IosArgs.default() + + // when + val data = args.toMap() + + // then + assertTrue(args::commonArgs.name !in data) + } } diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt index 1824f916f8..1e6942b895 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/Mixpanel.kt @@ -22,6 +22,7 @@ object Mixpanel { object Platform { const val FIREBASE = "firebase" + const val CORELLIUM = "corellium" } const val schemaVersion = "1.0" @@ -42,6 +43,10 @@ object Mixpanel { fun add(key: String, reportNode: Any): Unit = addToReport(key, reportNode) + fun add(map: ObjectMap): Unit = addToReport(map) + + fun add(vararg entries: Pair): Unit = addToReport(entries.toMap()) + fun send(eventName: String): Unit = sendReport(eventName) } diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Add.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Add.kt index 792128df91..427cf7bb12 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Add.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Add.kt @@ -1,5 +1,11 @@ package flank.tool.analytics.mixpanel.internal +import flank.tool.analytics.mixpanel.ObjectMap + internal fun addToReport(key: String, reportNode: Any) { Report.data[key] = reportNode } + +internal fun addToReport(map: ObjectMap) { + Report.data += map +} From d9cf87595c42f9fcc62cfb51b2c2379add869500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janek=20G=C3=B3ral?= Date: Thu, 5 Aug 2021 11:56:38 +0200 Subject: [PATCH 9/9] Fix test --- .../src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt | 2 +- .../flank/tool/analytics/mixpanel/internal/Configure.kt | 4 ++-- .../kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt b/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt index ae6e6fcdf9..153d9be876 100644 --- a/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt +++ b/test_runner/src/test/kotlin/ftl/analytics/UsageStatisticsTest.kt @@ -30,7 +30,7 @@ class UsageStatisticsTest { val default = AndroidArgs.default() val args = default.copy(environmentVariables = mapOf("testKey" to "testValue", "testKey2" to "testValue2")) args.initUsageStatistics() - val nonDefaultArgs = args.toMap() + val nonDefaultArgs = Mixpanel.removeSensitiveValues(args.toMap()) (nonDefaultArgs["environmentVariables"] as? Map<*, *>)?.let { environmentVariables -> assertThat(environmentVariables.count()).isEqualTo(2) assertThat(environmentVariables.values.all { it == "..." }).isTrue() diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Configure.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Configure.kt index 49bb60d4e5..58dee02e9e 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Configure.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Configure.kt @@ -11,8 +11,8 @@ internal fun configureReport( ) { Report.projectName = projectName Report.blockSendUsageStatistics = blockUsageStatistics - Report.keysToRemove = statisticClasses getMembersWith AnonymizeInStatistics::class - Report.keysToAnonymize = statisticClasses getMembersWith IgnoreInStatistics::class + Report.keysToRemove = statisticClasses getMembersWith IgnoreInStatistics::class + Report.keysToAnonymize = statisticClasses getMembersWith AnonymizeInStatistics::class } private infix fun Array>.getMembersWith( diff --git a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt index 52e6f5fb9f..ca30ddd950 100644 --- a/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt +++ b/tool/analytics/mixpanel/src/main/kotlin/flank/tool/analytics/mixpanel/internal/Filter.kt @@ -3,10 +3,10 @@ package flank.tool.analytics.mixpanel.internal import flank.tool.analytics.mixpanel.ObjectMap internal fun ObjectMap.removeNotNeededKeys( - keysToRemove: Set = Report.keysToAnonymize + keysToRemove: Set = Report.keysToRemove ): ObjectMap = if (keysToRemove.isEmpty()) this - else filterNot { (key, _) -> key in Report.keysToRemove } + else filterNot { (key, _) -> key in keysToRemove } internal fun ObjectMap.anonymizeSensitiveValues( keysToAnonymize: Set = Report.keysToAnonymize,