mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge remote-tracking branch 'upstream/master' into postgres-query-builder
This commit is contained in:
commit
8392fe5cd2
@ -15,6 +15,9 @@
|
||||
* **Units**: Second to HH:mm:ss formatter [#11107](https://github.com/grafana/grafana/issues/11107), thx [@gladdiologist](https://github.com/gladdiologist)
|
||||
* **Singlestat**: Add color to prefix and postfix in singlestat panel [#11143](https://github.com/grafana/grafana/pull/11143), thx [@ApsOps](https://github.com/ApsOps)
|
||||
|
||||
# 5.0.3 (2018-03-16)
|
||||
* **Mysql**: Mysql panic occurring occasionally upon Grafana dashboard access (a bigger patch than the one in 5.0.2) [#11155](https://github.com/grafana/grafana/issues/11155)
|
||||
|
||||
# 5.0.2 (2018-03-14)
|
||||
* **Mysql**: Mysql panic occurring occasionally upon Grafana dashboard access [#11155](https://github.com/grafana/grafana/issues/11155)
|
||||
* **Dashboards**: Should be possible to browse dashboard using only uid [#11231](https://github.com/grafana/grafana/issues/11231)
|
||||
|
@ -28,4 +28,4 @@
|
||||
build: blocks/prometheus_random_data
|
||||
network_mode: host
|
||||
ports:
|
||||
- "8080:8080"
|
||||
- "8081:8080"
|
||||
|
@ -36,4 +36,4 @@ scrape_configs:
|
||||
|
||||
- job_name: 'prometheus-random-data'
|
||||
static_configs:
|
||||
- targets: ['127.0.0.1:8080']
|
||||
- targets: ['127.0.0.1:8081']
|
||||
|
@ -28,4 +28,4 @@
|
||||
build: blocks/prometheus_random_data
|
||||
network_mode: host
|
||||
ports:
|
||||
- "8080:8080"
|
||||
- "8081:8080"
|
||||
|
@ -36,4 +36,4 @@ scrape_configs:
|
||||
|
||||
- job_name: 'prometheus-random-data'
|
||||
static_configs:
|
||||
- targets: ['127.0.0.1:8080']
|
||||
- targets: ['127.0.0.1:8081']
|
||||
|
@ -15,7 +15,7 @@ weight = 1
|
||||
|
||||
Description | Download
|
||||
------------ | -------------
|
||||
Stable for Debian-based Linux | [grafana_5.0.2_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.2_amd64.deb)
|
||||
Stable for Debian-based Linux | [grafana_5.0.3_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.3_amd64.deb)
|
||||
|
||||
Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing
|
||||
installation.
|
||||
@ -24,9 +24,9 @@ installation.
|
||||
|
||||
|
||||
```bash
|
||||
wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.2_amd64.deb
|
||||
wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.3_amd64.deb
|
||||
sudo apt-get install -y adduser libfontconfig
|
||||
sudo dpkg -i grafana_5.0.2_amd64.deb
|
||||
sudo dpkg -i grafana_5.0.3_amd64.deb
|
||||
```
|
||||
|
||||
## APT Repository
|
||||
|
@ -15,7 +15,7 @@ weight = 2
|
||||
|
||||
Description | Download
|
||||
------------ | -------------
|
||||
Stable for CentOS / Fedora / OpenSuse / Redhat Linux | [5.0.2 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.2-1.x86_64.rpm)
|
||||
Stable for CentOS / Fedora / OpenSuse / Redhat Linux | [5.0.3 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.3-1.x86_64.rpm)
|
||||
|
||||
|
||||
Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing
|
||||
@ -26,7 +26,7 @@ installation.
|
||||
You can install Grafana using Yum directly.
|
||||
|
||||
```bash
|
||||
$ sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.2-1.x86_64.rpm
|
||||
$ sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.3-1.x86_64.rpm
|
||||
```
|
||||
|
||||
Or install manually using `rpm`.
|
||||
@ -34,15 +34,15 @@ Or install manually using `rpm`.
|
||||
#### On CentOS / Fedora / Redhat:
|
||||
|
||||
```bash
|
||||
$ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.2-1.x86_64.rpm
|
||||
$ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.3-1.x86_64.rpm
|
||||
$ sudo yum install initscripts fontconfig
|
||||
$ sudo rpm -Uvh grafana-5.0.2-1.x86_64.rpm
|
||||
$ sudo rpm -Uvh grafana-5.0.3-1.x86_64.rpm
|
||||
```
|
||||
|
||||
#### On OpenSuse:
|
||||
|
||||
```bash
|
||||
$ sudo rpm -i --nodeps grafana-5.0.2-1.x86_64.rpm
|
||||
$ sudo rpm -i --nodeps grafana-5.0.3-1.x86_64.rpm
|
||||
```
|
||||
|
||||
## Install via YUM Repository
|
||||
|
@ -13,7 +13,7 @@ weight = 3
|
||||
|
||||
Description | Download
|
||||
------------ | -------------
|
||||
Latest stable package for Windows | [grafana-5.0.2.windows-x64.zip](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.2.windows-x64.zip)
|
||||
Latest stable package for Windows | [grafana-5.0.3.windows-x64.zip](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.3.windows-x64.zip)
|
||||
|
||||
Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing
|
||||
installation.
|
||||
|
@ -46,25 +46,49 @@ type AlertmanagerNotifier struct {
|
||||
}
|
||||
|
||||
func (this *AlertmanagerNotifier) ShouldNotify(evalContext *alerting.EvalContext) bool {
|
||||
this.log.Debug("Should notify", "ruleId", evalContext.Rule.Id, "state", evalContext.Rule.State, "previousState", evalContext.PrevAlertState)
|
||||
|
||||
// Do not notify when we become OK for the first time.
|
||||
if (evalContext.PrevAlertState == m.AlertStatePending) && (evalContext.Rule.State == m.AlertStateOK) {
|
||||
return false
|
||||
}
|
||||
// Notify on Alerting -> OK to resolve before alertmanager timeout.
|
||||
if (evalContext.PrevAlertState == m.AlertStateAlerting) && (evalContext.Rule.State == m.AlertStateOK) {
|
||||
return true
|
||||
}
|
||||
return evalContext.Rule.State == m.AlertStateAlerting
|
||||
}
|
||||
|
||||
func (this *AlertmanagerNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
func (this *AlertmanagerNotifier) createAlert(evalContext *alerting.EvalContext, match *alerting.EvalMatch, ruleUrl string) *simplejson.Json {
|
||||
alertJSON := simplejson.New()
|
||||
alertJSON.Set("startsAt", evalContext.StartTime.UTC().Format(time.RFC3339))
|
||||
if evalContext.Rule.State == m.AlertStateOK {
|
||||
alertJSON.Set("endsAt", time.Now().UTC().Format(time.RFC3339))
|
||||
}
|
||||
alertJSON.Set("generatorURL", ruleUrl)
|
||||
|
||||
alerts := make([]interface{}, 0)
|
||||
for _, match := range evalContext.EvalMatches {
|
||||
alertJSON := simplejson.New()
|
||||
alertJSON.Set("startsAt", evalContext.StartTime.UTC().Format(time.RFC3339))
|
||||
|
||||
if ruleUrl, err := evalContext.GetRuleUrl(); err == nil {
|
||||
alertJSON.Set("generatorURL", ruleUrl)
|
||||
// Annotations (summary and description are very commonly used).
|
||||
alertJSON.SetPath([]string{"annotations", "summary"}, evalContext.Rule.Name)
|
||||
description := ""
|
||||
if evalContext.Rule.Message != "" {
|
||||
description += evalContext.Rule.Message
|
||||
}
|
||||
if evalContext.Error != nil {
|
||||
if description != "" {
|
||||
description += "\n"
|
||||
}
|
||||
description += "Error: " + evalContext.Error.Error()
|
||||
}
|
||||
if description != "" {
|
||||
alertJSON.SetPath([]string{"annotations", "description"}, description)
|
||||
}
|
||||
if evalContext.ImagePublicUrl != "" {
|
||||
alertJSON.SetPath([]string{"annotations", "image"}, evalContext.ImagePublicUrl)
|
||||
}
|
||||
|
||||
if evalContext.Rule.Message != "" {
|
||||
alertJSON.SetPath([]string{"annotations", "description"}, evalContext.Rule.Message)
|
||||
}
|
||||
|
||||
tags := make(map[string]string)
|
||||
// Labels (from metrics tags + mandatory alertname).
|
||||
tags := make(map[string]string)
|
||||
if match != nil {
|
||||
if len(match.Tags) == 0 {
|
||||
tags["metric"] = match.Metric
|
||||
} else {
|
||||
@ -72,10 +96,32 @@ func (this *AlertmanagerNotifier) Notify(evalContext *alerting.EvalContext) erro
|
||||
tags[k] = v
|
||||
}
|
||||
}
|
||||
tags["alertname"] = evalContext.Rule.Name
|
||||
alertJSON.Set("labels", tags)
|
||||
}
|
||||
tags["alertname"] = evalContext.Rule.Name
|
||||
alertJSON.Set("labels", tags)
|
||||
return alertJSON
|
||||
}
|
||||
|
||||
alerts = append(alerts, alertJSON)
|
||||
func (this *AlertmanagerNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
this.log.Info("Sending Alertmanager alert", "ruleId", evalContext.Rule.Id, "notification", this.Name)
|
||||
|
||||
ruleUrl, err := evalContext.GetRuleUrl()
|
||||
if err != nil {
|
||||
this.log.Error("Failed get rule link", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Send one alert per matching series.
|
||||
alerts := make([]interface{}, 0)
|
||||
for _, match := range evalContext.EvalMatches {
|
||||
alert := this.createAlert(evalContext, match, ruleUrl)
|
||||
alerts = append(alerts, alert)
|
||||
}
|
||||
|
||||
// This happens on ExecutionError or NoData
|
||||
if len(alerts) == 0 {
|
||||
alert := this.createAlert(evalContext, nil, ruleUrl)
|
||||
alerts = append(alerts, alert)
|
||||
}
|
||||
|
||||
bodyJSON := simplejson.NewFromAny(alerts)
|
||||
|
@ -27,15 +27,21 @@ func NewNotifierBase(id int64, isDefault bool, name, notifierType string, model
|
||||
}
|
||||
|
||||
func defaultShouldNotify(context *alerting.EvalContext) bool {
|
||||
// Only notify on state change.
|
||||
if context.PrevAlertState == context.Rule.State {
|
||||
return false
|
||||
}
|
||||
// Do not notify when we become OK for the first time.
|
||||
if (context.PrevAlertState == m.AlertStatePending) && (context.Rule.State == m.AlertStateOK) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (n *NotifierBase) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (n *NotifierBase) GetType() string {
|
||||
return n.Type
|
||||
}
|
||||
|
@ -38,10 +38,6 @@ func NewDingDingNotifier(model *m.AlertNotification) (alerting.Notifier, error)
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (this *DingDingNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
type DingDingNotifier struct {
|
||||
NotifierBase
|
||||
Url string
|
||||
|
@ -58,10 +58,6 @@ func NewEmailNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (this *EmailNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (this *EmailNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
this.log.Info("Sending alert notification to", "addresses", this.Addresses)
|
||||
|
||||
|
@ -75,10 +75,6 @@ type HipChatNotifier struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func (this *HipChatNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (this *HipChatNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
this.log.Info("Executing hipchat notification", "ruleId", evalContext.Rule.Id, "notification", this.Name)
|
||||
|
||||
|
@ -57,10 +57,6 @@ type KafkaNotifier struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func (this *KafkaNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (this *KafkaNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
|
||||
state := evalContext.Rule.State
|
||||
|
@ -51,10 +51,6 @@ type LineNotifier struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func (this *LineNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (this *LineNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
this.log.Info("Executing line notification", "ruleId", evalContext.Rule.Id, "notification", this.Name)
|
||||
|
||||
|
@ -72,10 +72,6 @@ type OpsGenieNotifier struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func (this *OpsGenieNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (this *OpsGenieNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
|
||||
var err error
|
||||
|
@ -65,10 +65,6 @@ type PagerdutyNotifier struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func (this *PagerdutyNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (this *PagerdutyNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
|
||||
if evalContext.Rule.State == m.AlertStateOK && !this.AutoResolve {
|
||||
|
@ -123,10 +123,6 @@ type PushoverNotifier struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func (this *PushoverNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (this *PushoverNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
ruleUrl, err := evalContext.GetRuleUrl()
|
||||
if err != nil {
|
||||
|
@ -71,10 +71,6 @@ type SensuNotifier struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func (this *SensuNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (this *SensuNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
this.log.Info("Sending sensu result")
|
||||
|
||||
|
@ -98,10 +98,6 @@ type SlackNotifier struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func (this *SlackNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (this *SlackNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
this.log.Info("Executing slack notification", "ruleId", evalContext.Rule.Id, "notification", this.Name)
|
||||
|
||||
|
@ -47,10 +47,6 @@ type TeamsNotifier struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func (this *TeamsNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (this *TeamsNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
this.log.Info("Executing teams notification", "ruleId", evalContext.Rule.Id, "notification", this.Name)
|
||||
|
||||
|
@ -208,6 +208,7 @@ func generateImageCaption(evalContext *alerting.EvalContext, ruleUrl string, met
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
func appendIfPossible(message string, extra string, sizeLimit int) string {
|
||||
if len(extra)+len(message) <= sizeLimit {
|
||||
return message + extra
|
||||
@ -216,10 +217,6 @@ func appendIfPossible(message string, extra string, sizeLimit int) string {
|
||||
return message
|
||||
}
|
||||
|
||||
func (this *TelegramNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (this *TelegramNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
var cmd *m.SendWebhookSync
|
||||
if evalContext.ImagePublicUrl == "" && this.UploadImage == true {
|
||||
|
@ -114,10 +114,6 @@ func NewThreemaNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (this *ThreemaNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (notifier *ThreemaNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
notifier.log.Info("Sending alert notification from", "threema_id", notifier.GatewayID)
|
||||
notifier.log.Info("Sending alert notification to", "threema_id", notifier.RecipientID)
|
||||
|
@ -68,10 +68,6 @@ type VictoropsNotifier struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func (this *VictoropsNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
// Notify sends notification to Victorops via POST to URL endpoint
|
||||
func (this *VictoropsNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
this.log.Info("Executing victorops notification", "ruleId", evalContext.Rule.Id, "notification", this.Name)
|
||||
|
@ -65,10 +65,6 @@ type WebhookNotifier struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func (this *WebhookNotifier) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
}
|
||||
|
||||
func (this *WebhookNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
this.log.Info("Sending webhook")
|
||||
|
||||
|
@ -5,32 +5,46 @@ export class PromCompleter {
|
||||
labelQueryCache: any;
|
||||
labelNameCache: any;
|
||||
labelValueCache: any;
|
||||
templateVariableCompletions: any;
|
||||
|
||||
identifierRegexps = [/\[/, /[a-zA-Z0-9_:]/];
|
||||
|
||||
constructor(private datasource: PrometheusDatasource) {
|
||||
constructor(private datasource: PrometheusDatasource, private templateSrv) {
|
||||
this.labelQueryCache = {};
|
||||
this.labelNameCache = {};
|
||||
this.labelValueCache = {};
|
||||
this.templateVariableCompletions = this.templateSrv.variables.map(variable => {
|
||||
return {
|
||||
caption: '$' + variable.name,
|
||||
value: '$' + variable.name,
|
||||
meta: 'variable',
|
||||
score: Number.MAX_VALUE,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getCompletions(editor, session, pos, prefix, callback) {
|
||||
let wrappedCallback = (err, completions) => {
|
||||
completions = completions.concat(this.templateVariableCompletions);
|
||||
return callback(err, completions);
|
||||
};
|
||||
|
||||
let token = session.getTokenAt(pos.row, pos.column);
|
||||
|
||||
switch (token.type) {
|
||||
case 'entity.name.tag.label-matcher':
|
||||
this.getCompletionsForLabelMatcherName(session, pos).then(completions => {
|
||||
callback(null, completions);
|
||||
wrappedCallback(null, completions);
|
||||
});
|
||||
return;
|
||||
case 'string.quoted.label-matcher':
|
||||
this.getCompletionsForLabelMatcherValue(session, pos).then(completions => {
|
||||
callback(null, completions);
|
||||
wrappedCallback(null, completions);
|
||||
});
|
||||
return;
|
||||
case 'entity.name.tag.label-list-matcher':
|
||||
this.getCompletionsForBinaryOperator(session, pos).then(completions => {
|
||||
callback(null, completions);
|
||||
wrappedCallback(null, completions);
|
||||
});
|
||||
return;
|
||||
}
|
||||
@ -59,14 +73,14 @@ export class PromCompleter {
|
||||
meta: 'range vector',
|
||||
});
|
||||
|
||||
callback(null, vectors);
|
||||
wrappedCallback(null, vectors);
|
||||
return;
|
||||
}
|
||||
|
||||
var query = prefix;
|
||||
|
||||
return this.datasource.performSuggestQuery(query, true).then(metricNames => {
|
||||
callback(
|
||||
wrappedCallback(
|
||||
null,
|
||||
metricNames.map(name => {
|
||||
let value = name;
|
||||
|
@ -50,6 +50,9 @@ var PrometheusHighlightRules = function() {
|
||||
token : "keyword.control",
|
||||
regex : "by|without|on|ignoring|group_left|group_right",
|
||||
next : "start-label-list-matcher"
|
||||
}, {
|
||||
token : "variable",
|
||||
regex : "\\$[A-Za-z0-9_]+"
|
||||
}, {
|
||||
token : keywordMapper,
|
||||
regex : "[a-zA-Z_:][a-zA-Z0-9_:]*"
|
||||
|
@ -43,7 +43,7 @@ class PrometheusQueryCtrl extends QueryCtrl {
|
||||
}
|
||||
|
||||
getCompleter(query) {
|
||||
return new PromCompleter(this.datasource);
|
||||
return new PromCompleter(this.datasource, this.templateSrv);
|
||||
}
|
||||
|
||||
getDefaultFormat() {
|
||||
|
@ -1,9 +1,13 @@
|
||||
import { describe, it, sinon, expect } from 'test/lib/common';
|
||||
import helpers from 'test/specs/helpers';
|
||||
|
||||
import { PromCompleter } from '../completer';
|
||||
import { PrometheusDatasource } from '../datasource';
|
||||
|
||||
describe('Prometheus editor completer', function() {
|
||||
var ctx = new helpers.ServiceTestContext();
|
||||
beforeEach(ctx.providePhase(['templateSrv']));
|
||||
|
||||
function getSessionStub(data) {
|
||||
return {
|
||||
getTokenAt: sinon.stub().returns(data.currentToken),
|
||||
@ -39,7 +43,18 @@ describe('Prometheus editor completer', function() {
|
||||
.returns(Promise.resolve(['node_cpu'])),
|
||||
};
|
||||
|
||||
let completer = new PromCompleter(datasourceStub);
|
||||
let templateSrv = {
|
||||
variables: [
|
||||
{
|
||||
name: 'var_name',
|
||||
options: [
|
||||
{ text: 'foo', value: 'foo', selected: false },
|
||||
{ text: 'bar', value: 'bar', selected: true }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
let completer = new PromCompleter(datasourceStub, templateSrv);
|
||||
|
||||
describe('When inside brackets', () => {
|
||||
it('Should return range vectors', () => {
|
||||
|
Loading…
Reference in New Issue
Block a user