Skip to content

Commit 17f780b

Browse files
kceiwdcaro
andauthored
Correlate the suggestion related events (#14041)
* Correlate the suggestion related events. - Collects the event when our suggestion is displayed. - Use SuggestionSessionId to correlate the suggestions that are provided by us, displayed by PSReadLine, and accepted by the user. - Collects the client id in the telemetry events to identify if it's called by PSReadLine or something else. * Update the version. * Use new api. * Guard against when the display mode is not known. * Fix the package and a bug - Use the preview packages that contain the change. - Fix a bug that the loop infinitely when parsing the parameter values and the last parameter is a switch parameter. * Rename the variable UserId to HashUserId. * Updated release notes * Added ChangeLog.md * Remove the binaries that're added accidentally. * Fixed typo in changelog * Fix the broken merge. * Fix the merge. * Remove the test version suffix. * Add a new field to the telemetry. * Update the psreadline binaries. * Update README.md Updated README to reflect on the change of versions. * Update Az.Tools.Predictor.psd1 Updated version requirements and addressed release notes comments. * Update the doc. * Update the link to dotnet 6.0 * Fix the list number. * Remove .NET 6 Co-authored-by: Damien Caro <[email protected]>
1 parent bed48d3 commit 17f780b

32 files changed

+1610
-242
lines changed

tools/Az.Tools.Predictor/Az.Tools.Predictor.Test/Az.Tools.Predictor.Test.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net5.0</TargetFramework>
4+
<TargetFramework>net6.0</TargetFramework>
55
<AssemblyName>Microsoft.Azure.PowerShell.Tools.AzPredictor.Test</AssemblyName>
66
<RootNamespace>Microsoft.Azure.PowerShell.Tools.AzPredictor.Test</RootNamespace>
77
<IsPackable>false</IsPackable>
@@ -14,7 +14,6 @@
1414
</PropertyGroup>
1515

1616
<ItemGroup>
17-
<PackageReference Include="System.Management.Automation" Version="7.1.0-preview.7" />
1817
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
1918
<PackageReference Include="xunit" Version="2.4.1" />
2019
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">

tools/Az.Tools.Predictor/Az.Tools.Predictor.Test/AzPredictorTelemetryTests.cs

Lines changed: 787 additions & 0 deletions
Large diffs are not rendered by default.

tools/Az.Tools.Predictor/Az.Tools.Predictor.Test/AzPredictorTests.cs

Lines changed: 53 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using System.Linq;
1818
using System.Management.Automation.Subsystem;
1919
using System.Threading;
20+
using System.Threading.Tasks;
2021
using Xunit;
2122

2223
namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Test
@@ -27,6 +28,7 @@ namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Test
2728
[Collection("Model collection")]
2829
public sealed class AzPredictorTests
2930
{
31+
private const string AzPredictorClient = "Test";
3032
private readonly ModelFixture _fixture;
3133
private readonly MockAzPredictorTelemetryClient _telemetryClient;
3234
private readonly MockAzPredictorService _service;
@@ -54,65 +56,66 @@ public AzPredictorTests(ModelFixture modelFixture)
5456
/// Verify we replace unsupported command with <see cref="AzPredictorConstants.CommandPlaceholder"/>.
5557
/// </summary>
5658
[Fact]
57-
public void VerifyRequestPredictionForOneUnsupportedCommandInHistory()
59+
public async Task VerifyRequestPredictionForOneUnsupportedCommandInHistory()
5860
{
5961
IReadOnlyList<string> history = new List<string>()
6062
{
6163
"git status"
6264
};
6365

64-
_telemetryClient.RecordedSuggestion = null;
6566
_service.Commands = null;
6667
_service.History = null;
68+
_service.ResetRequestPredictionTask();
6769

68-
_azPredictor.StartEarlyProcessing(history);
70+
_azPredictor.StartEarlyProcessing(AzPredictorTests.AzPredictorClient, history);
71+
await _service.RequestPredictionTaskCompletionSource.Task;
6972

7073
Assert.Equal(new List<string>() { AzPredictorConstants.CommandPlaceholder, AzPredictorConstants.CommandPlaceholder }, _service.Commands);
71-
Assert.Equal(AzPredictorConstants.CommandPlaceholder, _telemetryClient.RecordedSuggestion.HistoryLine);
7274
Assert.Null(_service.History);
7375
}
7476

7577
/// <summary>
7678
/// Verify that we masked the supported command in requesting prediction and telemetry.
7779
/// </summary>
7880
[Fact]
79-
public void VerifyRequestPredictionForOneSupportedCommandInHistory()
81+
public async Task VerifyRequestPredictionForOneSupportedCommandInHistory()
8082
{
8183
IReadOnlyList<string> history = new List<string>()
8284
{
8385
"New-AzVM -Name hello -Location WestUS"
8486
};
8587

86-
_telemetryClient.RecordedSuggestion = null;
8788
_service.Commands = null;
8889
_service.History = null;
90+
_service.ResetRequestPredictionTask();
8991

90-
_azPredictor.StartEarlyProcessing(history);
92+
_azPredictor.StartEarlyProcessing(AzPredictorTests.AzPredictorClient, history);
93+
await _service.RequestPredictionTaskCompletionSource.Task;
9194

9295
string maskedCommand = "New-AzVM -Location *** -Name ***";
9396

9497
Assert.Equal(new List<string>() { AzPredictorConstants.CommandPlaceholder, maskedCommand }, _service.Commands);
95-
Assert.Equal(maskedCommand, _telemetryClient.RecordedSuggestion.HistoryLine);
9698
Assert.Equal(history[0], _service.History.ToString());
9799
}
98100

99101
/// <summary>
100102
/// Verify that we can handle the two supported command in sequences.
101103
/// </summary>
102104
[Fact]
103-
public void VerifyRequestPredictionForTwoSupportedCommandInHistory()
105+
public async Task VerifyRequestPredictionForTwoSupportedCommandInHistory()
104106
{
105107
IReadOnlyList<string> history = new List<string>()
106108
{
107109
"New-AzResourceGroup -Name 'resourceGroup01'",
108110
"New-AzVM -Name:hello -Location:WestUS"
109111
};
110112

111-
_telemetryClient.RecordedSuggestion = null;
112113
_service.Commands = null;
113114
_service.History = null;
115+
_service.ResetRequestPredictionTask();
114116

115-
_azPredictor.StartEarlyProcessing(history);
117+
_azPredictor.StartEarlyProcessing(AzPredictorTests.AzPredictorClient, history);
118+
await _service.RequestPredictionTaskCompletionSource.Task;
116119

117120
var maskedCommands = new List<string>()
118121
{
@@ -121,27 +124,27 @@ public void VerifyRequestPredictionForTwoSupportedCommandInHistory()
121124
};
122125

123126
Assert.Equal(maskedCommands, _service.Commands);
124-
Assert.Equal(maskedCommands[1], _telemetryClient.RecordedSuggestion.HistoryLine);
125127
Assert.Equal(history[1], _service.History.ToString());
126128
}
127129

128130
/// <summary>
129131
/// Verify that we can handle the two unsupported command in sequences.
130132
/// </summary>
131133
[Fact]
132-
public void VerifyRequestPredictionForTwoUnsupportedCommandInHistory()
134+
public async Task VerifyRequestPredictionForTwoUnsupportedCommandInHistory()
133135
{
134136
IReadOnlyList<string> history = new List<string>()
135137
{
136138
"git status",
137139
@"$a='ResourceGroup01'",
138140
};
139141

140-
_telemetryClient.RecordedSuggestion = null;
141142
_service.Commands = null;
142143
_service.History = null;
144+
_service.ResetRequestPredictionTask();
143145

144-
_azPredictor.StartEarlyProcessing(history);
146+
_azPredictor.StartEarlyProcessing(AzPredictorTests.AzPredictorClient, history);
147+
await _service.RequestPredictionTaskCompletionSource.Task;
145148

146149
var maskedCommands = new List<string>()
147150
{
@@ -150,33 +153,37 @@ public void VerifyRequestPredictionForTwoUnsupportedCommandInHistory()
150153
};
151154

152155
Assert.Equal(maskedCommands, _service.Commands);
153-
Assert.Equal(maskedCommands[1], _telemetryClient.RecordedSuggestion.HistoryLine);
154156
Assert.Null(_service.History);
155157
}
156158

157159
/// <summary>
158160
/// Verify that we skip the unsupported commands.
159161
/// </summary>
160162
[Fact]
161-
public void VerifyNotTakeUnsupportedCommands()
163+
public async Task VerifyNotTakeUnsupportedCommands()
162164
{
163165
var history = new List<string>()
164166
{
165167
"New-AzResourceGroup -Name:resourceGroup01",
166168
"New-AzVM -Name hello -Location WestUS"
167169
};
168170

169-
_telemetryClient.RecordedSuggestion = null;
170171
_service.Commands = null;
171172
_service.History = null;
173+
_service.ResetRequestPredictionTask();
172174

173-
_azPredictor.StartEarlyProcessing(history);
175+
_azPredictor.StartEarlyProcessing(AzPredictorTests.AzPredictorClient, history);
176+
await _service.RequestPredictionTaskCompletionSource.Task;
174177

178+
_service.ResetRequestPredictionTask();
175179
history.Add("git status");
176-
_azPredictor.StartEarlyProcessing(history);
180+
_azPredictor.StartEarlyProcessing(AzPredictorTests.AzPredictorClient, history);
181+
// Don't need to await on _service.RequestPredictionTask, because "git" isn't a supported command and RequestPredictionsAsync isn't called.
177182

183+
_service.ResetRequestPredictionTask();
178184
history.Add(@"$a='NewResourceName'");
179-
_azPredictor.StartEarlyProcessing(history);
185+
_azPredictor.StartEarlyProcessing(AzPredictorTests.AzPredictorClient, history);
186+
// Don't need to await on _service.RequestPredictionTask, because assignment isn't supported and RequestPredictionsAsync isn't called.
180187

181188
// We don't take the last two unsupported command to request predictions.
182189
// But we send the masked one in telemetry.
@@ -188,13 +195,14 @@ public void VerifyNotTakeUnsupportedCommands()
188195
};
189196

190197
Assert.Equal(maskedCommands, _service.Commands);
191-
Assert.Equal(AzPredictorConstants.CommandPlaceholder, _telemetryClient.RecordedSuggestion.HistoryLine);
192198
Assert.Equal(history[1], _service.History.ToString());
193199

194200
// When there is a new supported command, we'll use that for prediction.
195201

202+
_service.ResetRequestPredictionTask();
196203
history.Add("Get-AzResourceGroup -Name ResourceGroup01");
197-
_azPredictor.StartEarlyProcessing(history);
204+
_azPredictor.StartEarlyProcessing(AzPredictorTests.AzPredictorClient, history);
205+
await _service.RequestPredictionTaskCompletionSource.Task;
198206

199207
maskedCommands = new List<string>()
200208
{
@@ -203,30 +211,32 @@ public void VerifyNotTakeUnsupportedCommands()
203211
};
204212

205213
Assert.Equal(maskedCommands, _service.Commands);
206-
Assert.Equal(maskedCommands[1], _telemetryClient.RecordedSuggestion.HistoryLine);
207214
Assert.Equal(history.Last(), _service.History.ToString());
208215
}
209216

210217
/// <summary>
211218
/// Verify that we handle the three supported command in the same order.
212219
/// </summary>
213220
[Fact]
214-
public void VerifyThreeSupportedCommands()
221+
public async Task VerifyThreeSupportedCommands()
215222
{
216223
var history = new List<string>()
217224
{
218225
"New-AzResourceGroup -Name resourceGroup01",
219226
"New-AzVM -Name:hello -Location:WestUS"
220227
};
221228

222-
_telemetryClient.RecordedSuggestion = null;
223229
_service.Commands = null;
224230
_service.History = null;
231+
_service.ResetRequestPredictionTask();
225232

226-
_azPredictor.StartEarlyProcessing(history);
233+
_azPredictor.StartEarlyProcessing(AzPredictorTests.AzPredictorClient, history);
234+
await _service.RequestPredictionTaskCompletionSource.Task;
227235

236+
_service.ResetRequestPredictionTask();
228237
history.Add("Get-AzResourceGroup -Name resourceGroup01");
229-
_azPredictor.StartEarlyProcessing(history);
238+
_azPredictor.StartEarlyProcessing(AzPredictorTests.AzPredictorClient, history);
239+
await _service.RequestPredictionTaskCompletionSource.Task;
230240

231241
var maskedCommands = new List<string>()
232242
{
@@ -235,27 +245,27 @@ public void VerifyThreeSupportedCommands()
235245
};
236246

237247
Assert.Equal(maskedCommands, _service.Commands);
238-
Assert.Equal(maskedCommands[1], _telemetryClient.RecordedSuggestion.HistoryLine);
239248
Assert.Equal(history.Last(), _service.History.ToString());
240249
}
241250

242251
/// <summary>
243252
/// Verify that we handle the sequence of one unsupported command and one supported command.
244253
/// </summary>
245254
[Fact]
246-
public void VerifyUnsupportedAndSupportedCommands()
255+
public async Task VerifyUnsupportedAndSupportedCommands()
247256
{
248257
var history = new List<string>()
249258
{
250259
"git status",
251260
"New-AzVM -Name:hello -Location:WestUS"
252261
};
253262

254-
_telemetryClient.RecordedSuggestion = null;
255263
_service.Commands = null;
256264
_service.History = null;
265+
_service.ResetRequestPredictionTask();
257266

258-
_azPredictor.StartEarlyProcessing(history);
267+
_azPredictor.StartEarlyProcessing(AzPredictorTests.AzPredictorClient, history);
268+
await _service.RequestPredictionTaskCompletionSource.Task;
259269

260270
var maskedCommands = new List<string>()
261271
{
@@ -264,27 +274,27 @@ public void VerifyUnsupportedAndSupportedCommands()
264274
};
265275

266276
Assert.Equal(maskedCommands, _service.Commands);
267-
Assert.Equal(maskedCommands[1], _telemetryClient.RecordedSuggestion.HistoryLine);
268277
Assert.Equal(history.Last(), _service.History.ToString());
269278
}
270279

271280
/// <summary>
272281
/// Verify that we handle the sequence of one supported command and one unsupported command.
273282
/// </summary>
274283
[Fact]
275-
public void VerifySupportedAndUnsupportedCommands()
284+
public async Task VerifySupportedAndUnsupportedCommands()
276285
{
277286
var history = new List<string>()
278287
{
279288
"New-AzVM -Name hello -Location WestUS",
280289
"git status",
281290
};
282291

283-
_telemetryClient.RecordedSuggestion = null;
284292
_service.Commands = null;
285293
_service.History = null;
294+
_service.ResetRequestPredictionTask();
286295

287-
_azPredictor.StartEarlyProcessing(history);
296+
_azPredictor.StartEarlyProcessing(AzPredictorTests.AzPredictorClient, history);
297+
await _service.RequestPredictionTaskCompletionSource.Task;
288298

289299
var maskedCommands = new List<string>()
290300
{
@@ -293,7 +303,6 @@ public void VerifySupportedAndUnsupportedCommands()
293303
};
294304

295305
Assert.Equal(maskedCommands, _service.Commands);
296-
Assert.Equal(AzPredictorConstants.CommandPlaceholder, _telemetryClient.RecordedSuggestion.HistoryLine);
297306
Assert.Equal(history.First(), _service.History.ToString());
298307
}
299308

@@ -307,10 +316,10 @@ public void VerifySuggestion(string userInput)
307316
{
308317
var predictionContext = PredictionContext.Create(userInput);
309318
var expected = this._service.GetSuggestion(predictionContext, 1, 1, CancellationToken.None);
310-
var actual = this._azPredictor.GetSuggestion(predictionContext, CancellationToken.None);
319+
var actual = this._azPredictor.GetSuggestion(AzPredictorTests.AzPredictorClient, predictionContext, CancellationToken.None);
311320

312-
Assert.Equal(expected.Count, actual.Count);
313-
Assert.Equal(expected.PredictiveSuggestions.First().SuggestionText, actual.First().SuggestionText);
321+
Assert.Equal(expected.Count, actual.SuggestionEntries.Count);
322+
Assert.Equal(expected.PredictiveSuggestions.First().SuggestionText, actual.SuggestionEntries.First().SuggestionText);
314323
}
315324

316325
/// <summary>
@@ -331,9 +340,9 @@ public void VerifySuggestionOnIncompleteCommand()
331340
var expected = "New-AzResourceGroup -Name 'ResourceGroup01' -Location 'Central US' -WhatIf -Tag value1";
332341

333342
var predictionContext = PredictionContext.Create(userInput);
334-
var actual = localAzPredictor.GetSuggestion(predictionContext, CancellationToken.None);
343+
var actual = localAzPredictor.GetSuggestion(AzPredictorTests.AzPredictorClient, predictionContext, CancellationToken.None);
335344

336-
Assert.Equal(expected, actual.First().SuggestionText);
345+
Assert.Equal(expected, actual.SuggestionEntries.First().SuggestionText);
337346
}
338347

339348
/// <summary>
@@ -348,9 +357,9 @@ public void VerifySuggestionOnIncompleteCommand()
348357
public void VerifyMalFormattedCommandLine(string userInput)
349358
{
350359
var predictionContext = PredictionContext.Create(userInput);
351-
var actual = _azPredictor.GetSuggestion(predictionContext, CancellationToken.None);
360+
var actual = _azPredictor.GetSuggestion(AzPredictorTests.AzPredictorClient, predictionContext, CancellationToken.None);
352361

353-
Assert.Empty(actual);
362+
Assert.Null(actual.SuggestionEntries);
354363
}
355364
}
356365
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
17+
namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Test.Mocks
18+
{
19+
sealed class MockAzContext : IAzContext
20+
{
21+
public string HashUserId => "TestUserId";
22+
23+
public string MacAddress => "TestMacAddress";
24+
25+
public string OSVersion => "TestOSVersion";
26+
27+
public Version PowerShellVersion => Version.Parse("0.0.0.0");
28+
29+
public Version ModuleVersion => Version.Parse("0.0.0.0");
30+
31+
public Version AzVersion => Version.Parse("0.0.0.0");
32+
33+
public bool IsInternal => true;
34+
35+
public void UpdateContext()
36+
{
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)