Skip to content

Commit 3fba661

Browse files
authored
Bump Redis 8.0 version(8.0-RC1-pre) in pipeline (#407)
* Bump Redis 8.0 version(8.0-RC1-pre) in pipeline * drop/fix failing tests with 8.0 * fix failing test * fix flaky test * attempt with await * check with completed count * - remove cancelled - assert ttl - run till key disappears from search result
1 parent 72e5138 commit 3fba661

File tree

3 files changed

+55
-23
lines changed

3 files changed

+55
-23
lines changed

.github/workflows/integration.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
max-parallel: 15
3838
fail-fast: false
3939
matrix:
40-
redis-version: [ '8.0-M05-pre', '${{ needs.redis_version.outputs.CURRENT }}', '7.2.6', '6.2.16']
40+
redis-version: [ '8.0-RC1-pre', '${{ needs.redis_version.outputs.CURRENT }}', '7.2.6', '6.2.16']
4141
dotnet-version: ['6.0', '7.0', '8.0']
4242
env:
4343
ACTIONS_ALLOW_UNSECURE_COMMANDS: true

tests/NRedisStack.Tests/Search/SearchTests.cs

+54-18
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
using NetTopologySuite.IO;
1010
using NetTopologySuite.Geometries;
1111

12-
1312
namespace NRedisStack.Tests.Search;
1413

1514
public class SearchTests : AbstractNRedisStackTest, IDisposable
@@ -1384,7 +1383,7 @@ public void TestDropIndex(string endpointId)
13841383
}
13851384
catch (RedisServerException ex)
13861385
{
1387-
Assert.Contains("no such index", ex.Message);
1386+
Assert.Contains("no such index", ex.Message, StringComparison.OrdinalIgnoreCase);
13881387
}
13891388
Assert.Equal("100", db.Execute("DBSIZE").ToString());
13901389
}
@@ -1417,7 +1416,7 @@ public async Task TestDropIndexAsync(string endpointId)
14171416
}
14181417
catch (RedisServerException ex)
14191418
{
1420-
Assert.Contains("no such index", ex.Message);
1419+
Assert.Contains("no such index", ex.Message, StringComparison.OrdinalIgnoreCase);
14211420
}
14221421
Assert.Equal("100", db.Execute("DBSIZE").ToString());
14231422
}
@@ -3416,52 +3415,89 @@ public void TestNumericLogicalOperatorsInDialect4(string endpointId)
34163415
Assert.Equal(1, ft.Search(index, new Query("@version==123 @id==456").Dialect(4)).TotalResults);
34173416
}
34183417

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

