def test_valid_query(self): query = '{"aggs": {"agg": {"terms": {"field": "a1"},' \ '"aggs": {"agg": {"terms": {"field": "b2"},' \ '"aggs": {"agg": {"date_histogram": {"field": "@timestamp","interval": "hour"},' \ '"aggs": {"max": {"max": {"field": "timing"}}}}}}}}}}' # Should not throw an exception validate_query(json.loads(query))
def test_unsupported_metric(self): query = '{"aggs": {"agg": {"terms": {"field": "data"},' \ '"aggs": {"agg": {"date_histogram": {"field": "@timestamp","interval": "hour"},' \ '"aggs": {"raw_document": {"max": {"field": "timing"}}}}}}}}' with self.assertRaises(ValidationError) as e: validate_query(json.loads(query)) self.assertEqual(e.exception, '{}: unsupported metric "raw_document."'.format(ES_VALIDATION_MSG_PREFIX))
def test_grafana_query(self): """Basic query building""" series = get_json_file('grafana/query_builder/grafana_series.json') created_query = build_query(series, min_time='now-1h') expected_query = get_json_file( 'grafana/query_builder/grafana_series_query.json') self.assertEqual(expected_query, created_query) validate_query(created_query)
def test_nonmatching_metric_name(self): query = '{"aggs": {"agg": {"terms": {"field": "data"},' \ '"aggs": {"agg": {"date_histogram": {"field": "@timestamp","interval": "hour"},' \ '"aggs": {"min": {"max": {"field": "timing"}}}}}}}}' with self.assertRaises(ValidationError) as e: validate_query(json.loads(query)) self.assertEqual(e.exception, '{}: metric name must be the same as the metric type.' .format(ES_VALIDATION_MSG_PREFIX))
def test_no_date_histogram(self): query = '{"aggs": {"agg": {"terms": {"field": "no"},' \ '"aggs": {"agg": {"terms": {"field": "data"},' \ '"aggs": {"max": {"max": {"field": "timing"}}}}}}}}' with self.assertRaises(ValidationError) as e: validate_query(json.loads(query)) self.assertEqual(e.exception, '{}: query must at least include a date_histogram aggregation.' .format(ES_VALIDATION_MSG_PREFIX))
def clean(self, *args, **kwargs): """Validate the query""" try: queries = json.loads(self.queries) except ValueError: raise ValidationError('Queries are not json-parsable') for query in queries: validate_query(query)
def test_filters_agg(self): """filter aggregation""" series = get_json_file( 'grafana/query_builder/grafana_filters_agg.json') created_query = build_query(series, min_time='now-1h') expected_query = get_json_file( 'grafana/query_builder/grafana_filters_agg_query.json') self.assertEqual(expected_query, created_query) validate_query(expected_query)
def test_count(self): """Count metrics get converted to value_count(timeField)""" series = get_json_file( 'grafana/query_builder/grafana_series_count.json') created_query = build_query(series, min_time='now-3d') expected_query = get_json_file( 'grafana/query_builder/grafana_series_count_query.json') self.assertEqual(expected_query, created_query) validate_query(created_query)
def test_multiple_metrics(self): """Multiple metrics (for example, sum and avg)""" series = get_json_file( 'grafana/query_builder/grafana_multiple_metrics.json') created_query = build_query(series, min_time='now-30m') expected_query = get_json_file( 'grafana/query_builder/grafana_multiple_metrics_query.json') self.assertEqual(expected_query, created_query) validate_query(created_query)
def test_multiple_aggs(self): """Multiple terms aggregations""" series = get_json_file( 'grafana/query_builder/grafana_series_terms.json') created_query = build_query(series, min_time='now-100m') expected_query = get_json_file( 'grafana/query_builder/grafana_series_terms_query.json') self.assertEqual(expected_query, created_query) validate_query(created_query)
def test_order_by_sub_agg(self): """Order by sub-aggregations""" series = get_json_file( 'grafana/query_builder/grafana_series_order_sub_agg.json') created_query = build_query(series, min_time='now-100m') expected_query = get_json_file( 'grafana/query_builder/grafana_series_order_sub_agg_query.json') self.assertEqual(expected_query, created_query) validate_query(created_query)
def test_not_agg(self): """Aggregations must be named 'agg'""" query = '{"aggs": {"notagg": {"terms": {"field": "data"},' \ '"aggs": {"agg": {"date_histogram": {"field": "@timestamp","interval": "hour"},' \ '"aggs": {"max": {"max": {"field": "timing"}}}}}}}}' with self.assertRaises(ValidationError) as e: validate_query(json.loads(query)) self.assertEqual(e.exception, '{}: aggregations should be named "agg."'.format(ES_VALIDATION_MSG_PREFIX))
def test_external_date_hist(self): """date_histogram must be the innermost aggregation""" query = '{"aggs": {"agg": {"date_histogram": {"field": "@timestamp","interval": "hour"},' \ '"aggs": {"agg": {"terms": {"field": "data"},' \ '"aggs": {"max": {"max": {"field": "timing"}}}}}}}}' with self.assertRaises(ValidationError) as e: validate_query(json.loads(query)) self.assertEqual(e.exception, '{}: date_histogram must be the innermost aggregation (besides metrics).' .format(ES_VALIDATION_MSG_PREFIX))
def test_moving_avg_adjusted(self): """ Moving average metric with hidden field. Should add interval (5m) * moving average range (10) to the time range to prevent partial points. """ series = get_json_file('grafana/query_builder/grafana_moving_avg.json') created_query = adjust_time_range( [build_query(series, min_time='now-3h')], 180)[0] expected_query = get_json_file( 'grafana/query_builder/grafana_adjusted_moving_avg_query.json') self.assertEqual(expected_query, created_query) validate_query(created_query)
def test_derivative_adjusted(self): """ Derivative metric with hidden field. Should add 1 * interval (1m) to the time range to prevent issues with partial points being used to calculate the derivative. """ series = get_json_file('grafana/query_builder/grafana_derivative.json') created_query = adjust_time_range( [build_query(series, min_time='now-3h')], 180)[0] expected_query = get_json_file( 'grafana/query_builder/grafana_adjusted_derivative_query.json') self.assertEqual(expected_query, created_query) validate_query(created_query)
def test_auto_time_field(self): """Make sure 'auto' fields are getting templated correctly""" templates = get_json_file( 'grafana/templating/auto_time_templating.json') templating_dict = create_elasticsearch_templating_dict(templates) panel = get_json_file('grafana/templating/auto_time_panel.json') templated_panel = template_response(panel, templating_dict) created_query = build_query(templated_panel, default_interval='2m') expected_query = get_json_file( 'grafana/templating/auto_time_panel_query.json') self.assertEqual(expected_query, created_query) validate_query(created_query)
def test_templating(self): """Test Grafana panel templating handling""" templates = get_json_file('grafana/templating/templating_info.json') templating_dict = create_elasticsearch_templating_dict(templates) panel_info = get_json_file('grafana/templating/templating_panel.json') expected_panel = get_json_file( 'grafana/templating/templating_panel_final.json') templated_panel = template_response(panel_info, templating_dict) self.assertEqual(templated_panel, expected_panel) # Make sure we can make a valid query from the output query = build_query(templated_panel, min_time='now-1h') validate_query(query)