Skip to content

Commit 98c207f

Browse files
authored
Add Tests for the new features in TS commands (#25)
* Add Tests for the new features in TS commands * Update TS.INFO DEBUG test * Add latest test * Add Async Tests
1 parent f028091 commit 98c207f

File tree

13 files changed

+408
-18
lines changed

13 files changed

+408
-18
lines changed

src/NRedisStack/ResponseParser.cs

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,31 +35,29 @@ public static bool[] ToBooleanArray(RedisResult result)
3535
public static RedisResult[] ToArray(RedisResult result)
3636
{
3737
var redisResults = (RedisResult[]?)result;
38-
if(redisResults != null)
38+
if (redisResults != null)
3939
return redisResults;
4040
throw new ArgumentNullException(nameof(redisResults));
41-
42-
4341
}
4442

4543
public static long ToLong(RedisResult result)
4644
{
47-
if((long?) result == null)
45+
if ((long?)result == null)
4846
throw new ArgumentNullException(nameof(result));
49-
return (long) result;
47+
return (long)result;
5048
}
5149

5250
public static double ToDouble(RedisResult result)
5351
{
54-
if((double?) result == null)
52+
if ((double?)result == null)
5553
throw new ArgumentNullException(nameof(result));
56-
return (double) result;
54+
return (double)result;
5755
}
5856

5957
public static double[] ToDoubleArray(RedisResult result)
6058
{
6159
List<double> redisResults = new List<double>();
62-
foreach(var res in ToArray(result))
60+
foreach (var res in ToArray(result))
6361
{
6462
redisResults.Add(ToDouble(res));
6563
}
@@ -70,7 +68,7 @@ public static double[] ToDoubleArray(RedisResult result)
7068
public static long[] ToLongArray(RedisResult result)
7169
{
7270
List<long> redisResults = new List<long>();
73-
foreach(var res in ToArray(result))
71+
foreach (var res in ToArray(result))
7472
{
7573
redisResults.Add(ToLong(res));
7674
}
@@ -150,6 +148,19 @@ public static IReadOnlyList<TimeSeriesLabel> ToLabelArray(RedisResult result)
150148
return list;
151149
}
152150

151+
// public static IReadOnlyList<TimeSeriesCunck> ToCunckArray(RedisResult result)
152+
// {
153+
// RedisResult[] redisResults = (RedisResult[])result;
154+
// var list = new List<TimeSeriesCunck>(redisResults.Length);
155+
// if (redisResults.Length == 0) return list;
156+
// Array.ForEach(redisResults, chunckResult =>
157+
// {
158+
// RedisResult[] labelTuple = (RedisResult[])labelResult;
159+
// list.Add(new TimeSeriesCunck((string)labelTuple[0], (string)labelTuple[1]));
160+
// });
161+
// return list;
162+
// }
163+
153164
public static IReadOnlyList<(string key, IReadOnlyList<TimeSeriesLabel> labels, TimeSeriesTuple value)> ParseMGetResponse(RedisResult result)
154165
{
155166
RedisResult[] redisResults = (RedisResult[])result;
@@ -405,8 +416,9 @@ public static TimeSeriesInformation ToTimeSeriesInfo(RedisResult result)
405416
TimeStamp? firstTimestamp = null, lastTimestamp = null;
406417
IReadOnlyList<TimeSeriesLabel>? labels = null;
407418
IReadOnlyList<TimeSeriesRule>? rules = null;
408-
string? sourceKey = null;
419+
string? sourceKey = null, keySelfName = null;
409420
TsDuplicatePolicy? duplicatePolicy = null;
421+
IReadOnlyList<TimeSeriesChunck>? chunks = null;
410422
RedisResult[] redisResults = (RedisResult[])result;
411423
for (int i = 0; i < redisResults.Length; ++i)
412424
{
@@ -452,11 +464,61 @@ public static TimeSeriesInformation ToTimeSeriesInfo(RedisResult result)
452464
// Avalible for > v1.4
453465
duplicatePolicy = ToPolicy(redisResults[i]);
454466
break;
467+
case "keySelfName":
468+
// Avalible for > v1.4
469+
keySelfName = redisResults[i].ToString();
470+
break;
471+
case "Chunks":
472+
// Avalible for > v1.4
473+
chunks = ToTimeSeriesChunkArray(redisResults[i]);
474+
break;
455475
}
456476
}
457477

458478
return new TimeSeriesInformation(totalSamples, memoryUsage, firstTimestamp,
459-
lastTimestamp, retentionTime, chunkCount, chunkSize, labels, sourceKey, rules, duplicatePolicy);
479+
lastTimestamp, retentionTime, chunkCount, chunkSize, labels, sourceKey, rules, duplicatePolicy, keySelfName, chunks);
480+
}
481+
482+
public static IReadOnlyList<TimeSeriesChunck> ToTimeSeriesChunkArray(RedisResult result)
483+
{
484+
RedisResult[] redisResults = (RedisResult[])result;
485+
var list = new List<TimeSeriesChunck>();
486+
if (redisResults.Length == 0) return list;
487+
Array.ForEach(redisResults, chunk => list.Add(ToTimeSeriesChunk(chunk)));
488+
return list;
489+
}
490+
491+
public static TimeSeriesChunck ToTimeSeriesChunk(RedisResult result)
492+
{
493+
long startTimestamp = -1, endTimestamp = -1, samples = -1, size = -1;
494+
string bytesPerSample = "";
495+
RedisResult[] redisResults = (RedisResult[])result;
496+
for (int i = 0; i < redisResults.Length; ++i)
497+
{
498+
string label = (string)redisResults[i++];
499+
switch (label)
500+
{
501+
case "startTimestamp":
502+
startTimestamp = (long)redisResults[i];
503+
break;
504+
case "endTimestamp":
505+
endTimestamp = (long)redisResults[i];
506+
break;
507+
case "samples":
508+
samples = (long)redisResults[i];
509+
break;
510+
case "size":
511+
size = (long)redisResults[i];
512+
break;
513+
case "bytesPerSample":
514+
bytesPerSample = redisResults[i].ToString();
515+
break;
516+
}
517+
}
518+
519+
return new TimeSeriesChunck(startTimestamp, endTimestamp,
520+
samples, size, bytesPerSample);
521+
460522
}
461523

