Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/NRedisStack/PublicAPI/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,8 @@ NRedisStack.Literals.Enums.TsAggregation.StdP = 8 -> NRedisStack.Literals.Enums.
NRedisStack.Literals.Enums.TsAggregation.StdS = 9 -> NRedisStack.Literals.Enums.TsAggregation
NRedisStack.Literals.Enums.TsAggregation.Sum = 1 -> NRedisStack.Literals.Enums.TsAggregation
NRedisStack.Literals.Enums.TsAggregation.Twa = 12 -> NRedisStack.Literals.Enums.TsAggregation
NRedisStack.Literals.Enums.TsAggregation.CountNan = 13 -> NRedisStack.Literals.Enums.TsAggregation
NRedisStack.Literals.Enums.TsAggregation.CountAll = 14 -> NRedisStack.Literals.Enums.TsAggregation
NRedisStack.Literals.Enums.TsAggregation.VarP = 10 -> NRedisStack.Literals.Enums.TsAggregation
NRedisStack.Literals.Enums.TsAggregation.VarS = 11 -> NRedisStack.Literals.Enums.TsAggregation
NRedisStack.Literals.Enums.TsBucketTimestamps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ internal static class AggregationExtensions
TsAggregation.VarP => "var.p",
TsAggregation.VarS => "var.s",
TsAggregation.Twa => "twa",
TsAggregation.CountNan => "countnan",
TsAggregation.CountAll => "countall",
_ => throw new ArgumentOutOfRangeException(nameof(aggregation), "Invalid aggregation type"),
};

Expand Down Expand Up @@ -50,6 +52,8 @@ internal static class AggregationExtensions
"VAR.P" => TsAggregation.VarP,
"VAR.S" => TsAggregation.VarS,
"TWA" => TsAggregation.Twa,
"COUNTNAN" => TsAggregation.CountNan,
"COUNTALL" => TsAggregation.CountAll,
_ => throw new ArgumentOutOfRangeException(nameof(aggregation), $"Invalid aggregation type '{aggregation}'"),
};
}
12 changes: 12 additions & 0 deletions src/NRedisStack/TimeSeries/Literals/Enums/Aggregation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,16 @@ public enum TsAggregation
/// Time-weighted average of all values
/// </summary>
Twa,

/// <summary>
/// Count of NaN values in the aggregation bucket
/// </summary>
/// <remarks>Available since Redis 8.6.0</remarks>
CountNan,

/// <summary>
/// Count of all values (including NaN) in the aggregation bucket
/// </summary>
/// <remarks>Available since Redis 8.6.0</remarks>
CountAll,
}
44 changes: 44 additions & 0 deletions tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -277,4 +277,48 @@
Assert.Equal(range[i].Val, expected[i].Val);
}
}

[SkipIfRedisTheory(Comparison.LessThan, "8.5.0")]
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
public void TestRangeCountNanAggregation(string endpointId)
{
IDatabase db = GetCleanDatabase(endpointId);
var ts = db.TS();
var key = CreateKeyName();

// Create a time series and add data including NaN values
ts.Create(key);
ts.Add(key, 10, 1.0);
ts.Add(key, 20, double.NaN);
ts.Add(key, 30, 3.0);
ts.Add(key, 40, double.NaN);
ts.Add(key, 50, 5.0);

// Test CountNan aggregation - should count NaN values
var range = ts.Range(key, 0, 100, aggregation: TsAggregation.CountNan, timeBucket: 100);

Check failure on line 298 in tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRange.cs

View workflow job for this annotation

GitHub Actions / Redis 8.6; .NET 8.0;

NRedisStack.Tests.TimeSeries.TestAPI.TestRange.TestRangeCountNanAggregation(endpointId: "cluster")

StackExchange.Redis.RedisServerException : Key has MOVED to Endpoint 127.0.0.1:16380 and hashslot 5534 but CommandFlags.NoRedirect was specified - redirect not followed for TS.RANGE.

Check failure on line 298 in tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRange.cs

View workflow job for this annotation

GitHub Actions / Redis 8.6; .NET 9.0;

NRedisStack.Tests.TimeSeries.TestAPI.TestRange.TestRangeCountNanAggregation(endpointId: "cluster")

StackExchange.Redis.RedisServerException : Key has MOVED to Endpoint 127.0.0.1:16380 and hashslot 5534 but CommandFlags.NoRedirect was specified - redirect not followed for TS.RANGE.
Assert.Single(range);
Assert.Equal(2, range[0].Val); // 2 NaN values
}

