|
|
|
@ -89,143 +89,228 @@ describe('Language_provider', () => { |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('an empty array', () => { |
|
|
|
|
expect(lp.generateQueryFromFilters([])).toBe('{}'); |
|
|
|
|
expect(lp.generateQueryFromFilters({ traceqlFilters: [] })).toBe('{}'); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('a field without value', () => { |
|
|
|
|
expect(lp.generateQueryFromFilters([{ id: 'foo', tag: 'footag', operator: '=' }])).toBe('{}'); |
|
|
|
|
expect(lp.generateQueryFromFilters({ traceqlFilters: [{ id: 'foo', tag: 'footag', operator: '=' }] })).toBe('{}'); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('a field with value but without tag', () => { |
|
|
|
|
expect(lp.generateQueryFromFilters([{ id: 'foo', value: 'foovalue', operator: '=' }])).toBe('{}'); |
|
|
|
|
expect(lp.generateQueryFromFilters({ traceqlFilters: [{ id: 'foo', value: 'foovalue', operator: '=' }] })).toBe( |
|
|
|
|
'{}' |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('a field with value and tag but without operator', () => { |
|
|
|
|
expect(lp.generateQueryFromFilters([{ id: 'foo', tag: 'footag', value: 'foovalue' }])).toBe('{}'); |
|
|
|
|
expect(lp.generateQueryFromFilters({ traceqlFilters: [{ id: 'foo', tag: 'footag', value: 'foovalue' }] })).toBe( |
|
|
|
|
'{}' |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
describe('generates correct query for duration when duration type', () => { |
|
|
|
|
it('not set', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters([ |
|
|
|
|
{ id: 'min-duration', operator: '>', valueType: 'duration', tag: 'duration', value: '100ms' }, |
|
|
|
|
]) |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [ |
|
|
|
|
{ id: 'min-duration', operator: '>', valueType: 'duration', tag: 'duration', value: '100ms' }, |
|
|
|
|
], |
|
|
|
|
}) |
|
|
|
|
).toBe('{duration>100ms}'); |
|
|
|
|
}); |
|
|
|
|
it('set to span', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters([ |
|
|
|
|
{ id: 'min-duration', operator: '>', valueType: 'duration', tag: 'duration', value: '100ms' }, |
|
|
|
|
{ id: 'duration-type', value: 'span' }, |
|
|
|
|
]) |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [ |
|
|
|
|
{ id: 'min-duration', operator: '>', valueType: 'duration', tag: 'duration', value: '100ms' }, |
|
|
|
|
{ id: 'duration-type', value: 'span' }, |
|
|
|
|
], |
|
|
|
|
}) |
|
|
|
|
).toBe('{duration>100ms}'); |
|
|
|
|
}); |
|
|
|
|
it('set to trace', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters([ |
|
|
|
|
{ id: 'min-duration', operator: '>', valueType: 'duration', tag: 'duration', value: '100ms' }, |
|
|
|
|
{ id: 'duration-type', value: 'trace' }, |
|
|
|
|
]) |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [ |
|
|
|
|
{ id: 'min-duration', operator: '>', valueType: 'duration', tag: 'duration', value: '100ms' }, |
|
|
|
|
{ id: 'duration-type', value: 'trace' }, |
|
|
|
|
], |
|
|
|
|
}) |
|
|
|
|
).toBe('{traceDuration>100ms}'); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('a field with tag, operator and tag', () => { |
|
|
|
|
expect(lp.generateQueryFromFilters([{ id: 'foo', tag: 'footag', value: 'foovalue', operator: '=' }])).toBe( |
|
|
|
|
'{.footag=foovalue}' |
|
|
|
|
); |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters([ |
|
|
|
|
{ id: 'foo', tag: 'footag', value: 'foovalue', operator: '=', valueType: 'string' }, |
|
|
|
|
]) |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [{ id: 'foo', tag: 'footag', value: 'foovalue', operator: '=' }], |
|
|
|
|
}) |
|
|
|
|
).toBe('{.footag=foovalue}'); |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [{ id: 'foo', tag: 'footag', value: 'foovalue', operator: '=', valueType: 'string' }], |
|
|
|
|
}) |
|
|
|
|
).toBe('{.footag="foovalue"}'); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('a field with valueType as integer', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters([{ id: 'foo', tag: 'footag', value: '1234', operator: '>', valueType: 'integer' }]) |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [{ id: 'foo', tag: 'footag', value: '1234', operator: '>', valueType: 'integer' }], |
|
|
|
|
}) |
|
|
|
|
).toBe('{.footag>1234}'); |
|
|
|
|
}); |
|
|
|
|
it.each([['=~'], ['!~']])('a field with a regexp operator (%s)', (operator) => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters([ |
|
|
|
|
{ |
|
|
|
|
id: 'span-name', |
|
|
|
|
tag: 'name', |
|
|
|
|
operator, |
|
|
|
|
scope: TraceqlSearchScope.Span, |
|
|
|
|
value: ['api/v2/variants/by-upc/(?P<upc>[\\s\\S]*)/$'], |
|
|
|
|
valueType: 'string', |
|
|
|
|
}, |
|
|
|
|
]) |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [ |
|
|
|
|
{ |
|
|
|
|
id: 'span-name', |
|
|
|
|
tag: 'name', |
|
|
|
|
operator, |
|
|
|
|
scope: TraceqlSearchScope.Span, |
|
|
|
|
value: ['api/v2/variants/by-upc/(?P<upc>[\\s\\S]*)/$'], |
|
|
|
|
valueType: 'string', |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
}) |
|
|
|
|
).toBe(`{name${operator}"api/v2/variants/by-upc/\\\\(\\\\?P<upc>\\\\[\\\\\\\\s\\\\\\\\S\\\\]\\\\*\\\\)/\\\\$"}`); |
|
|
|
|
}); |
|
|
|
|
it('two fields with everything filled in', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters([ |
|
|
|
|
{ id: 'foo', tag: 'footag', value: '1234', operator: '>=', valueType: 'integer' }, |
|
|
|
|
{ id: 'bar', tag: 'bartag', value: 'barvalue', operator: '=', valueType: 'string' }, |
|
|
|
|
]) |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [ |
|
|
|
|
{ id: 'foo', tag: 'footag', value: '1234', operator: '>=', valueType: 'integer' }, |
|
|
|
|
{ id: 'bar', tag: 'bartag', value: 'barvalue', operator: '=', valueType: 'string' }, |
|
|
|
|
], |
|
|
|
|
}) |
|
|
|
|
).toBe('{.footag>=1234 && .bartag="barvalue"}'); |
|
|
|
|
}); |
|
|
|
|
it('two fields but one is missing a value', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters([ |
|
|
|
|
{ id: 'foo', tag: 'footag', value: '1234', operator: '>=', valueType: 'integer' }, |
|
|
|
|
{ id: 'bar', tag: 'bartag', operator: '=', valueType: 'string' }, |
|
|
|
|
]) |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [ |
|
|
|
|
{ id: 'foo', tag: 'footag', value: '1234', operator: '>=', valueType: 'integer' }, |
|
|
|
|
{ id: 'bar', tag: 'bartag', operator: '=', valueType: 'string' }, |
|
|
|
|
], |
|
|
|
|
}) |
|
|
|
|
).toBe('{.footag>=1234}'); |
|
|
|
|
}); |
|
|
|
|
it('two fields but one is missing a value and the other a tag', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters([ |
|
|
|
|
{ id: 'foo', value: '1234', operator: '>=', valueType: 'integer' }, |
|
|
|
|
{ id: 'bar', tag: 'bartag', operator: '=', valueType: 'string' }, |
|
|
|
|
]) |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [ |
|
|
|
|
{ id: 'foo', value: '1234', operator: '>=', valueType: 'integer' }, |
|
|
|
|
{ id: 'bar', tag: 'bartag', operator: '=', valueType: 'string' }, |
|
|
|
|
], |
|
|
|
|
}) |
|
|
|
|
).toBe('{}'); |
|
|
|
|
}); |
|
|
|
|
it('scope is unscoped', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters([ |
|
|
|
|
{ |
|
|
|
|
id: 'foo', |
|
|
|
|
tag: 'footag', |
|
|
|
|
value: '1234', |
|
|
|
|
operator: '>=', |
|
|
|
|
scope: TraceqlSearchScope.Unscoped, |
|
|
|
|
valueType: 'integer', |
|
|
|
|
}, |
|
|
|
|
]) |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [ |
|
|
|
|
{ |
|
|
|
|
id: 'foo', |
|
|
|
|
tag: 'footag', |
|
|
|
|
value: '1234', |
|
|
|
|
operator: '>=', |
|
|
|
|
scope: TraceqlSearchScope.Unscoped, |
|
|
|
|
valueType: 'integer', |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
}) |
|
|
|
|
).toBe('{.footag>=1234}'); |
|
|
|
|
}); |
|
|
|
|
it('scope is span', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters([ |
|
|
|
|
{ |
|
|
|
|
id: 'foo', |
|
|
|
|
tag: 'footag', |
|
|
|
|
value: '1234', |
|
|
|
|
operator: '>=', |
|
|
|
|
scope: TraceqlSearchScope.Span, |
|
|
|
|
valueType: 'integer', |
|
|
|
|
}, |
|
|
|
|
]) |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [ |
|
|
|
|
{ |
|
|
|
|
id: 'foo', |
|
|
|
|
tag: 'footag', |
|
|
|
|
value: '1234', |
|
|
|
|
operator: '>=', |
|
|
|
|
scope: TraceqlSearchScope.Span, |
|
|
|
|
valueType: 'integer', |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
}) |
|
|
|
|
).toBe('{span.footag>=1234}'); |
|
|
|
|
}); |
|
|
|
|
it('scope is resource', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters([ |
|
|
|
|
{ |
|
|
|
|
id: 'foo', |
|
|
|
|
tag: 'footag', |
|
|
|
|
value: '1234', |
|
|
|
|
operator: '>=', |
|
|
|
|
scope: TraceqlSearchScope.Resource, |
|
|
|
|
valueType: 'integer', |
|
|
|
|
}, |
|
|
|
|
]) |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [ |
|
|
|
|
{ |
|
|
|
|
id: 'foo', |
|
|
|
|
tag: 'footag', |
|
|
|
|
value: '1234', |
|
|
|
|
operator: '>=', |
|
|
|
|
scope: TraceqlSearchScope.Resource, |
|
|
|
|
valueType: 'integer', |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
}) |
|
|
|
|
).toBe('{resource.footag>=1234}'); |
|
|
|
|
}); |
|
|
|
|
describe('adhoc filters', () => { |
|
|
|
|
it('mixes adhoc filters with trace ql', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
traceqlFilters: [ |
|
|
|
|
{ |
|
|
|
|
id: 'foo', |
|
|
|
|
tag: 'footag', |
|
|
|
|
value: '1234', |
|
|
|
|
operator: '>=', |
|
|
|
|
scope: TraceqlSearchScope.Resource, |
|
|
|
|
valueType: 'integer', |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
adhocFilters: [ |
|
|
|
|
{ |
|
|
|
|
key: 'resource.name', |
|
|
|
|
operator: '=', |
|
|
|
|
value: 'foo', |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
}) |
|
|
|
|
).toBe('{resource.footag>=1234 && resource.name="foo"}'); |
|
|
|
|
}); |
|
|
|
|
it('an empty array', () => { |
|
|
|
|
expect(lp.generateQueryFromFilters({ adhocFilters: [] })).toBe('{}'); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('a filter with values', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters({ adhocFilters: [{ key: 'footag', operator: '=', value: 'foovalue' }] }) |
|
|
|
|
).toBe('{footag="foovalue"}'); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('two filters with values', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters({ |
|
|
|
|
adhocFilters: [ |
|
|
|
|
{ key: 'footag', operator: '=', value: 'foovalue' }, |
|
|
|
|
{ key: 'bartag', operator: '=', value: '0' }, |
|
|
|
|
], |
|
|
|
|
}) |
|
|
|
|
).toBe('{footag="foovalue" && bartag=0}'); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('a filter with enum intrinsic values', () => { |
|
|
|
|
expect(lp.generateQueryFromFilters({ adhocFilters: [{ key: 'kind', operator: '=', value: 'server' }] })).toBe( |
|
|
|
|
'{kind=server}' |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('a filter with non-enum intrinsic values', () => { |
|
|
|
|
expect( |
|
|
|
|
lp.generateQueryFromFilters({ adhocFilters: [{ key: 'name', operator: '=', value: 'my-server' }] }) |
|
|
|
|
).toBe('{name="my-server"}'); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const setup = (tagsV1?: string[], tagsV2?: Scope[]) => { |
|
|
|
|