462524
public static IReadOnlyList<string> ToStringArray(RedisResult result)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System.Collections.Generic;
2+
3+
namespace NRedisStack.DataTypes
4+
{
5+
/// <summary>
6+
/// A key-value pair class represetns metadata label of time-series.
7+
/// </summary>
8+
public class TimeSeriesChunck
9+
{
10+
/// <summary>
11+
/// First timestamp present in the chunk
12+
/// </summary>
13+
public long StartTimestamp { get; }
14+
15+
/// <summary>
16+
/// Last timestamp present in the chunk
17+
/// </summary>
18+
public long EndTimestamp { get; }
19+
20+
/// <summary>
21+
/// Total number of samples in the chunk
22+
/// </summary>
23+
public long Samples { get; }
24+
25+
/// <summary>
26+
/// The chunk data size in bytes. This is the exact size that used for
27+
/// data only inside the chunk. It does not include other overheads.
28+
/// </summary>
29+
public long Size { get; }
30+
31+
/// <summary>
32+
/// Ratio of size and samples
33+
/// </summary>
34+
public string BytesPerSample { get; }
35+
36+
public TimeSeriesChunck(long startTimestamp, long endTimestamp, long samples, long size, string bytesPerSample)
37+
{
38+
StartTimestamp = startTimestamp;
39+
EndTimestamp = endTimestamp;
40+
Samples = samples;
41+
Size = size;
42+
BytesPerSample = bytesPerSample;
43+
}
44+
}
45+
}

src/NRedisStack/TimeSeries/DataTypes/TimeSeriesInformation.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,20 @@ public class TimeSeriesInformation
7373
/// </summary>
7474
public TsDuplicatePolicy? DuplicatePolicy { get; private set; }
7575

