Skip to content

Commit e0f3467

Browse files
authored
Emit metric event on telemetry opt-in/opt-out (#4622)
1 parent 44e2486 commit e0f3467

File tree

5 files changed

+79
-14
lines changed

5 files changed

+79
-14
lines changed

plugins/core/core/src/software/aws/toolkits/core/telemetry/TelemetryBatcher.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ interface TelemetryBatcher {
1919

2020
fun flush(retry: Boolean)
2121

22-
fun onTelemetryEnabledChanged(isEnabled: Boolean)
22+
fun onTelemetryEnabledChanged(isEnabled: Boolean, onChangeEvent: (Boolean) -> Unit = {})
2323

2424
fun shutdown()
2525
}
@@ -111,11 +111,19 @@ class DefaultTelemetryBatcher(
111111
}
112112
}
113113

114-
override fun onTelemetryEnabledChanged(isEnabled: Boolean) {
115-
isTelemetryEnabled.set(isEnabled)
116-
if (!isEnabled) {
114+
override fun onTelemetryEnabledChanged(isEnabled: Boolean, onChangeEvent: (Boolean) -> Unit) {
115+
if (isEnabled) {
116+
isTelemetryEnabled.set(true)
117+
} else {
117118
eventQueue.clear()
118119
}
120+
121+
onChangeEvent(isEnabled)
122+
flush(isEnabled)
123+
124+
if (!isEnabled) {
125+
isTelemetryEnabled.set(false)
126+
}
119127
}
120128

121129
companion object {

plugins/core/core/tst/software/aws/toolkits/core/telemetry/TelemetryBatcherTest.kt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ import org.mockito.kotlin.doThrow
1313
import org.mockito.kotlin.mock
1414
import org.mockito.kotlin.stub
1515
import org.mockito.kotlin.times
16+
import org.mockito.kotlin.verify
1617
import org.mockito.kotlin.verifyBlocking
1718
import org.mockito.kotlin.verifyNoMoreInteractions
1819
import org.mockito.stubbing.Answer
1920
import software.amazon.awssdk.core.exception.SdkServiceException
21+
import java.time.Instant
2022
import java.util.concurrent.CountDownLatch
2123
import java.util.concurrent.TimeUnit
2224

@@ -144,6 +146,45 @@ class TelemetryBatcherTest {
144146
assertThat(batcher.eventQueue).isEmpty()
145147
}
146148

149+
@Test
150+
fun verifyEnablementCallbackTrue() {
151+
val mockCallback: (Boolean) -> Unit = mock()
152+
153+
batcher.onTelemetryEnabledChanged(true, mockCallback)
154+
verify(mockCallback, times(1)).invoke(true)
155+
}
156+
157+
@Test
158+
fun verifyEnablementCallbackFalse() {
159+
val mockCallback: (Boolean) -> Unit = mock()
160+
161+
batcher.onTelemetryEnabledChanged(false, mockCallback)
162+
verify(mockCallback, times(1)).invoke(false)
163+
}
164+
165+
@Test
166+
fun verifyCallbackMetricPublished() {
167+
batcher.enqueue(createEmptyMetricEvent())
168+
val publishCountDown = CountDownLatch(1)
169+
val publishCaptor = argumentCaptor<Collection<MetricEvent>>()
170+
171+
publisher.stub {
172+
onBlocking { publisher.publish(publishCaptor.capture()) }
173+
.doAnswer(createPublishAnswer(publishCountDown))
174+
}
175+
176+
val fooMetricEvent = DefaultMetricEvent.builder()
177+
.createTime(Instant.now())
178+
.build()
179+
batcher.onTelemetryEnabledChanged(false) { batcher.enqueue(createEmptyMetricEvent()) }
180+
waitForPublish(publishCountDown)
181+
182+
verifyBlocking(publisher) { publish(anyCollection()) }
183+
184+
assertThat(publishCaptor.firstValue).hasSize(1)
185+
assertThat(publishCaptor.firstValue.contains(fooMetricEvent))
186+
}
187+
147188
private fun createEmptyMetricEvent(): MetricEvent = DefaultMetricEvent.builder().build()
148189

149190
private fun waitForPublish(publishCountDown: CountDownLatch) {

plugins/core/jetbrains-community/src/migration/software/aws/toolkits/jetbrains/services/telemetry/TelemetryService.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ abstract class TelemetryService(private val publisher: TelemetryPublisher, priva
7171
private fun ConnectionSettings.activeAwsAccountIfKnown(): String? = tryOrNull { this.getResourceIfPresent(StsResources.ACCOUNT) }
7272

7373
@Synchronized
74-
fun setTelemetryEnabled(isEnabled: Boolean) {
75-
batcher.onTelemetryEnabledChanged(isEnabled and TELEMETRY_ENABLED)
74+
fun setTelemetryEnabled(isEnabled: Boolean, onChangeEvent: (Boolean) -> Unit = {}) {
75+
batcher.onTelemetryEnabledChanged(isEnabled and TELEMETRY_ENABLED, onChangeEvent)
7676
}
7777

7878
fun addListener(listener: TelemetryListener) {

plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/settings/AwsSettings.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ import com.intellij.openapi.application.ApplicationManager
77
import com.intellij.openapi.components.PersistentStateComponent
88
import com.intellij.openapi.components.State
99
import com.intellij.openapi.components.Storage
10+
import com.intellij.openapi.project.Project
1011
import software.aws.toolkits.jetbrains.services.telemetry.TelemetryService
1112
import software.aws.toolkits.resources.message
1213
import software.aws.toolkits.telemetry.AwsTelemetry
14+
import software.aws.toolkits.telemetry.UiTelemetry
1315
import java.util.UUID
1416
import java.util.prefs.Preferences
1517

@@ -46,7 +48,10 @@ class DefaultAwsSettings : PersistentStateComponent<AwsConfiguration>, AwsSettin
4648
get() = state.isTelemetryEnabled ?: true
4749
set(value) {
4850
state.isTelemetryEnabled = value
49-
TelemetryService.getInstance().setTelemetryEnabled(value)
51+
val enablementElement = if (value) "aws_enabledTelemetry" else "aws_disabledTelemetry"
52+
TelemetryService.getInstance().setTelemetryEnabled(value) {
53+
UiTelemetry.click(null as Project?, enablementElement)
54+
}
5055
}
5156

5257
override var promptedForTelemetry: Boolean

plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/telemetry/TelemetryServiceTest.kt

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,10 @@ class TelemetryServiceTest {
7979

8080
val changeCountDown = CountDownLatch(1)
8181
val changeCaptor = argumentCaptor<Boolean>()
82+
val onChangeEventCaptor = argumentCaptor<(Boolean) -> Unit>()
8283

8384
val batcher = mock<TelemetryBatcher> {
84-
on { onTelemetryEnabledChanged(changeCaptor.capture()) }
85+
on { onTelemetryEnabledChanged(changeCaptor.capture(), onChangeEventCaptor.capture()) }
8586
.doAnswer {
8687
changeCountDown.countDown()
8788
}
@@ -90,7 +91,8 @@ class TelemetryServiceTest {
9091
TestTelemetryService(batcher = batcher)
9192

9293
changeCountDown.await(5, TimeUnit.SECONDS)
93-
verify(batcher).onTelemetryEnabledChanged(true)
94+
assertThat(onChangeEventCaptor.allValues).hasSize(1)
95+
verify(batcher).onTelemetryEnabledChanged(true, onChangeEventCaptor.firstValue)
9496
assertThat(changeCaptor.allValues).hasSize(1)
9597
assertThat(changeCaptor.firstValue).isEqualTo(true)
9698
}
@@ -101,24 +103,33 @@ class TelemetryServiceTest {
101103

102104
val changeCountDown = CountDownLatch(3)
103105
val changeCaptor = argumentCaptor<Boolean>()
106+
val onChangeEventCaptor = argumentCaptor<(Boolean) -> Unit>()
104107

105108
val batcher = mock<TelemetryBatcher>()
106109

107110
batcher.stub {
108-
on(batcher.onTelemetryEnabledChanged(changeCaptor.capture()))
111+
on(batcher.onTelemetryEnabledChanged(changeCaptor.capture(), onChangeEventCaptor.capture()))
109112
.doAnswer {
110113
changeCountDown.countDown()
111114
}
112115
}
113116

117+
val dummyEnabledEvent: (Boolean) -> Unit = {
118+
assertThat(it).isTrue()
119+
}
120+
val dummyDisabledEvent: (Boolean) -> Unit = {
121+
assertThat(it).isFalse()
122+
}
114123
val telemetryService = TestTelemetryService(batcher = batcher)
115124

116-
telemetryService.setTelemetryEnabled(false)
117-
telemetryService.setTelemetryEnabled(true)
125+
telemetryService.setTelemetryEnabled(false, dummyDisabledEvent)
126+
telemetryService.setTelemetryEnabled(true, dummyEnabledEvent)
118127

119128
changeCountDown.await(5, TimeUnit.SECONDS)
120-
verify(batcher, times(2)).onTelemetryEnabledChanged(true)
121-
verify(batcher).onTelemetryEnabledChanged(false)
129+
assertThat(onChangeEventCaptor.allValues).hasSize(3)
130+
verify(batcher).onTelemetryEnabledChanged(true, onChangeEventCaptor.firstValue)
131+
verify(batcher).onTelemetryEnabledChanged(true, dummyEnabledEvent)
132+
verify(batcher).onTelemetryEnabledChanged(false, dummyDisabledEvent)
122133
assertThat(changeCaptor.allValues).hasSize(3)
123134
assertThat(changeCaptor.firstValue).isEqualTo(true)
124135
assertThat(changeCaptor.secondValue).isEqualTo(false)

0 commit comments

Comments
 (0)