-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathExtensibilityTests.cs
69 lines (61 loc) · 2.82 KB
/
ExtensibilityTests.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
using System;
using FluentAssertions;
using NUnit.Framework;
using PromQL.Parser.Ast;
using Superpower;
using Superpower.Parsers;
namespace PromQL.Parser.Tests
{
[TestFixture]
public class ExtensibilityTests
{
/// <summary>
/// This is a simple test of the tokenizers and parsers extensibility- can we recognize the $__rate_interval + $__interval
/// durations that grafana uses?
/// </summary>
/// <remarks>
/// This library was designed to be semi-extensible but it certainly wasn't the primary goal. However, some validation that
/// we can match a commonly-used extension to PromQL is good to have.
/// </remarks>
[Test]
public void Can_Parse_Grafana_Durations()
{
var tokenizer = new Tokenizer();
// Replace the default duration tokenizer with one to recognize the grafana variables
tokenizer.Duration =
from num in Span.EqualTo("$__rate_interval").Try().Or(Span.EqualTo("$__interval")).Try()
select num.ToStringValue();
var original = Parser.Duration;
// Replace the default Duration parser with one that will return a special duration value (-1) when we encounter a duration token.
// We have to to do this as the default parser will be expected a prometheus duration and will attempt to match a regex against our newly
// accepted and invalid duration.
Parser.Duration = from t in Token.EqualTo(PromToken.DURATION)
select new Duration(new TimeSpan(-1));
// Should work for vector selectors..
Parser.ParseExpression("my_metric[$__interval]", tokenizer).Should().BeOfType<MatrixSelector>()
.Which.Duration.Value.Should().Be(new TimeSpan(-1));
// ..and subqueries
Parser.ParseExpression("my_metric[$__rate_interval:]", tokenizer).Should().BeOfType<SubqueryExpr>()
.Which.Range.Value.Should().Be(new TimeSpan(-1));;
// And then prove we can modify how expressions are printed
var printer = new CustomPrinter();
printer.ToPromQl(Parser.ParseExpression("my_metric[$__interval]", tokenizer))
.Should().Be("my_metric[$__my_replaced_value]");
// Restore original parser so rest of tests can pass
Parser.Duration = original;
}
public class CustomPrinter : Printer
{
public CustomPrinter() : base(PrinterOptions.NoFormatting)
{
}
public override void Visit(Duration d)
{
if (d.Value == new TimeSpan(-1))
Write($"$__my_replaced_value");
else
base.Visit(d);
}
}
}
}