76-
internal TimeSeriesInformation(long totalSamples, long memoryUsage, TimeStamp firstTimeStamp, TimeStamp lastTimeStamp, long retentionTime, long chunkCount, long chunkSize, IReadOnlyList<TimeSeriesLabel> labels, string sourceKey, IReadOnlyList<TimeSeriesRule> rules, TsDuplicatePolicy? policy)
76+
/// <summary>
77+
/// In DEBUG mode: Key self name.
78+
/// </summary>
79+
public string? KeySelfName { get; private set; }
80+
81+
/// <summary>
82+
/// In DEBUG mode: gives more information about the chunks
83+
/// </summary>
84+
public IReadOnlyList<TimeSeriesChunck>? Chunks { get; private set; }
85+
internal TimeSeriesInformation(long totalSamples, long memoryUsage,
86+
TimeStamp firstTimeStamp, TimeStamp lastTimeStamp, long retentionTime,
87+
long chunkCount, long chunkSize, IReadOnlyList<TimeSeriesLabel> labels,
88+
string sourceKey, IReadOnlyList<TimeSeriesRule> rules, TsDuplicatePolicy? policy,
89+
string? keySelfName = null, IReadOnlyList<TimeSeriesChunck>? chunks = null)
7790
{
7891
TotalSamples = totalSamples;
7992
MemoryUsage = memoryUsage;
@@ -89,6 +102,11 @@ internal TimeSeriesInformation(long totalSamples, long memoryUsage, TimeStamp fi
89102
ChunkSize = chunkSize;
90103
// configure what to do on duplicate sample > v1.4
91104
DuplicatePolicy = policy;
105+
106+
// Will be equal to null when DEBUG is not in use:
107+
KeySelfName = keySelfName;
108+
Chunks = chunks;
109+
92110
}
93111

94112
/// <summary>

src/NRedisStack/TimeSeries/TimeSeriesCommands.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,8 @@ public async Task<bool> DeleteRuleAsync(string sourceKey, string destKey)
346346
/// <remarks><seealso href="https://redis.io/commands/ts.get"/></remarks>
347347
public TimeSeriesTuple? Get(string key, bool latest = false)
348348
{
349-
return ResponseParser.ToTimeSeriesTuple((latest) ? _db.Execute(TS.GET, key)
350-
: _db.Execute(TS.GET, key, TimeSeriesArgs.LATEST));
349+
return ResponseParser.ToTimeSeriesTuple((latest) ? _db.Execute(TS.GET, key, TimeSeriesArgs.LATEST)
350+
: _db.Execute(TS.GET, key));
351351
}
352352

353353
/// <summary>
@@ -362,8 +362,8 @@ public async Task<bool> DeleteRuleAsync(string sourceKey, string destKey)
362362
/// <remarks><seealso href="https://redis.io/commands/ts.get"/></remarks>
363363
public async Task<TimeSeriesTuple?> GetAsync(string key, bool latest = false)
364364
{
365-
return ResponseParser.ToTimeSeriesTuple(await ((latest) ? _db.ExecuteAsync(TS.GET, key)
366-
: _db.ExecuteAsync(TS.GET, key, TimeSeriesArgs.LATEST)));
365+
return ResponseParser.ToTimeSeriesTuple(await ((latest) ? _db.ExecuteAsync(TS.GET, key, TimeSeriesArgs.LATEST)
366+
: _db.ExecuteAsync(TS.GET, key)));
367367
}
368368

369369
/// <summary>

tests/NRedisStack.Tests/TimeSeries/TestAPI/TestAlter.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using NRedisStack.DataTypes;
4+
using NRedisStack.Literals.Enums;
45
using NRedisStack.RedisStackCommands;
56
using StackExchange.Redis;
67
using Xunit;
@@ -47,5 +48,16 @@ public void TestAlterLabels()
4748
Assert.Equal(labels, info.Labels);
4849
}
4950

51+
[Fact]
52+
public void TestAlterPolicyAndChunk()
53+
{
54+
IDatabase db = redisFixture.Redis.GetDatabase();
55+
db.Execute("FLUSHALL");
56+
db.TS().Create(key);
57+
Assert.True(db.TS().Alter(key, chunkSizeBytes: 128, duplicatePolicy: TsDuplicatePolicy.MIN));
58+
TimeSeriesInformation info = db.TS().Info(key);
59+
Assert.Equal(info.ChunkSize, 128);
60+
Assert.Equal(info.DuplicatePolicy, TsDuplicatePolicy.MIN);
61+
}
5062
}
5163
}

tests/NRedisStack.Tests/TimeSeries/TestAPI/TestAlterAsync.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using NRedisStack.DataTypes;
2+
using NRedisStack.Literals.Enums;
23
using NRedisStack.RedisStackCommands;
34
using System.Collections.Generic;
45
using System.Threading.Tasks;
@@ -45,5 +46,18 @@ public async Task TestAlterLabels()
4546
Assert.Equal(labels, info.Labels);
4647
}
4748

