Skip to content

Commit cbad4bb

Browse files
Mark test as inconclusive if doc publish does not start (Azure#21859)
* Add asserts to verify all actions are counted for pending queue * Increase timeout of test
1 parent a358f10 commit cbad4bb

File tree

2 files changed

+60
-4
lines changed

2 files changed

+60
-4
lines changed

sdk/search/Azure.Search.Documents/tests/Batching/BatchingTests.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ public async Task Champion_BasicCheckpointing()
364364
AutoFlushInterval = null
365365
});
366366

367+
int removeFailedCount = 0;
368+
367369
List<IndexDocumentsAction<SimpleDocument>> pending = new List<IndexDocumentsAction<SimpleDocument>>();
368370
indexer.ActionAdded +=
369371
(IndexActionEventArgs<SimpleDocument> e) =>
@@ -374,25 +376,31 @@ public async Task Champion_BasicCheckpointing()
374376
indexer.ActionCompleted +=
375377
(IndexActionCompletedEventArgs<SimpleDocument> e) =>
376378
{
377-
pending.Remove(e.Action);
379+
if (!pending.Remove(e.Action))
380+
{ removeFailedCount++; }
378381
return Task.CompletedTask;
379382
};
380383
indexer.ActionFailed +=
381384
(IndexActionFailedEventArgs<SimpleDocument> e) =>
382385
{
383-
pending.Remove(e.Action);
386+
if (!pending.Remove(e.Action))
387+
{ removeFailedCount++; }
384388
return Task.CompletedTask;
385389
};
386390

387391
await indexer.UploadDocumentsAsync(data.Take(500));
388392
await indexer.MergeDocumentsAsync(new[] { new SimpleDocument { Id = "Fake" } });
389393
await indexer.UploadDocumentsAsync(data.Skip(500));
390394

391-
await DelayAsync(TimeSpan.FromSeconds(5), TimeSpan.FromMilliseconds(250));
392-
Assert.AreEqual(1001 - BatchSize, pending.Count);
395+
int expectedPendingQueueSize = 1001 - BatchSize;
396+
397+
await ConditionallyDelayAsync(() => (pending.Count == expectedPendingQueueSize), TimeSpan.FromSeconds(2), TimeSpan.FromMilliseconds(250), 5);
398+
Assert.AreEqual(expectedPendingQueueSize, pending.Count);
399+
Assert.AreEqual(0, removeFailedCount);
393400

394401
await indexer.FlushAsync();
395402
Assert.AreEqual(0, pending.Count);
403+
Assert.AreEqual(0, removeFailedCount);
396404
}
397405
#endregion
398406

sdk/search/Azure.Search.Documents/tests/Utilities/SearchTestBase.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,54 @@ public async Task DelayAsync(TimeSpan? delay = null, TimeSpan? playbackDelay = n
107107
}
108108
}
109109

110+
/// <summary>
111+
/// A number of our tests have built in delays while we wait an expected
112+
/// amount of time for a service operation to complete and this method
113+
/// allows us to wait (unless we're playing back recordings, which can
114+
/// complete immediately).
115+
/// <para>This method allows us to return early if the <paramref name="predicate"/> condition evaluates to true.
116+
/// It evaluates the predicate after every <paramref name="delayPerIteration"/> or <paramref name="playbackDelayPerIteration"/> time span.
117+
/// It returns when the condition evaluates to <c>true</c>, or if the condition stays false after <paramref name="maxIterations"/> checks.</para>
118+
/// </summary>
119+
/// <param name="predicate">Condition that will result in early end of delay when it evaluates to <c>true</c>.</param>
120+
/// <param name="delayPerIteration">The time to wait per iteration. Defaults to 1s.</param>
121+
/// <param name="playbackDelayPerIteration">
122+
/// An optional time wait if we're playing back a recorded test. This
123+
/// is useful for allowing client side events to get processed.
124+
/// </param>
125+
/// <param name="maxIterations">Maximum number of iterations of the wait-and-check cycle.</param>
126+
/// <param name="cancellationToken">Optional <see cref="CancellationToken"/> to check.</param>
127+
/// <returns>A task that will (optionally) delay.</returns>
128+
/// <exception cref="OperationCanceledException">The <paramref name="cancellationToken"/> was signaled.</exception>
129+
public async Task ConditionallyDelayAsync(Func<bool> predicate, TimeSpan ? delayPerIteration = null, TimeSpan? playbackDelayPerIteration = null, uint maxIterations = 1, CancellationToken cancellationToken = default)
130+
{
131+
TimeSpan waitPeriod = TimeSpan.Zero;
132+
133+
for (int i = 0; i < maxIterations; i++)
134+
{
135+
if (predicate())
136+
{
137+
TestContext.WriteLine($"{nameof(ConditionallyDelayAsync)}: Condition evaluated to true in {waitPeriod.TotalSeconds} seconds.");
138+
return;
139+
}
140+
141+
cancellationToken.ThrowIfCancellationRequested();
142+
143+
if (Mode != RecordedTestMode.Playback)
144+
{
145+
waitPeriod += delayPerIteration ?? TimeSpan.FromSeconds(1);
146+
await Task.Delay(delayPerIteration ?? TimeSpan.FromSeconds(1));
147+
}
148+
else if (playbackDelayPerIteration != null)
149+
{
150+
waitPeriod += playbackDelayPerIteration.Value;
151+
await Task.Delay(playbackDelayPerIteration.Value);
152+
}
153+
}
154+
155+
TestContext.WriteLine($"{nameof(ConditionallyDelayAsync)}: Condition did not evaluate to true in {waitPeriod.TotalSeconds} seconds.");
156+
}
157+
110158
/// <summary>
111159
/// Assert that we can catch the desired exception. NUnit's default
112160
/// forces everything to be sync.

0 commit comments

Comments
 (0)