[SkipIfRedisTheory(Comparison.LessThan, "8.5.0")]
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
public void TestRangeCountAllAggregation(string endpointId)
{
IDatabase db = GetCleanDatabase(endpointId);
var ts = db.TS();
var key = CreateKeyName();

// Create a time series and add data including NaN values
ts.Create(key);
ts.Add(key, 10, 1.0);
ts.Add(key, 20, double.NaN);
ts.Add(key, 30, 3.0);
ts.Add(key, 40, double.NaN);
ts.Add(key, 50, 5.0);

// Test CountAll aggregation - should count all values including NaN
var range = ts.Range(key, 0, 100, aggregation: TsAggregation.CountAll, timeBucket: 100);

Check failure on line 320 in tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRange.cs

View workflow job for this annotation

GitHub Actions / Redis 8.6; .NET 8.0;

NRedisStack.Tests.TimeSeries.TestAPI.TestRange.TestRangeCountAllAggregation(endpointId: "cluster")

StackExchange.Redis.RedisServerException : Key has MOVED to Endpoint 127.0.0.1:16379 and hashslot 2125 but CommandFlags.NoRedirect was specified - redirect not followed for TS.RANGE.

Check failure on line 320 in tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRange.cs

View workflow job for this annotation

GitHub Actions / Redis 8.6; .NET 9.0;

NRedisStack.Tests.TimeSeries.TestAPI.TestRange.TestRangeCountAllAggregation(endpointId: "cluster")

StackExchange.Redis.RedisServerException : Key has MOVED to Endpoint 127.0.0.1:16379 and hashslot 2125 but CommandFlags.NoRedirect was specified - redirect not followed for TS.RANGE.
Assert.Single(range);
Assert.Equal(5, range[0].Val); // 5 total values (3 regular + 2 NaN)
}
}
44 changes: 44 additions & 0 deletions tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRangeAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,4 +283,48 @@
Assert.Equal(range[i].Val, expected[i].Val);
}
}

[SkipIfRedisTheory(Comparison.LessThan, "8.5.0")]
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
public async Task TestRangeCountNanAggregationAsync(string endpointId)
{
IDatabase db = GetCleanDatabase(endpointId);
var ts = db.TS();
var key = CreateKeyName();

// Create a time series and add data including NaN values
await ts.CreateAsync(key);
await ts.AddAsync(key, 10, 1.0);
await ts.AddAsync(key, 20, double.NaN);
await ts.AddAsync(key, 30, 3.0);
await ts.AddAsync(key, 40, double.NaN);
await ts.AddAsync(key, 50, 5.0);

// Test CountNan aggregation - should count NaN values
var range = await ts.RangeAsync(key, 0, 100, aggregation: TsAggregation.CountNan, timeBucket: 100);
Assert.Single(range);
Assert.Equal(2, range[0].Val); // 2 NaN values
}

[SkipIfRedisTheory(Comparison.LessThan, "8.5.0")]
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
public async Task TestRangeCountAllAggregationAsync(string endpointId)
{
IDatabase db = GetCleanDatabase(endpointId);
var ts = db.TS();
var key = CreateKeyName();

// Create a time series and add data including NaN values
await ts.CreateAsync(key);
await ts.AddAsync(key, 10, 1.0);
await ts.AddAsync(key, 20, double.NaN);
await ts.AddAsync(key, 30, 3.0);
await ts.AddAsync(key, 40, double.NaN);
await ts.AddAsync(key, 50, 5.0);

// Test CountAll aggregation - should count all values including NaN
var range = await ts.RangeAsync(key, 0, 100, aggregation: TsAggregation.CountAll, timeBucket: 100);

Check failure on line 326 in tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRangeAsync.cs

View workflow job for this annotation

GitHub Actions / Redis 8.6; .NET 8.0;

NRedisStack.Tests.TimeSeries.TestAPI.TestRangeAsync.TestRangeCountAllAggregationAsync(endpointId: "cluster")

StackExchange.Redis.RedisServerException : Key has MOVED to Endpoint 127.0.0.1:16379 and hashslot 1691 but CommandFlags.NoRedirect was specified - redirect not followed for TS.RANGE.

Check failure on line 326 in tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRangeAsync.cs

View workflow job for this annotation

GitHub Actions / Redis 8.6; .NET 9.0;

NRedisStack.Tests.TimeSeries.TestAPI.TestRangeAsync.TestRangeCountAllAggregationAsync(endpointId: "cluster")

StackExchange.Redis.RedisServerException : Key has MOVED to Endpoint 127.0.0.1:16379 and hashslot 1691 but CommandFlags.NoRedirect was specified - redirect not followed for TS.RANGE.
Assert.Single(range);
Assert.Equal(5, range[0].Val); // 5 total values (3 regular + 2 NaN)
}
}
6 changes: 5 additions & 1 deletion tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRulesAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ public async Task TestRulesAdditionDeletion(string endpointId)
var db = GetCleanDatabase(endpointId);
var ts = db.TS();
await ts.CreateAsync(key);
var aggregations = (TsAggregation[])Enum.GetValues(typeof(TsAggregation));
var allAggregations = (TsAggregation[])Enum.GetValues(typeof(TsAggregation));
// Filter out CountNan and CountAll on Redis versions < 8.6.0 as they are not supported
var aggregations = EndpointsFixture.RedisVersion >= new Version("8.5.0")
? allAggregations
: allAggregations.Where(a => a != TsAggregation.CountNan && a != TsAggregation.CountAll).ToArray();

foreach (var aggregation in aggregations)
{
Expand Down
Loading