49+
[Fact]
50+
public async Task TestAlterPolicyAndChunkAsync()
51+
{
52+
var key = CreateKeyName();
53+
var db = redisFixture.Redis.GetDatabase();
54+
db.Execute("FLUSHALL");
55+
db.TS().Create(key);
56+
Assert.True(await db.TS().AlterAsync(key, chunkSizeBytes: 128, duplicatePolicy: TsDuplicatePolicy.MIN));
57+
TimeSeriesInformation info = db.TS().Info(key);
58+
Assert.Equal(info.ChunkSize, 128);
59+
Assert.Equal(info.DuplicatePolicy, TsDuplicatePolicy.MIN);
60+
}
61+
4862
}
4963
}

tests/NRedisStack.Tests/TimeSeries/TestAPI/TestMGet.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,31 @@ public void TestMGetQueryWithLabels()
7373
Assert.Equal(tuple2, results[1].value);
7474
Assert.Equal(labels2, results[1].labels);
7575
}
76+
77+
[Fact]
78+
public void TestMGetQuerySelectedLabels()
79+
{
80+
IDatabase db = redisFixture.Redis.GetDatabase();
81+
db.Execute("FLUSHALL");
82+
83+
var label1 = new TimeSeriesLabel("MGET_TESTS_1", "value");
84+
var label2 = new TimeSeriesLabel("MGET_TESTS_2", "value2");
85+
var labels1 = new List<TimeSeriesLabel> { label1, label2 };
86+
var labels2 = new List<TimeSeriesLabel> { label1 };
87+
88+
TimeStamp ts1 = db.TS().Add(keys[0], "*", 1.1, labels: labels1);
89+
TimeSeriesTuple tuple1 = new TimeSeriesTuple(ts1, 1.1);
90+
TimeStamp ts2 = db.TS().Add(keys[1], "*", 2.2, labels: labels2);
91+
TimeSeriesTuple tuple2 = new TimeSeriesTuple(ts2, 2.2);
92+
93+
var results = db.TS().MGet(new List<string> { "MGET_TESTS_1=value" }, selectedLabels: new List<string>{"MGET_TESTS_1"});
94+
Assert.Equal(2, results.Count);
95+
Assert.Equal(keys[0], results[0].key);
96+
Assert.Equal(tuple1, results[0].value);
97+
Assert.Equal(labels2, results[0].labels);
98+
Assert.Equal(keys[1], results[1].key);
99+
Assert.Equal(tuple2, results[1].value);
100+
Assert.Equal(labels2, results[1].labels);
101+
}
76102
}
77103
}

tests/NRedisStack.Tests/TimeSeries/TestAPI/TestMGetAsync.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,32 @@ public async Task TestMGetQueryWithLabels()
6363
Assert.Equal(tuple2, results[1].value);
6464
Assert.Equal(labels2, results[1].labels);
6565
}
66+
67+
[Fact]
68+
public async Task TestMGetQuerySelectedLabelsAsync()
69+
{
70+
var keys = CreateKeyNames(2);
71+
var db = redisFixture.Redis.GetDatabase();
72+
db.Execute("FLUSHALL");
73+
74+
var label1 = new TimeSeriesLabel("MGET_TESTS_1", "value");
75+
var label2 = new TimeSeriesLabel("MGET_TESTS_2", "value2");
76+
var labels1 = new List<TimeSeriesLabel> { label1, label2 };
77+
var labels2 = new List<TimeSeriesLabel> { label1 };
78+
79+
TimeStamp ts1 = await db.TS().AddAsync(keys[0], "*", 1.1, labels: labels1);
80+
TimeSeriesTuple tuple1 = new TimeSeriesTuple(ts1, 1.1);
81+
TimeStamp ts2 = await db.TS().AddAsync(keys[1], "*", 2.2, labels: labels2);
82+
TimeSeriesTuple tuple2 = new TimeSeriesTuple(ts2, 2.2);
83+
84+
var results = await db.TS().MGetAsync(new List<string> { "MGET_TESTS_1=value" }, selectedLabels: new List<string>{"MGET_TESTS_1"});
85+
Assert.Equal(2, results.Count);
86+
Assert.Equal(keys[0], results[0].key);
87+
Assert.Equal(tuple1, results[0].value);
88+
Assert.Equal(labels2, results[0].labels);
89+
Assert.Equal(keys[1], results[1].key);
90+
Assert.Equal(tuple2, results[1].value);
91+
Assert.Equal(labels2, results[1].labels);
92+
}
6693
}
6794
}

0 commit comments

Comments
 (0)