Skip to content

Commit dbd0db0

Browse files
committed
fix flaky test
1 parent 5ce7767 commit dbd0db0

File tree

1 file changed

+51
-12
lines changed

1 file changed

+51
-12
lines changed

Diff for: tests/NRedisStack.Tests/Search/SearchTests.cs

+51-12
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
using System.Runtime.InteropServices;
99
using NetTopologySuite.IO;
1010
using NetTopologySuite.Geometries;
11+
using System.Linq.Expressions;
12+
using System.Collections;
1113

1214

1315
namespace NRedisStack.Tests.Search;
@@ -3416,13 +3418,27 @@ public void TestNumericLogicalOperatorsInDialect4(string endpointId)
34163418
Assert.Equal(1, ft.Search(index, new Query("@version==123 @id==456").Dialect(4)).TotalResults);
34173419
}
34183420

3421+
/// <summary>
3422+
/// this test is to check if the issue 352 is fixed
3423+
/// Load operation was failing because the document was not being dropped in search result due to this behaviour;
3424+
/// "If a relevant key expires while a query is running, an attempt to load the key's value will return a null array.
3425+
/// However, the key is still counted in the total number of results."
3426+
/// https://redis.io/docs/latest/commands/ft.search/#:~:text=If%20a%20relevant%20key%20expires,the%20total%20number%20of%20results.
3427+
/// </summary>
34193428
[Fact]
34203429
public void TestDocumentLoad_Issue352()
34213430
{
34223431
Document d = Document.Load("1", 0.5, null, new RedisValue[] { RedisValue.Null });
34233432
Assert.Empty(d.GetProperties().ToList());
34243433
}
34253434

3435+
/// <summary>
3436+
/// this test is to check if the issue 352 is fixed
3437+
/// Load operation was failing because the document was not being dropped in search result due to this behaviour;
3438+
/// "If a relevant key expires while a query is running, an attempt to load the key's value will return a null array.
3439+
/// However, the key is still counted in the total number of results."
3440+
/// https://redis.io/docs/latest/commands/ft.search/#:~:text=If%20a%20relevant%20key%20expires,the%20total%20number%20of%20results.
3441+
/// </summary>
34263442
[SkippableTheory]
34273443
[MemberData(nameof(EndpointsFixture.Env.StandaloneOnly), MemberType = typeof(EndpointsFixture.Env))]
34283444
public void TestDocumentLoadWithDB_Issue352(string endpointId)
@@ -3435,33 +3451,56 @@ public void TestDocumentLoadWithDB_Issue352(string endpointId)
34353451

34363452
Document droppedDocument = null;
34373453
int numberOfAttempts = 0;
3454+
34383455
do
34393456
{
3440-
db.HashSet("student:1111", new HashEntry[] { new("first", "Joe"), new("last", "Dod"), new("age", 18) });
3441-
3442-
Assert.True(db.KeyExpire("student:1111", TimeSpan.FromMilliseconds(500)));
3457+
// try until succesfully create the key and set the TTL
3458+
bool ttlRefreshed = false;
3459+
do
3460+
{
3461+
db.HashSet("student:1111", new HashEntry[] { new("first", "Joe"), new("last", "Dod"), new("age", 18) });
3462+
ttlRefreshed = db.KeyExpire("student:1111", TimeSpan.FromMilliseconds(500));
3463+
} while (!ttlRefreshed);
34433464

34443465
Boolean cancelled = false;
3445-
Task searchTask = Task.Run(() =>
3466+
Action checker = () =>
34463467
{
3447-
for (int i = 0; i < 100000; i++)
3468+
for (int i = 0; i < 100000 && !cancelled; i++)
34483469
{
34493470
SearchResult result = ft.Search(index, new Query());
34503471
List<Document> docs = result.Documents;
3451-
if (docs.Count == 0 || cancelled)
3472+
// check if doc is already dropped before search and load;
3473+
// if yes then its already late and we missed the window that
3474+
// doc would show up in search result with no fields
3475+
if (docs.Count == 0)
34523476
{
34533477
break;
34543478
}
3455-
else if (docs[0].GetProperties().ToList().Count == 0)
3479+
// if we get a document with no fields then we know that the key
3480+
// expired while the query is running, and we are able to catch the state
3481+
// so we can break the loop
3482+
else if (docs[0].GetProperties().Count() == 0)
34563483
{
34573484
droppedDocument = docs[0];
3485+
break;
34583486
}
34593487
}
3460-
});
3461-
Task.WhenAny(searchTask, Task.Delay(1000)).GetAwaiter().GetResult();
3462-
Assert.True(searchTask.IsCompleted);
3463-
Assert.Null(searchTask.Exception);
3488+
};
3489+
3490+
List<Task> tasks = new List<Task>();
3491+
// try with 3 different tasks simultaneously to increase the chance of hitting it
3492+
for (int i = 0; i < 3; i++)
3493+
{
3494+
tasks.Add(Task.Run(checker));
3495+
}
3496+
Task checkTask = Task.WhenAll(tasks);
3497+
Task.WhenAny(checkTask, Task.Delay(1500)).GetAwaiter().GetResult();
3498+
Assert.True(checkTask.IsCompleted);
3499+
Assert.Null(checkTask.Exception);
34643500
cancelled = true;
3465-
} while (droppedDocument == null && numberOfAttempts++ < 3);
3501+
} while (droppedDocument == null && numberOfAttempts++ < 5);
3502+
// we wont do an actual assert here since
3503+
// it is not guaranteed that window stays open wide enough to catch it.
3504+
// instead we attempt 5 times
34663505
}
34673506
}

0 commit comments

Comments
 (0)