3432+
/// <summary>
3433+
/// this test is to check if the issue 352 is fixed
3434+
/// Load operation was failing because the document was not being dropped in search result due to this behaviour;
3435+
/// "If a relevant key expires while a query is running, an attempt to load the key's value will return a null array.
3436+
/// However, the key is still counted in the total number of results."
3437+
/// https://redis.io/docs/latest/commands/ft.search/#:~:text=If%20a%20relevant%20key%20expires,the%20total%20number%20of%20results.
3438+
/// </summary>
34263439
[SkippableTheory]
34273440
[MemberData(nameof(EndpointsFixture.Env.StandaloneOnly), MemberType = typeof(EndpointsFixture.Env))]
3428-
public void TestDocumentLoadWithDB_Issue352(string endpointId)
3441+
public async void TestDocumentLoadWithDB_Issue352(string endpointId)
34293442
{
34303443
IDatabase db = GetCleanDatabase(endpointId);
34313444
var ft = db.FT();
34323445

3433-
Schema sc = new Schema().AddTextField("first", 1.0).AddTextField("last", 1.0).AddNumericField("age");
3446+
Schema sc = new Schema().AddTextField("firstText", 1.0).AddTextField("lastText", 1.0).AddNumericField("ageNumeric");
34343447
Assert.True(ft.Create(index, FTCreateParams.CreateParams(), sc));
34353448

34363449
Document droppedDocument = null;
34373450
int numberOfAttempts = 0;
34383451
do
34393452
{
3440-
db.HashSet("student:1111", new HashEntry[] { new("first", "Joe"), new("last", "Dod"), new("age", 18) });
3453+
// try until succesfully create the key and set the TTL
3454+
bool ttlRefreshed = false;
3455+
do
3456+
{
3457+
db.HashSet("student:22222", new HashEntry[] { new("firstText", "Joe"), new("lastText", "Dod"), new("ageNumeric", 18) });
3458+
ttlRefreshed = db.KeyExpire("student:22222", TimeSpan.FromMilliseconds(500));
3459+
} while (!ttlRefreshed);
34413460

3442-
Assert.True(db.KeyExpire("student:1111", TimeSpan.FromMilliseconds(500)));
3461+
Int32 completed = 0;
34433462

3444-
Boolean cancelled = false;
3445-
Task searchTask = Task.Run(() =>
3463+
Action checker = () =>
34463464
{
3447-
for (int i = 0; i < 100000; i++)
3465+
for (int i = 0; i < 1000000; i++)
34483466
{
34493467
SearchResult result = ft.Search(index, new Query());
34503468
List<Document> docs = result.Documents;
3451-
if (docs.Count == 0 || cancelled)
3469+
3470+
// check if doc is already dropped before search and load;
3471+
// if yes then its already late and we missed the window that
3472+
// doc would show up in search result with no fields
3473+
if (docs.Count == 0)
34523474
{
3475+
Interlocked.Increment(ref completed);
34533476
break;
34543477
}
3455-
else if (docs[0].GetProperties().ToList().Count == 0)
3478+
// if we get a document with no fields then we know that the key
3479+
// is going to be expired while the query is running, and we are able to catch the state
3480+
// but key itself might not be expired yet
3481+
else if (docs[0].GetProperties().Count() == 0)
34563482
{
34573483
droppedDocument = docs[0];
34583484
}
34593485
}
3460-
});
3461-
Task.WhenAny(searchTask, Task.Delay(1000)).GetAwaiter().GetResult();
3462-
Assert.True(searchTask.IsCompleted);
3463-
Assert.Null(searchTask.Exception);
3464-
cancelled = true;
3465-
} while (droppedDocument == null && numberOfAttempts++ < 3);
3486+
};
3487+
3488+
List<Task> tasks = new List<Task>();
3489+
// try with 3 different tasks simultaneously to increase the chance of hitting it
3490+
for (int i = 0; i < 3; i++) { tasks.Add(Task.Run(checker)); }
3491+
Task checkTask = Task.WhenAll(tasks);
3492+
await Task.WhenAny(checkTask, Task.Delay(1000));
3493+
var keyTtl = db.KeyTimeToLive("student:22222");
3494+
Assert.Equal(0, keyTtl.HasValue ? keyTtl.Value.Milliseconds : 0);
3495+
Assert.Equal(3, completed);
3496+
} while (droppedDocument == null && numberOfAttempts++ < 5);
3497+
// we won't do an actual assert here since
3498+
// it is not guaranteed that window stays open wide enough to catch it.
3499+
// instead we attempt 5 times.
3500+
// Without fix for Issue352, document load in this case fails %100 with my local test runs,, and %100 success with fixed version.
3501+
// The results in pipeline should be the same.
34663502
}
34673503
}

tests/NRedisStack.Tests/TimeSeries/TestDataTypes/TestTimeSeriesInformation.cs

-4
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,12 @@ public void TestInformationSync()
2727
TimeSeriesInformation info = ts.Info(key);
2828
TimeSeriesInformation infoDebug = ts.Info(key, debug: true);
2929

30-
Assert.Equal(4184, info.MemoryUsage);
3130
Assert.Equal(0, info.RetentionTime);
3231
Assert.Equal(1, info.ChunkCount);
3332
Assert.Null(info.DuplicatePolicy);
3433
Assert.Null(info.KeySelfName);
3534
Assert.Null(info.Chunks);
3635

37-
Assert.Equal(4184, infoDebug.MemoryUsage);
3836
Assert.Equal(0, infoDebug.RetentionTime);
3937
Assert.Equal(1, infoDebug.ChunkCount);
4038
Assert.Null(infoDebug.DuplicatePolicy);
@@ -55,14 +53,12 @@ public async Task TestInformationAsync()
5553
TimeSeriesInformation info = await ts.InfoAsync(key);
5654
TimeSeriesInformation infoDebug = await ts.InfoAsync(key, debug: true);
5755

58-
Assert.Equal(4184, info.MemoryUsage);
5956
Assert.Equal(0, info.RetentionTime);
6057
Assert.Equal(1, info.ChunkCount);
6158
Assert.Null(info.DuplicatePolicy);
6259
Assert.Null(info.KeySelfName);
6360
Assert.Null(info.Chunks);
6461

65-
Assert.Equal(4184, infoDebug.MemoryUsage);
6662
Assert.Equal(0, infoDebug.RetentionTime);
6763
Assert.Equal(1, infoDebug.ChunkCount);
6864
Assert.Null(infoDebug.DuplicatePolicy);

0 commit comments

Comments
 (0)