From 4a0eda7fa9044e2f281f2be7a7f2bef3953d60d9 Mon Sep 17 00:00:00 2001 From: "James Truher [MSFT]" Date: Tue, 11 Feb 2020 11:40:43 -0800 Subject: [PATCH] Handle cases where `CustomEvent` was not initially sent (#11807) --- .../utils/Telemetry.cs | 11 ++++++++ .../engine/Basic/Telemetry.Tests.ps1 | 25 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/System.Management.Automation/utils/Telemetry.cs b/src/System.Management.Automation/utils/Telemetry.cs index bf4f0be1f5..14431a0c14 100644 --- a/src/System.Management.Automation/utils/Telemetry.cs +++ b/src/System.Management.Automation/utils/Telemetry.cs @@ -87,6 +87,9 @@ namespace Microsoft.PowerShell.Telemetry // the session identifier private static string s_sessionId { get; set; } + // private semaphore to determine whether we sent the startup telemetry event + private static int s_startupEventSent = 0; + /// Use a hashset for quick lookups. /// We send telemetry only a known set of modules. /// If it's not in the list (initialized in the static constructor), then we report anonymous. @@ -583,6 +586,8 @@ namespace Microsoft.PowerShell.Telemetry return; } + SendPSCoreStartupTelemetry("hosted"); + string metricName = metricId.ToString(); try { @@ -645,6 +650,12 @@ namespace Microsoft.PowerShell.Telemetry /// The "mode" of the startup. internal static void SendPSCoreStartupTelemetry(string mode) { + // Check if we already sent startup telemetry + if (Interlocked.CompareExchange(ref s_startupEventSent, 1, 0) == 1) + { + return; + } + if (!CanSendTelemetry) { return; diff --git a/test/powershell/engine/Basic/Telemetry.Tests.ps1 b/test/powershell/engine/Basic/Telemetry.Tests.ps1 index 5a0ee2d2d2..b07ba07c30 100644 --- a/test/powershell/engine/Basic/Telemetry.Tests.ps1 +++ b/test/powershell/engine/Basic/Telemetry.Tests.ps1 @@ -128,4 +128,29 @@ Describe "Telemetry for shell startup" -Tag CI { $result = & $PWSH -NoProfile -Command '[Microsoft.PowerShell.Telemetry.ApplicationInsightsTelemetry]::CanSendTelemetry' $result | Should -Be $expectedValue } + + It "Should resend startup event if the semaphore says we haven't sent telemetry" { + + $resultJson = & $PWSH -NoProfile -c { + $telemetryType = [Microsoft.PowerShell.Telemetry.ApplicationInsightsTelemetry] + $bindingFlags = [System.Reflection.BindingFlags]"NonPublic,Static" + $initialValue = ${telemetryType}.GetMember("s_startupEventSent", $bindingFlags)[0].GetValue($null) + # force a resend of the startup telemetry + $null = ${telemetryType}.GetMember("s_startupEventSent", $bindingFlags)[0].SetValue($null,0) + $null = Get-Date | Out-String + # now check it again, it should be true now that something has executed + $finalValue = ${telemetryType}.GetMember("s_startupEventSent", $bindingFlags)[0].GetValue($null) + @{ + initialValue = $initialValue + finalValue = $finalValue + } | ConvertTo-Json -Compress + } + + $result = $resultJson | ConvertFrom-Json + + $result.InitialValue | Should -Be 1 -Because "Should have sent telemetry on console startup" + + $result.FinalValue | Should -Be 1 -Because "Should have resent telemetry" + } + }