Expressions: Create json schema for query types (#84032)

This commit is contained in:
Ryan McKinley
2024-03-26 06:58:56 +02:00
committed by GitHub
parent 2e06677240
commit 4cda34ff7d
40 changed files with 4649 additions and 654 deletions
@@ -1,211 +0,0 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
//
// Generated by:
// public/app/plugins/gen.go
// Using jennies:
// PluginGoTypesJenny
//
// Run 'make gen-cue' from repository root to regenerate.
package dataquery
// Defines values for NodesQueryType.
const (
NodesQueryTypeFeatureShowcase NodesQueryType = "feature_showcase"
NodesQueryTypeRandom NodesQueryType = "random"
NodesQueryTypeRandomEdges NodesQueryType = "random edges"
NodesQueryTypeResponseMedium NodesQueryType = "response_medium"
NodesQueryTypeResponseSmall NodesQueryType = "response_small"
)
// Defines values for StreamingQueryType.
const (
StreamingQueryTypeFetch StreamingQueryType = "fetch"
StreamingQueryTypeLogs StreamingQueryType = "logs"
StreamingQueryTypeSignal StreamingQueryType = "signal"
StreamingQueryTypeTraces StreamingQueryType = "traces"
)
// Defines values for TestDataDataQueryErrorType.
const (
TestDataDataQueryErrorTypeFrontendException TestDataDataQueryErrorType = "frontend_exception"
TestDataDataQueryErrorTypeFrontendObservable TestDataDataQueryErrorType = "frontend_observable"
TestDataDataQueryErrorTypeServerPanic TestDataDataQueryErrorType = "server_panic"
)
// Defines values for TestDataQueryType.
const (
TestDataQueryTypeAnnotations TestDataQueryType = "annotations"
TestDataQueryTypeArrow TestDataQueryType = "arrow"
TestDataQueryTypeCsvContent TestDataQueryType = "csv_content"
TestDataQueryTypeCsvFile TestDataQueryType = "csv_file"
TestDataQueryTypeCsvMetricValues TestDataQueryType = "csv_metric_values"
TestDataQueryTypeDatapointsOutsideRange TestDataQueryType = "datapoints_outside_range"
TestDataQueryTypeExponentialHeatmapBucketData TestDataQueryType = "exponential_heatmap_bucket_data"
TestDataQueryTypeFlameGraph TestDataQueryType = "flame_graph"
TestDataQueryTypeGrafanaApi TestDataQueryType = "grafana_api"
TestDataQueryTypeLinearHeatmapBucketData TestDataQueryType = "linear_heatmap_bucket_data"
TestDataQueryTypeLive TestDataQueryType = "live"
TestDataQueryTypeLogs TestDataQueryType = "logs"
TestDataQueryTypeManualEntry TestDataQueryType = "manual_entry"
TestDataQueryTypeNoDataPoints TestDataQueryType = "no_data_points"
TestDataQueryTypeNodeGraph TestDataQueryType = "node_graph"
TestDataQueryTypePredictableCsvWave TestDataQueryType = "predictable_csv_wave"
TestDataQueryTypePredictablePulse TestDataQueryType = "predictable_pulse"
TestDataQueryTypeRandomWalk TestDataQueryType = "random_walk"
TestDataQueryTypeRandomWalkTable TestDataQueryType = "random_walk_table"
TestDataQueryTypeRandomWalkWithError TestDataQueryType = "random_walk_with_error"
TestDataQueryTypeRawFrame TestDataQueryType = "raw_frame"
TestDataQueryTypeServerError500 TestDataQueryType = "server_error_500"
TestDataQueryTypeSimulation TestDataQueryType = "simulation"
TestDataQueryTypeSlowQuery TestDataQueryType = "slow_query"
TestDataQueryTypeStreamingClient TestDataQueryType = "streaming_client"
TestDataQueryTypeTableStatic TestDataQueryType = "table_static"
TestDataQueryTypeTrace TestDataQueryType = "trace"
TestDataQueryTypeUsa TestDataQueryType = "usa"
TestDataQueryTypeVariablesQuery TestDataQueryType = "variables-query"
)
// CSVWave defines model for CSVWave.
type CSVWave struct {
Labels *string `json:"labels,omitempty"`
Name *string `json:"name,omitempty"`
TimeStep *int64 `json:"timeStep,omitempty"`
ValuesCSV *string `json:"valuesCSV,omitempty"`
}
// These are the common properties available to all queries in all datasources.
// Specific implementations will *extend* this interface, adding the required
// properties for the given context.
type DataQuery struct {
// For mixed data sources the selected datasource is on the query level.
// For non mixed scenarios this is undefined.
// TODO find a better way to do this ^ that's friendly to schema
// TODO this shouldn't be unknown but DataSourceRef | null
Datasource *any `json:"datasource,omitempty"`
// If hide is set to true, Grafana will filter out the response(s) associated with this query before returning it to the panel.
Hide *bool `json:"hide,omitempty"`
// Specify the query flavor
// TODO make this required and give it a default
QueryType *string `json:"queryType,omitempty"`
// A unique identifier for the query within the list of targets.
// In server side expressions, the refId is used as a variable name to identify results.
// By default, the UI will assign A->Z; however setting meaningful names may be useful.
RefId string `json:"refId"`
}
// NodesQuery defines model for NodesQuery.
type NodesQuery struct {
Count *int64 `json:"count,omitempty"`
Seed *int64 `json:"seed,omitempty"`
Type *NodesQueryType `json:"type,omitempty"`
}
// NodesQueryType defines model for NodesQuery.Type.
type NodesQueryType string
// PulseWaveQuery defines model for PulseWaveQuery.
type PulseWaveQuery struct {
OffCount *int64 `json:"offCount,omitempty"`
OffValue *float64 `json:"offValue,omitempty"`
OnCount *int64 `json:"onCount,omitempty"`
OnValue *float64 `json:"onValue,omitempty"`
TimeStep *int64 `json:"timeStep,omitempty"`
}
// TODO: Should this live here given it's not used in the dataquery?
type Scenario struct {
Description *string `json:"description,omitempty"`
HideAliasField *bool `json:"hideAliasField,omitempty"`
Id string `json:"id"`
Name string `json:"name"`
StringInput string `json:"stringInput"`
}
// SimulationQuery defines model for SimulationQuery.
type SimulationQuery struct {
Config map[string]any `json:"config,omitempty"`
Key struct {
Tick float64 `json:"tick"`
Type string `json:"type"`
Uid *string `json:"uid,omitempty"`
} `json:"key"`
Last *bool `json:"last,omitempty"`
Stream *bool `json:"stream,omitempty"`
}
// StreamingQuery defines model for StreamingQuery.
type StreamingQuery struct {
Bands *int32 `json:"bands,omitempty"`
Noise int32 `json:"noise"`
Speed int32 `json:"speed"`
Spread int32 `json:"spread"`
Type StreamingQueryType `json:"type"`
Url *string `json:"url,omitempty"`
}
// StreamingQueryType defines model for StreamingQuery.Type.
type StreamingQueryType string
// TestDataDataQuery defines model for TestDataDataQuery.
type TestDataDataQuery struct {
Alias *string `json:"alias,omitempty"`
Channel *string `json:"channel,omitempty"`
CsvContent *string `json:"csvContent,omitempty"`
CsvFileName *string `json:"csvFileName,omitempty"`
CsvWave []CSVWave `json:"csvWave,omitempty"`
// For mixed data sources the selected datasource is on the query level.
// For non mixed scenarios this is undefined.
// TODO find a better way to do this ^ that's friendly to schema
// TODO this shouldn't be unknown but DataSourceRef | null
Datasource *any `json:"datasource,omitempty"`
// Drop percentage (the chance we will lose a point 0-100)
DropPercent *float64 `json:"dropPercent,omitempty"`
ErrorType *TestDataDataQueryErrorType `json:"errorType,omitempty"`
FlamegraphDiff *bool `json:"flamegraphDiff,omitempty"`
// If hide is set to true, Grafana will filter out the response(s) associated with this query before returning it to the panel.
Hide *bool `json:"hide,omitempty"`
Labels *string `json:"labels,omitempty"`
LevelColumn *bool `json:"levelColumn,omitempty"`
Lines *int64 `json:"lines,omitempty"`
Nodes *NodesQuery `json:"nodes,omitempty"`
Points [][]any `json:"points,omitempty"`
PulseWave *PulseWaveQuery `json:"pulseWave,omitempty"`
// Specify the query flavor
// TODO make this required and give it a default
QueryType *string `json:"queryType,omitempty"`
RawFrameContent *string `json:"rawFrameContent,omitempty"`
// A unique identifier for the query within the list of targets.
// In server side expressions, the refId is used as a variable name to identify results.
// By default, the UI will assign A->Z; however setting meaningful names may be useful.
RefId *string `json:"refId,omitempty"`
ScenarioId *TestDataQueryType `json:"scenarioId,omitempty"`
SeriesCount *int32 `json:"seriesCount,omitempty"`
Sim *SimulationQuery `json:"sim,omitempty"`
SpanCount *int32 `json:"spanCount,omitempty"`
Stream *StreamingQuery `json:"stream,omitempty"`
StringInput *string `json:"stringInput,omitempty"`
Usa *USAQuery `json:"usa,omitempty"`
}
// TestDataDataQueryErrorType defines model for TestDataDataQuery.ErrorType.
type TestDataDataQueryErrorType string
// TestDataQueryType defines model for TestDataQueryType.
type TestDataQueryType string
// USAQuery defines model for USAQuery.
type USAQuery struct {
Fields []string `json:"fields,omitempty"`
Mode *string `json:"mode,omitempty"`
Period *string `json:"period,omitempty"`
States []string `json:"states,omitempty"`
}
@@ -0,0 +1,178 @@
package kinds
import (
"embed"
"encoding/json"
)
// NodesQueryType defines model for NodesQuery.Type.
// +enum
type NodesQueryType string
const (
NodesQueryTypeRandom NodesQueryType = "random"
NodesQueryTypeRandomEdges NodesQueryType = "random edges"
NodesQueryTypeResponseMedium NodesQueryType = "response_medium"
NodesQueryTypeResponseSmall NodesQueryType = "response_small"
NodesQueryTypeFeatureShowcase NodesQueryType = "feature_showcase"
)
// StreamingQueryType defines model for StreamingQuery.Type.
// +enum
type StreamingQueryType string
const (
StreamingQueryTypeFetch StreamingQueryType = "fetch"
StreamingQueryTypeLogs StreamingQueryType = "logs"
StreamingQueryTypeSignal StreamingQueryType = "signal"
StreamingQueryTypeTraces StreamingQueryType = "traces"
)
// ErrorType defines model for TestDataQuery.ErrorType.
// +enum
type ErrorType string
const (
ErrorTypeFrontendException ErrorType = "frontend_exception"
ErrorTypeFrontendObservable ErrorType = "frontend_observable"
ErrorTypeServerPanic ErrorType = "server_panic"
)
// TestDataQueryType defines model for TestDataQueryType.
// +enum
type TestDataQueryType string
// Defines values for TestDataQueryType.
const (
TestDataQueryTypeAnnotations TestDataQueryType = "annotations"
TestDataQueryTypeArrow TestDataQueryType = "arrow"
TestDataQueryTypeCsvContent TestDataQueryType = "csv_content"
TestDataQueryTypeCsvFile TestDataQueryType = "csv_file"
TestDataQueryTypeCsvMetricValues TestDataQueryType = "csv_metric_values"
TestDataQueryTypeDatapointsOutsideRange TestDataQueryType = "datapoints_outside_range"
TestDataQueryTypeExponentialHeatmapBucketData TestDataQueryType = "exponential_heatmap_bucket_data"
TestDataQueryTypeFlameGraph TestDataQueryType = "flame_graph"
TestDataQueryTypeGrafanaApi TestDataQueryType = "grafana_api"
TestDataQueryTypeLinearHeatmapBucketData TestDataQueryType = "linear_heatmap_bucket_data"
TestDataQueryTypeLive TestDataQueryType = "live"
TestDataQueryTypeLogs TestDataQueryType = "logs"
TestDataQueryTypeManualEntry TestDataQueryType = "manual_entry"
TestDataQueryTypeNoDataPoints TestDataQueryType = "no_data_points"
TestDataQueryTypeNodeGraph TestDataQueryType = "node_graph"
TestDataQueryTypePredictableCsvWave TestDataQueryType = "predictable_csv_wave"
TestDataQueryTypePredictablePulse TestDataQueryType = "predictable_pulse"
TestDataQueryTypeRandomWalk TestDataQueryType = "random_walk"
TestDataQueryTypeRandomWalkTable TestDataQueryType = "random_walk_table"
TestDataQueryTypeRandomWalkWithError TestDataQueryType = "random_walk_with_error"
TestDataQueryTypeRawFrame TestDataQueryType = "raw_frame"
TestDataQueryTypeServerError500 TestDataQueryType = "server_error_500"
TestDataQueryTypeSimulation TestDataQueryType = "simulation"
TestDataQueryTypeSlowQuery TestDataQueryType = "slow_query"
TestDataQueryTypeStreamingClient TestDataQueryType = "streaming_client"
TestDataQueryTypeTableStatic TestDataQueryType = "table_static"
TestDataQueryTypeTrace TestDataQueryType = "trace"
TestDataQueryTypeUsa TestDataQueryType = "usa"
TestDataQueryTypeVariablesQuery TestDataQueryType = "variables-query"
)
// TestDataQuery defines model for TestDataQuery.
type TestDataQuery struct {
ScenarioId TestDataQueryType `json:"scenarioId,omitempty"`
Alias string `json:"alias,omitempty"`
Labels string `json:"labels,omitempty"`
// common parameter used by many query types
StringInput string `json:"stringInput,omitempty"`
CsvContent string `json:"csvContent,omitempty"`
CsvFileName string `json:"csvFileName,omitempty"`
CsvWave []CSVWave `json:"csvWave,omitempty"`
// Used for live query
Channel string `json:"channel,omitempty"`
// Drop percentage (the chance we will lose a point 0-100)
DropPercent float64 `json:"dropPercent,omitempty"`
ErrorType ErrorType `json:"errorType,omitempty"`
FlamegraphDiff bool `json:"flamegraphDiff,omitempty"`
LevelColumn bool `json:"levelColumn,omitempty"`
StartValue float64 `json:"startValue,omitempty"`
Spread float64 `json:"spread,omitempty"`
Noise float64 `json:"noise,omitempty"`
Min *float64 `json:"min,omitempty"`
Max *float64 `json:"max,omitempty"`
WithNil bool `json:"withNil,omitempty"`
Lines int64 `json:"lines,omitempty"`
Points [][]any `json:"points,omitempty"`
RawFrameContent string `json:"rawFrameContent,omitempty"`
SeriesCount int `json:"seriesCount,omitempty"`
SpanCount int `json:"spanCount,omitempty"`
Nodes *NodesQuery `json:"nodes,omitempty"`
PulseWave *PulseWaveQuery `json:"pulseWave,omitempty"`
Sim *SimulationQuery `json:"sim,omitempty"`
Stream *StreamingQuery `json:"stream,omitempty"`
Usa *USAQuery `json:"usa,omitempty"`
}
// CSVWave defines model for CSVWave.
type CSVWave struct {
TimeStep int64 `json:"timeStep,omitempty"`
ValuesCSV string `json:"valuesCSV,omitempty"`
Labels string `json:"labels,omitempty"`
Name string `json:"name,omitempty"`
}
// NodesQuery defines model for NodesQuery.
type NodesQuery struct {
Count int64 `json:"count,omitempty"`
Seed int64 `json:"seed,omitempty"`
Type NodesQueryType `json:"type,omitempty"`
}
// PulseWaveQuery defines model for PulseWaveQuery.
type PulseWaveQuery struct {
OffCount int64 `json:"offCount,omitempty"`
OffValue float64 `json:"offValue,omitempty"`
OnCount int64 `json:"onCount,omitempty"`
OnValue float64 `json:"onValue,omitempty"`
TimeStep int64 `json:"timeStep,omitempty"`
}
// SimulationQuery defines model for SimulationQuery.
type SimulationQuery struct {
Config map[string]any `json:"config,omitempty"`
Key struct {
Tick float64 `json:"tick"`
Type string `json:"type"`
Uid *string `json:"uid,omitempty"`
} `json:"key"`
Last bool `json:"last,omitempty"`
Stream bool `json:"stream,omitempty"`
}
// StreamingQuery defines model for StreamingQuery.
type StreamingQuery struct {
Bands int32 `json:"bands,omitempty"`
Noise float64 `json:"noise"`
Speed float64 `json:"speed"`
Spread float64 `json:"spread"`
Type StreamingQueryType `json:"type"`
Url string `json:"url,omitempty"`
}
// USAQuery defines model for USAQuery.
type USAQuery struct {
Fields []string `json:"fields,omitempty"`
Mode string `json:"mode,omitempty"`
Period string `json:"period,omitempty"`
States []string `json:"states,omitempty"`
}
//go:embed query.types.json
var f embed.FS
// QueryTypeDefinitionsJSON returns the query type definitions
func QueryTypeDefinitionsJSON() (json.RawMessage, error) {
return f.ReadFile("query.types.json")
}
@@ -0,0 +1,28 @@
{
"type": "table",
"targets": [
{
"refId": "A",
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "TheUID"
},
"scenarioId": "random_walk"
},
{
"refId": "B",
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "TheUID"
},
"pulseWave": {
"offCount": 20,
"offValue": 1.23,
"onCount": 10,
"onValue": 4.56,
"timeStep": 1000
},
"scenarioId": "predictable_pulse"
}
]
}
@@ -0,0 +1,411 @@
{
"type": "object",
"required": [
"targets",
"type"
],
"properties": {
"targets": {
"type": "array",
"items": {
"description": "TestDataQuery defines model for TestDataQuery.",
"type": "object",
"properties": {
"alias": {
"type": "string"
},
"channel": {
"description": "Used for live query",
"type": "string"
},
"csvContent": {
"type": "string"
},
"csvFileName": {
"type": "string"
},
"csvWave": {
"type": "array",
"items": {
"description": "CSVWave defines model for CSVWave.",
"type": "object",
"properties": {
"labels": {
"type": "string"
},
"name": {
"type": "string"
},
"timeStep": {
"type": "integer"
},
"valuesCSV": {
"type": "string"
}
},
"additionalProperties": false
}
},
"datasource": {
"description": "The datasource",
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"description": "The datasource plugin type",
"type": "string",
"pattern": "^grafana-testdata-datasource$|^testdata$"
},
"uid": {
"description": "Datasource UID",
"type": "string"
}
},
"additionalProperties": false
},
"dropPercent": {
"description": "Drop percentage (the chance we will lose a point 0-100)",
"type": "number"
},
"errorType": {
"description": "Possible enum values:\n - `\"frontend_exception\"` \n - `\"frontend_observable\"` \n - `\"server_panic\"` ",
"type": "string",
"enum": [
"frontend_exception",
"frontend_observable",
"server_panic"
],
"x-enum-description": {}
},
"flamegraphDiff": {
"type": "boolean"
},
"hide": {
"description": "true if query is disabled (ie should not be returned to the dashboard)\nNOTE: this does not always imply that the query should not be executed since\nthe results from a hidden query may be used as the input to other queries (SSE etc)",
"type": "boolean"
},
"intervalMs": {
"description": "Interval is the suggested duration between time points in a time series query.\nNOTE: the values for intervalMs is not saved in the query model. It is typically calculated\nfrom the interval required to fill a pixels in the visualization",
"type": "number"
},
"labels": {
"type": "string"
},
"levelColumn": {
"type": "boolean"
},
"lines": {
"type": "integer"
},
"max": {
"type": "number"
},
"maxDataPoints": {
"description": "MaxDataPoints is the maximum number of data points that should be returned from a time series query.\nNOTE: the values for maxDataPoints is not saved in the query model. It is typically calculated\nfrom the number of pixels visible in a visualization",
"type": "integer"
},
"min": {
"type": "number"
},
"nodes": {
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"seed": {
"type": "integer"
},
"type": {
"description": "Possible enum values:\n - `\"random\"` \n - `\"random edges\"` \n - `\"response_medium\"` \n - `\"response_small\"` \n - `\"feature_showcase\"` ",
"type": "string",
"enum": [
"random",
"random edges",
"response_medium",
"response_small",
"feature_showcase"
],
"x-enum-description": {}
}
},
"additionalProperties": false
},
"noise": {
"type": "number"
},
"points": {
"type": "array",
"items": {
"type": "array"
}
},
"pulseWave": {
"type": "object",
"properties": {
"offCount": {
"type": "integer"
},
"offValue": {
"type": "number"
},
"onCount": {
"type": "integer"
},
"onValue": {
"type": "number"
},
"timeStep": {
"type": "integer"
}
},
"additionalProperties": false
},
"queryType": {
"description": "QueryType is an optional identifier for the type of query.\nIt can be used to distinguish different types of queries.",
"type": "string"
},
"rawFrameContent": {
"type": "string"
},
"refId": {
"description": "RefID is the unique identifier of the query, set by the frontend call.",
"type": "string"
},
"resultAssertions": {
"description": "Optionally define expected query result behavior",
"type": "object",
"required": [
"typeVersion"
],
"properties": {
"maxFrames": {
"description": "Maximum frame count",
"type": "integer"
},
"type": {
"description": "Type asserts that the frame matches a known type structure.\n\n\nPossible enum values:\n - `\"\"` \n - `\"timeseries-wide\"` \n - `\"timeseries-long\"` \n - `\"timeseries-many\"` \n - `\"timeseries-multi\"` \n - `\"directory-listing\"` \n - `\"table\"` \n - `\"numeric-wide\"` \n - `\"numeric-multi\"` \n - `\"numeric-long\"` \n - `\"log-lines\"` ",
"type": "string",
"enum": [
"",
"timeseries-wide",
"timeseries-long",
"timeseries-many",
"timeseries-multi",
"directory-listing",
"table",
"numeric-wide",
"numeric-multi",
"numeric-long",
"log-lines"
],
"x-enum-description": {}
},
"typeVersion": {
"description": "TypeVersion is the version of the Type property. Versions greater than 0.0 correspond to the dataplane\ncontract documentation https://grafana.github.io/dataplane/contract/.",
"type": "array",
"maxItems": 2,
"minItems": 2,
"items": {
"type": "integer"
}
}
},
"additionalProperties": false
},
"scenarioId": {
"description": "Possible enum values:\n - `\"annotations\"` \n - `\"arrow\"` \n - `\"csv_content\"` \n - `\"csv_file\"` \n - `\"csv_metric_values\"` \n - `\"datapoints_outside_range\"` \n - `\"exponential_heatmap_bucket_data\"` \n - `\"flame_graph\"` \n - `\"grafana_api\"` \n - `\"linear_heatmap_bucket_data\"` \n - `\"live\"` \n - `\"logs\"` \n - `\"manual_entry\"` \n - `\"no_data_points\"` \n - `\"node_graph\"` \n - `\"predictable_csv_wave\"` \n - `\"predictable_pulse\"` \n - `\"random_walk\"` \n - `\"random_walk_table\"` \n - `\"random_walk_with_error\"` \n - `\"raw_frame\"` \n - `\"server_error_500\"` \n - `\"simulation\"` \n - `\"slow_query\"` \n - `\"streaming_client\"` \n - `\"table_static\"` \n - `\"trace\"` \n - `\"usa\"` \n - `\"variables-query\"` ",
"type": "string",
"enum": [
"annotations",
"arrow",
"csv_content",
"csv_file",
"csv_metric_values",
"datapoints_outside_range",
"exponential_heatmap_bucket_data",
"flame_graph",
"grafana_api",
"linear_heatmap_bucket_data",
"live",
"logs",
"manual_entry",
"no_data_points",
"node_graph",
"predictable_csv_wave",
"predictable_pulse",
"random_walk",
"random_walk_table",
"random_walk_with_error",
"raw_frame",
"server_error_500",
"simulation",
"slow_query",
"streaming_client",
"table_static",
"trace",
"usa",
"variables-query"
],
"x-enum-description": {}
},
"seriesCount": {
"type": "integer"
},
"sim": {
"type": "object",
"required": [
"key"
],
"properties": {
"config": {
"type": "object"
},
"key": {
"type": "object",
"required": [
"tick",
"type"
],
"properties": {
"tick": {
"type": "number"
},
"type": {
"type": "string"
},
"uid": {
"type": "string"
}
},
"additionalProperties": false
},
"last": {
"type": "boolean"
},
"stream": {
"type": "boolean"
}
},
"additionalProperties": false
},
"spanCount": {
"type": "integer"
},
"spread": {
"type": "number"
},
"startValue": {
"type": "number"
},
"stream": {
"type": "object",
"required": [
"noise",
"speed",
"spread",
"type"
],
"properties": {
"bands": {
"type": "integer"
},
"noise": {
"type": "number"
},
"speed": {
"type": "number"
},
"spread": {
"type": "number"
},
"type": {
"description": "Possible enum values:\n - `\"fetch\"` \n - `\"logs\"` \n - `\"signal\"` \n - `\"traces\"` ",
"type": "string",
"enum": [
"fetch",
"logs",
"signal",
"traces"
],
"x-enum-description": {}
},
"url": {
"type": "string"
}
},
"additionalProperties": false
},
"stringInput": {
"description": "common parameter used by many query types",
"type": "string"
},
"timeRange": {
"description": "TimeRange represents the query range\nNOTE: unlike generic /ds/query, we can now send explicit time values in each query\nNOTE: the values for timeRange are not saved in a dashboard, they are constructed on the fly",
"type": "object",
"required": [
"from",
"to"
],
"properties": {
"from": {
"description": "From is the start time of the query.",
"type": "string",
"default": "now-6h",
"examples": [
"now-1h"
]
},
"to": {
"description": "To is the end time of the query.",
"type": "string",
"default": "now",
"examples": [
"now"
]
}
},
"additionalProperties": false
},
"usa": {
"type": "object",
"properties": {
"fields": {
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"type": "string"
},
"period": {
"type": "string"
},
"states": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
},
"withNil": {
"type": "boolean"
}
},
"additionalProperties": false,
"$schema": "https://json-schema.org/draft-04/schema#"
}
},
"type": {
"description": "the panel type",
"type": "string"
}
},
"additionalProperties": true,
"$schema": "https://json-schema.org/draft-04/schema#"
}
@@ -0,0 +1,25 @@
{
"from": "now-1h",
"to": "now",
"queries": [
{
"refId": "A",
"maxDataPoints": 1000,
"intervalMs": 5,
"scenarioId": "random_walk"
},
{
"refId": "B",
"maxDataPoints": 1000,
"intervalMs": 5,
"pulseWave": {
"offCount": 20,
"offValue": 1.23,
"onCount": 10,
"onValue": 4.56,
"timeStep": 1000
},
"scenarioId": "predictable_pulse"
}
]
}
@@ -0,0 +1,421 @@
{
"type": "object",
"required": [
"queries"
],
"properties": {
"$schema": {
"description": "helper",
"type": "string"
},
"debug": {
"type": "boolean"
},
"from": {
"description": "From Start time in epoch timestamps in milliseconds or relative using Grafana time units.",
"type": "string"
},
"queries": {
"type": "array",
"items": {
"description": "TestDataQuery defines model for TestDataQuery.",
"type": "object",
"properties": {
"alias": {
"type": "string"
},
"channel": {
"description": "Used for live query",
"type": "string"
},
"csvContent": {
"type": "string"
},
"csvFileName": {
"type": "string"
},
"csvWave": {
"type": "array",
"items": {
"description": "CSVWave defines model for CSVWave.",
"type": "object",
"properties": {
"labels": {
"type": "string"
},
"name": {
"type": "string"
},
"timeStep": {
"type": "integer"
},
"valuesCSV": {
"type": "string"
}
},
"additionalProperties": false
}
},
"datasource": {
"description": "The datasource",
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"description": "The datasource plugin type",
"type": "string",
"pattern": "^grafana-testdata-datasource$|^testdata$"
},
"uid": {
"description": "Datasource UID",
"type": "string"
}
},
"additionalProperties": false
},
"dropPercent": {
"description": "Drop percentage (the chance we will lose a point 0-100)",
"type": "number"
},
"errorType": {
"description": "Possible enum values:\n - `\"frontend_exception\"` \n - `\"frontend_observable\"` \n - `\"server_panic\"` ",
"type": "string",
"enum": [
"frontend_exception",
"frontend_observable",
"server_panic"
],
"x-enum-description": {}
},
"flamegraphDiff": {
"type": "boolean"
},
"hide": {
"description": "true if query is disabled (ie should not be returned to the dashboard)\nNOTE: this does not always imply that the query should not be executed since\nthe results from a hidden query may be used as the input to other queries (SSE etc)",
"type": "boolean"
},
"intervalMs": {
"description": "Interval is the suggested duration between time points in a time series query.\nNOTE: the values for intervalMs is not saved in the query model. It is typically calculated\nfrom the interval required to fill a pixels in the visualization",
"type": "number"
},
"labels": {
"type": "string"
},
"levelColumn": {
"type": "boolean"
},
"lines": {
"type": "integer"
},
"max": {
"type": "number"
},
"maxDataPoints": {
"description": "MaxDataPoints is the maximum number of data points that should be returned from a time series query.\nNOTE: the values for maxDataPoints is not saved in the query model. It is typically calculated\nfrom the number of pixels visible in a visualization",
"type": "integer"
},
"min": {
"type": "number"
},
"nodes": {
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"seed": {
"type": "integer"
},
"type": {
"description": "Possible enum values:\n - `\"random\"` \n - `\"random edges\"` \n - `\"response_medium\"` \n - `\"response_small\"` \n - `\"feature_showcase\"` ",
"type": "string",
"enum": [
"random",
"random edges",
"response_medium",
"response_small",
"feature_showcase"
],
"x-enum-description": {}
}
},
"additionalProperties": false
},
"noise": {
"type": "number"
},
"points": {
"type": "array",
"items": {
"type": "array"
}
},
"pulseWave": {
"type": "object",
"properties": {
"offCount": {
"type": "integer"
},
"offValue": {
"type": "number"
},
"onCount": {
"type": "integer"
},
"onValue": {
"type": "number"
},
"timeStep": {
"type": "integer"
}
},
"additionalProperties": false
},
"queryType": {
"description": "QueryType is an optional identifier for the type of query.\nIt can be used to distinguish different types of queries.",
"type": "string"
},
"rawFrameContent": {
"type": "string"
},
"refId": {
"description": "RefID is the unique identifier of the query, set by the frontend call.",
"type": "string"
},
"resultAssertions": {
"description": "Optionally define expected query result behavior",
"type": "object",
"required": [
"typeVersion"
],
"properties": {
"maxFrames": {
"description": "Maximum frame count",
"type": "integer"
},
"type": {
"description": "Type asserts that the frame matches a known type structure.\n\n\nPossible enum values:\n - `\"\"` \n - `\"timeseries-wide\"` \n - `\"timeseries-long\"` \n - `\"timeseries-many\"` \n - `\"timeseries-multi\"` \n - `\"directory-listing\"` \n - `\"table\"` \n - `\"numeric-wide\"` \n - `\"numeric-multi\"` \n - `\"numeric-long\"` \n - `\"log-lines\"` ",
"type": "string",
"enum": [
"",
"timeseries-wide",
"timeseries-long",
"timeseries-many",
"timeseries-multi",
"directory-listing",
"table",
"numeric-wide",
"numeric-multi",
"numeric-long",
"log-lines"
],
"x-enum-description": {}
},
"typeVersion": {
"description": "TypeVersion is the version of the Type property. Versions greater than 0.0 correspond to the dataplane\ncontract documentation https://grafana.github.io/dataplane/contract/.",
"type": "array",
"maxItems": 2,
"minItems": 2,
"items": {
"type": "integer"
}
}
},
"additionalProperties": false
},
"scenarioId": {
"description": "Possible enum values:\n - `\"annotations\"` \n - `\"arrow\"` \n - `\"csv_content\"` \n - `\"csv_file\"` \n - `\"csv_metric_values\"` \n - `\"datapoints_outside_range\"` \n - `\"exponential_heatmap_bucket_data\"` \n - `\"flame_graph\"` \n - `\"grafana_api\"` \n - `\"linear_heatmap_bucket_data\"` \n - `\"live\"` \n - `\"logs\"` \n - `\"manual_entry\"` \n - `\"no_data_points\"` \n - `\"node_graph\"` \n - `\"predictable_csv_wave\"` \n - `\"predictable_pulse\"` \n - `\"random_walk\"` \n - `\"random_walk_table\"` \n - `\"random_walk_with_error\"` \n - `\"raw_frame\"` \n - `\"server_error_500\"` \n - `\"simulation\"` \n - `\"slow_query\"` \n - `\"streaming_client\"` \n - `\"table_static\"` \n - `\"trace\"` \n - `\"usa\"` \n - `\"variables-query\"` ",
"type": "string",
"enum": [
"annotations",
"arrow",
"csv_content",
"csv_file",
"csv_metric_values",
"datapoints_outside_range",
"exponential_heatmap_bucket_data",
"flame_graph",
"grafana_api",
"linear_heatmap_bucket_data",
"live",
"logs",
"manual_entry",
"no_data_points",
"node_graph",
"predictable_csv_wave",
"predictable_pulse",
"random_walk",
"random_walk_table",
"random_walk_with_error",
"raw_frame",
"server_error_500",
"simulation",
"slow_query",
"streaming_client",
"table_static",
"trace",
"usa",
"variables-query"
],
"x-enum-description": {}
},
"seriesCount": {
"type": "integer"
},
"sim": {
"type": "object",
"required": [
"key"
],
"properties": {
"config": {
"type": "object"
},
"key": {
"type": "object",
"required": [
"tick",
"type"
],
"properties": {
"tick": {
"type": "number"
},
"type": {
"type": "string"
},
"uid": {
"type": "string"
}
},
"additionalProperties": false
},
"last": {
"type": "boolean"
},
"stream": {
"type": "boolean"
}
},
"additionalProperties": false
},
"spanCount": {
"type": "integer"
},
"spread": {
"type": "number"
},
"startValue": {
"type": "number"
},
"stream": {
"type": "object",
"required": [
"noise",
"speed",
"spread",
"type"
],
"properties": {
"bands": {
"type": "integer"
},
"noise": {
"type": "number"
},
"speed": {
"type": "number"
},
"spread": {
"type": "number"
},
"type": {
"description": "Possible enum values:\n - `\"fetch\"` \n - `\"logs\"` \n - `\"signal\"` \n - `\"traces\"` ",
"type": "string",
"enum": [
"fetch",
"logs",
"signal",
"traces"
],
"x-enum-description": {}
},
"url": {
"type": "string"
}
},
"additionalProperties": false
},
"stringInput": {
"description": "common parameter used by many query types",
"type": "string"
},
"timeRange": {
"description": "TimeRange represents the query range\nNOTE: unlike generic /ds/query, we can now send explicit time values in each query\nNOTE: the values for timeRange are not saved in a dashboard, they are constructed on the fly",
"type": "object",
"required": [
"from",
"to"
],
"properties": {
"from": {
"description": "From is the start time of the query.",
"type": "string",
"default": "now-6h",
"examples": [
"now-1h"
]
},
"to": {
"description": "To is the end time of the query.",
"type": "string",
"default": "now",
"examples": [
"now"
]
}
},
"additionalProperties": false
},
"usa": {
"type": "object",
"properties": {
"fields": {
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"type": "string"
},
"period": {
"type": "string"
},
"states": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
},
"withNil": {
"type": "boolean"
}
},
"additionalProperties": false,
"$schema": "https://json-schema.org/draft-04/schema#"
}
},
"to": {
"description": "To end time in epoch timestamps in milliseconds or relative using Grafana time units.",
"type": "string"
}
},
"additionalProperties": false,
"$schema": "https://json-schema.org/draft-04/schema#"
}
@@ -0,0 +1,325 @@
{
"kind": "QueryTypeDefinitionList",
"apiVersion": "query.grafana.app/v0alpha1",
"metadata": {
"resourceVersion": "1709261615323"
},
"items": [
{
"metadata": {
"name": "default",
"resourceVersion": "1711119846950",
"creationTimestamp": "2024-03-01T02:53:35Z"
},
"spec": {
"schema": {
"$schema": "https://json-schema.org/draft-04/schema",
"additionalProperties": false,
"description": "TestDataQuery defines model for TestDataQuery.",
"properties": {
"alias": {
"type": "string"
},
"channel": {
"description": "Used for live query",
"type": "string"
},
"csvContent": {
"type": "string"
},
"csvFileName": {
"type": "string"
},
"csvWave": {
"items": {
"additionalProperties": false,
"description": "CSVWave defines model for CSVWave.",
"properties": {
"labels": {
"type": "string"
},
"name": {
"type": "string"
},
"timeStep": {
"type": "integer"
},
"valuesCSV": {
"type": "string"
}
},
"type": "object"
},
"type": "array"
},
"dropPercent": {
"description": "Drop percentage (the chance we will lose a point 0-100)",
"type": "number"
},
"errorType": {
"description": "Possible enum values:\n - `\"frontend_exception\"` \n - `\"frontend_observable\"` \n - `\"server_panic\"` ",
"enum": [
"frontend_exception",
"frontend_observable",
"server_panic"
],
"type": "string",
"x-enum-description": {}
},
"flamegraphDiff": {
"type": "boolean"
},
"labels": {
"type": "string"
},
"levelColumn": {
"type": "boolean"
},
"lines": {
"type": "integer"
},
"max": {
"type": "number"
},
"min": {
"type": "number"
},
"nodes": {
"additionalProperties": false,
"properties": {
"count": {
"type": "integer"
},
"seed": {
"type": "integer"
},
"type": {
"description": "Possible enum values:\n - `\"random\"` \n - `\"random edges\"` \n - `\"response_medium\"` \n - `\"response_small\"` \n - `\"feature_showcase\"` ",
"enum": [
"random",
"random edges",
"response_medium",
"response_small",
"feature_showcase"
],
"type": "string",
"x-enum-description": {}
}
},
"type": "object"
},
"noise": {
"type": "number"
},
"points": {
"items": {
"type": "array"
},
"type": "array"
},
"pulseWave": {
"additionalProperties": false,
"properties": {
"offCount": {
"type": "integer"
},
"offValue": {
"type": "number"
},
"onCount": {
"type": "integer"
},
"onValue": {
"type": "number"
},
"timeStep": {
"type": "integer"
}
},
"type": "object"
},
"rawFrameContent": {
"type": "string"
},
"scenarioId": {
"description": "Possible enum values:\n - `\"annotations\"` \n - `\"arrow\"` \n - `\"csv_content\"` \n - `\"csv_file\"` \n - `\"csv_metric_values\"` \n - `\"datapoints_outside_range\"` \n - `\"exponential_heatmap_bucket_data\"` \n - `\"flame_graph\"` \n - `\"grafana_api\"` \n - `\"linear_heatmap_bucket_data\"` \n - `\"live\"` \n - `\"logs\"` \n - `\"manual_entry\"` \n - `\"no_data_points\"` \n - `\"node_graph\"` \n - `\"predictable_csv_wave\"` \n - `\"predictable_pulse\"` \n - `\"random_walk\"` \n - `\"random_walk_table\"` \n - `\"random_walk_with_error\"` \n - `\"raw_frame\"` \n - `\"server_error_500\"` \n - `\"simulation\"` \n - `\"slow_query\"` \n - `\"streaming_client\"` \n - `\"table_static\"` \n - `\"trace\"` \n - `\"usa\"` \n - `\"variables-query\"` ",
"enum": [
"annotations",
"arrow",
"csv_content",
"csv_file",
"csv_metric_values",
"datapoints_outside_range",
"exponential_heatmap_bucket_data",
"flame_graph",
"grafana_api",
"linear_heatmap_bucket_data",
"live",
"logs",
"manual_entry",
"no_data_points",
"node_graph",
"predictable_csv_wave",
"predictable_pulse",
"random_walk",
"random_walk_table",
"random_walk_with_error",
"raw_frame",
"server_error_500",
"simulation",
"slow_query",
"streaming_client",
"table_static",
"trace",
"usa",
"variables-query"
],
"type": "string",
"x-enum-description": {}
},
"seriesCount": {
"type": "integer"
},
"sim": {
"additionalProperties": false,
"properties": {
"config": {
"type": "object"
},
"key": {
"additionalProperties": false,
"properties": {
"tick": {
"type": "number"
},
"type": {
"type": "string"
},
"uid": {
"type": "string"
}
},
"required": [
"tick",
"type"
],
"type": "object"
},
"last": {
"type": "boolean"
},
"stream": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object"
},
"spanCount": {
"type": "integer"
},
"spread": {
"type": "number"
},
"startValue": {
"type": "number"
},
"stream": {
"additionalProperties": false,
"properties": {
"bands": {
"type": "integer"
},
"noise": {
"type": "number"
},
"speed": {
"type": "number"
},
"spread": {
"type": "number"
},
"type": {
"description": "Possible enum values:\n - `\"fetch\"` \n - `\"logs\"` \n - `\"signal\"` \n - `\"traces\"` ",
"enum": [
"fetch",
"logs",
"signal",
"traces"
],
"type": "string",
"x-enum-description": {}
},
"url": {
"type": "string"
}
},
"required": [
"noise",
"speed",
"spread",
"type"
],
"type": "object"
},
"stringInput": {
"description": "common parameter used by many query types",
"type": "string"
},
"usa": {
"additionalProperties": false,
"properties": {
"fields": {
"items": {
"type": "string"
},
"type": "array"
},
"mode": {
"type": "string"
},
"period": {
"type": "string"
},
"states": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"withNil": {
"type": "boolean"
}
},
"type": "object"
},
"examples": [
{
"name": "simple random walk",
"saveModel": {
"scenarioId": "random_walk"
}
},
{
"name": "pulse wave example",
"saveModel": {
"pulseWave": {
"offCount": 20,
"offValue": 1.23,
"onCount": 10,
"onValue": 4.56,
"timeStep": 1000
},
"scenarioId": "predictable_pulse"
}
}
]
}
}
]
}
@@ -0,0 +1,62 @@
package kinds
import (
"reflect"
"testing"
data "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1"
"github.com/grafana/grafana-plugin-sdk-go/experimental/schemabuilder"
"github.com/stretchr/testify/require"
)
func TestQueryTypeDefinitions(t *testing.T) {
builder, err := schemabuilder.NewSchemaBuilder(
schemabuilder.BuilderOptions{
PluginID: []string{"grafana-testdata-datasource", "testdata"},
ScanCode: []schemabuilder.CodePaths{{
BasePackage: "github.com/grafana/grafana/pkg/tsdb/grafana-testdata-datasource/kinds",
CodePath: "./",
}},
Enums: []reflect.Type{
reflect.TypeOf(NodesQueryTypeRandom), // pick an example value (not the root)
reflect.TypeOf(StreamingQueryTypeFetch), // pick an example value (not the root)
reflect.TypeOf(ErrorTypeServerPanic), // pick an example value (not the root)
reflect.TypeOf(TestDataQueryTypeAnnotations), // pick an example value (not the root)
},
})
require.NoError(t, err)
err = builder.AddQueries(
schemabuilder.QueryTypeInfo{
Name: "default",
GoType: reflect.TypeOf(&TestDataQuery{}),
Examples: []data.QueryExample{
{
Name: "simple random walk",
SaveModel: data.AsUnstructured(
TestDataQuery{
ScenarioId: TestDataQueryTypeRandomWalk,
},
),
},
{
Name: "pulse wave example",
SaveModel: data.AsUnstructured(
TestDataQuery{
ScenarioId: TestDataQueryTypePredictablePulse,
PulseWave: &PulseWaveQuery{
TimeStep: int64(1000),
OnCount: 10,
OffCount: 20,
OffValue: 1.23, // should be any (rather json any)
OnValue: 4.56, // should be any
},
},
),
},
},
},
)
require.NoError(t, err)
builder.UpdateQueryDefinition(t, "./")
}