{
  "__inputs": [
    {
      "name": "DS_RESIM",
      "label": "SignalFlag datasource",
      "description": "An Infinity datasource with a SignalFlag bearer token and https://api.resim.ai, https://bff.resim.ai as allowed hosts.",
      "type": "datasource",
      "pluginId": "yesoreyeram-infinity-datasource",
      "pluginName": "Infinity"
    }
  ],
  "__requires": [
    {
      "type": "datasource",
      "id": "yesoreyeram-infinity-datasource",
      "name": "Infinity",
      "version": "2.0.0"
    }
  ],
  "uid": "resim-test-throughput",
  "title": "SignalFlag: test throughput",
  "description": "Weekly hours under test, early-ending tests and event rates normalised by test time, read from the SignalFlag data lake through the SignalFlag query API (/api/v1/query). Replace my_events and category in the last panel with your own topic and column.",
  "tags": [
    "resim",
    "template"
  ],
  "editable": true,
  "schemaVersion": 39,
  "timezone": "browser",
  "time": {
    "from": "now-90d",
    "to": "now"
  },
  "refresh": "",
  "templating": {
    "list": [
      {
        "hide": 2,
        "name": "api_url",
        "query": "https://api.resim.ai",
        "type": "constant"
      },
      {
        "hide": 2,
        "name": "bff_url",
        "query": "https://bff.resim.ai",
        "type": "constant"
      },
      {
        "datasource": {
          "type": "yesoreyeram-infinity-datasource",
          "uid": "${DS_RESIM}"
        },
        "label": "Project",
        "name": "project",
        "query": {
          "infinityQuery": {
            "columns": [
              {
                "selector": "name",
                "text": "__text",
                "type": "string"
              },
              {
                "selector": "projectID",
                "text": "__value",
                "type": "string"
              }
            ],
            "format": "table",
            "pagination_max_pages": 20,
            "pagination_mode": "cursor",
            "pagination_param_cursor_extraction_path": "nextPageToken",
            "pagination_param_cursor_field_name": "pageToken",
            "parser": "backend",
            "refId": "variable",
            "root_selector": "projects",
            "source": "url",
            "type": "json",
            "url": "${api_url}/v1/projects",
            "url_options": {
              "method": "GET",
              "params": [
                {
                  "key": "pageSize",
                  "value": "100"
                }
              ]
            }
          },
          "queryType": "infinity",
          "refId": "variable"
        },
        "refresh": 1,
        "sort": 1,
        "type": "query"
      },
      {
        "datasource": {
          "type": "yesoreyeram-infinity-datasource",
          "uid": "${DS_RESIM}"
        },
        "label": "Branch",
        "name": "branch",
        "query": {
          "infinityQuery": {
            "columns": [
              {
                "selector": "name",
                "text": "__text",
                "type": "string"
              },
              {
                "selector": "branchID",
                "text": "__value",
                "type": "string"
              }
            ],
            "format": "table",
            "pagination_max_pages": 20,
            "pagination_mode": "cursor",
            "pagination_param_cursor_extraction_path": "nextPageToken",
            "pagination_param_cursor_field_name": "pageToken",
            "parser": "backend",
            "refId": "variable",
            "root_selector": "branches",
            "source": "url",
            "type": "json",
            "url": "${api_url}/v1/projects/${project}/branches",
            "url_options": {
              "method": "GET",
              "params": [
                {
                  "key": "pageSize",
                  "value": "100"
                }
              ]
            }
          },
          "queryType": "infinity",
          "refId": "variable"
        },
        "refresh": 1,
        "sort": 1,
        "type": "query"
      }
    ]
  },
  "panels": [
    {
      "id": 1,
      "type": "timeseries",
      "title": "Hours under test",
      "description": "Total test runtime per week, from the built-in test_length_seconds topic.",
      "datasource": {
        "type": "yesoreyeram-infinity-datasource",
        "uid": "${DS_RESIM}"
      },
      "gridPos": {
        "h": 8,
        "w": 12,
        "x": 0,
        "y": 0
      },
      "fieldConfig": {
        "defaults": {
          "unit": "short",
          "displayName": "${__field.labels.Series}",
          "custom": {
            "drawStyle": "line",
            "lineWidth": 2,
            "pointSize": 5,
            "showPoints": "always",
            "spanNulls": true
          },
          "min": 0
        },
        "overrides": []
      },
      "options": {
        "legend": {
          "displayMode": "list",
          "placement": "bottom",
          "showLegend": true
        },
        "tooltip": {
          "mode": "multi",
          "sort": "desc"
        }
      },
      "targets": [
        {
          "refId": "A",
          "datasource": {
            "type": "yesoreyeram-infinity-datasource",
            "uid": "${DS_RESIM}"
          },
          "type": "json",
          "source": "url",
          "parser": "backend",
          "format": "table",
          "url": "${bff_url}/api/v1/query",
          "url_options": {
            "method": "POST",
            "body_type": "raw",
            "body_content_type": "application/json",
            "data": "{\"projectId\": \"${project}\", \"branchId\": \"${branch}\", \"sql\": \"SELECT 'Hours under test' AS series, CAST(to_unixtime(date_trunc('week', m.time)) * 1000 AS BIGINT) AS t, round(sum(tl.test_length) / 3600.0, 2) AS v FROM test_length_seconds tl JOIN metadata m ON m.job_id = tl.job_id WHERE m.time >= TIMESTAMP '${__from:date:YYYY-MM-DD HH:mm:ss}' AND m.time < TIMESTAMP '${__to:date:YYYY-MM-DD HH:mm:ss}' GROUP BY 2 ORDER BY 2\", \"limit\": 5000}"
          },
          "root_selector": "records",
          "columns": [
            {
              "selector": "series",
              "text": "Series",
              "type": "string"
            },
            {
              "selector": "t",
              "text": "Time",
              "type": "timestamp_epoch"
            },
            {
              "selector": "v",
              "text": "Hours",
              "type": "number"
            }
          ]
        }
      ],
      "transformations": [
        {
          "id": "partitionByValues",
          "options": {
            "fields": [
              "Series"
            ],
            "keepFields": false
          }
        }
      ]
    },
    {
      "id": 2,
      "type": "timeseries",
      "title": "Share of tests ending early",
      "description": "Percentage of tests per week that ran for less than 5 minutes. A rise usually means the system stopped before the scenario finished.",
      "datasource": {
        "type": "yesoreyeram-infinity-datasource",
        "uid": "${DS_RESIM}"
      },
      "gridPos": {
        "h": 8,
        "w": 12,
        "x": 12,
        "y": 0
      },
      "fieldConfig": {
        "defaults": {
          "unit": "percent",
          "displayName": "${__field.labels.Series}",
          "custom": {
            "drawStyle": "line",
            "lineWidth": 2,
            "pointSize": 5,
            "showPoints": "always",
            "spanNulls": true
          },
          "min": 0,
          "max": 100
        },
        "overrides": []
      },
      "options": {
        "legend": {
          "displayMode": "list",
          "placement": "bottom",
          "showLegend": true
        },
        "tooltip": {
          "mode": "multi",
          "sort": "desc"
        }
      },
      "targets": [
        {
          "refId": "A",
          "datasource": {
            "type": "yesoreyeram-infinity-datasource",
            "uid": "${DS_RESIM}"
          },
          "type": "json",
          "source": "url",
          "parser": "backend",
          "format": "table",
          "url": "${bff_url}/api/v1/query",
          "url_options": {
            "method": "POST",
            "body_type": "raw",
            "body_content_type": "application/json",
            "data": "{\"projectId\": \"${project}\", \"branchId\": \"${branch}\", \"sql\": \"SELECT 'Under 5 min' AS series, CAST(to_unixtime(date_trunc('week', m.time)) * 1000 AS BIGINT) AS t, round(100.0 * count_if(tl.test_length < 300) / count(*), 1) AS v FROM test_length_seconds tl JOIN metadata m ON m.job_id = tl.job_id WHERE m.time >= TIMESTAMP '${__from:date:YYYY-MM-DD HH:mm:ss}' AND m.time < TIMESTAMP '${__to:date:YYYY-MM-DD HH:mm:ss}' GROUP BY 2 ORDER BY 2\", \"limit\": 5000}"
          },
          "root_selector": "records",
          "columns": [
            {
              "selector": "series",
              "text": "Series",
              "type": "string"
            },
            {
              "selector": "t",
              "text": "Time",
              "type": "timestamp_epoch"
            },
            {
              "selector": "v",
              "text": "Short tests (%)",
              "type": "number"
            }
          ]
        }
      ],
      "transformations": [
        {
          "id": "partitionByValues",
          "options": {
            "fields": [
              "Series"
            ],
            "keepFields": false
          }
        }
      ]
    },
    {
      "id": 3,
      "type": "timeseries",
      "title": "Events per hour by category",
      "description": "Weekly count of my_events rows per category, divided by the hours under test that week. Replace my_events and category with your own topic and column.",
      "datasource": {
        "type": "yesoreyeram-infinity-datasource",
        "uid": "${DS_RESIM}"
      },
      "gridPos": {
        "h": 8,
        "w": 24,
        "x": 0,
        "y": 8
      },
      "fieldConfig": {
        "defaults": {
          "unit": "short",
          "displayName": "${__field.labels.Series}",
          "custom": {
            "drawStyle": "line",
            "lineWidth": 2,
            "pointSize": 5,
            "showPoints": "always",
            "spanNulls": true
          },
          "min": 0
        },
        "overrides": []
      },
      "options": {
        "legend": {
          "displayMode": "list",
          "placement": "bottom",
          "showLegend": true
        },
        "tooltip": {
          "mode": "multi",
          "sort": "desc"
        }
      },
      "targets": [
        {
          "refId": "A",
          "datasource": {
            "type": "yesoreyeram-infinity-datasource",
            "uid": "${DS_RESIM}"
          },
          "type": "json",
          "source": "url",
          "parser": "backend",
          "format": "table",
          "url": "${bff_url}/api/v1/query",
          "url_options": {
            "method": "POST",
            "body_type": "raw",
            "body_content_type": "application/json",
            "data": "{\"projectId\": \"${project}\", \"branchId\": \"${branch}\", \"sql\": \"WITH hours AS ( SELECT date_trunc('week', m.time) AS week, sum(tl.test_length) / 3600.0 AS hours FROM test_length_seconds tl JOIN metadata m ON m.job_id = tl.job_id WHERE m.time >= TIMESTAMP '${__from:date:YYYY-MM-DD HH:mm:ss}' AND m.time < TIMESTAMP '${__to:date:YYYY-MM-DD HH:mm:ss}' GROUP BY 1 ), events AS ( SELECT date_trunc('week', m.time) AS week, e.category, count(*) AS n FROM my_events e JOIN metadata m ON m.job_id = e.job_id WHERE m.time >= TIMESTAMP '${__from:date:YYYY-MM-DD HH:mm:ss}' AND m.time < TIMESTAMP '${__to:date:YYYY-MM-DD HH:mm:ss}' GROUP BY 1, 2 ) SELECT events.category AS series, CAST(to_unixtime(hours.week) * 1000 AS BIGINT) AS t, round(events.n / hours.hours, 2) AS v FROM hours JOIN events ON events.week = hours.week ORDER BY 2\", \"limit\": 5000}"
          },
          "root_selector": "records",
          "columns": [
            {
              "selector": "series",
              "text": "Series",
              "type": "string"
            },
            {
              "selector": "t",
              "text": "Time",
              "type": "timestamp_epoch"
            },
            {
              "selector": "v",
              "text": "Events / hour",
              "type": "number"
            }
          ]
        }
      ],
      "transformations": [
        {
          "id": "partitionByValues",
          "options": {
            "fields": [
              "Series"
            ],
            "keepFields": false
          }
        }
      ]
    }
  ]
}
