Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
479209f4
Commit
479209f4
authored
Mar 12, 2018
by
Alexander Zobnin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
prometheus: datasource refactor
parent
425d2cfd
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
294 additions
and
245 deletions
+294
-245
public/app/plugins/datasource/prometheus/datasource.ts
+16
-196
public/app/plugins/datasource/prometheus/result_transformer.ts
+199
-0
public/app/plugins/datasource/prometheus/specs/datasource_specs.ts
+1
-49
public/app/plugins/datasource/prometheus/specs/result_transformer.jest.ts
+78
-0
No files found.
public/app/plugins/datasource/prometheus/datasource.ts
View file @
479209f4
...
...
@@ -3,7 +3,7 @@ import _ from 'lodash';
import
kbn
from
'app/core/utils/kbn'
;
import
*
as
dateMath
from
'app/core/utils/datemath'
;
import
PrometheusMetricFindQuery
from
'./metric_find_query'
;
import
TableModel
from
'app/core/table_model
'
;
import
{
ResultTransformer
}
from
'./result_transformer
'
;
function
prometheusSpecialRegexEscape
(
value
)
{
return
value
.
replace
(
/
[\\
^$*+?.()|[
\]
{}
]
/g
,
'
\\\\
$&'
);
...
...
@@ -20,6 +20,7 @@ export class PrometheusDatasource {
withCredentials
:
any
;
metricsNameCache
:
any
;
interval
:
string
;
resultTransformer
:
ResultTransformer
;
/** @ngInject */
constructor
(
instanceSettings
,
private
$q
,
private
backendSrv
,
private
templateSrv
,
private
timeSrv
)
{
...
...
@@ -32,6 +33,7 @@ export class PrometheusDatasource {
this
.
basicAuth
=
instanceSettings
.
basicAuth
;
this
.
withCredentials
=
instanceSettings
.
withCredentials
;
this
.
interval
=
instanceSettings
.
jsonData
.
timeInterval
||
'15s'
;
this
.
resultTransformer
=
new
ResultTransformer
(
templateSrv
);
}
_request
(
method
,
url
,
requestId
?)
{
...
...
@@ -73,7 +75,6 @@ export class PrometheusDatasource {
}
query
(
options
)
{
var
self
=
this
;
var
start
=
this
.
getPrometheusTime
(
options
.
range
.
from
,
false
);
var
end
=
this
.
getPrometheusTime
(
options
.
range
.
to
,
true
);
var
range
=
Math
.
ceil
(
end
-
start
);
...
...
@@ -113,29 +114,17 @@ export class PrometheusDatasource {
throw
response
.
error
;
}
let
prometheusResult
=
response
.
data
.
data
.
result
;
if
(
activeTargets
[
index
].
format
===
'table'
)
{
result
.
push
(
self
.
transformMetricDataToTable
(
prometheusResult
,
responseList
.
length
,
index
));
}
else
if
(
activeTargets
[
index
].
format
===
'heatmap'
)
{
let
seriesList
=
[];
prometheusResult
.
sort
(
sortSeriesByLabel
);
for
(
let
metricData
of
prometheusResult
)
{
seriesList
.
push
(
self
.
transformMetricData
(
metricData
,
activeTargets
[
index
],
start
,
end
,
queries
[
index
].
step
)
);
}
seriesList
=
self
.
transformToHistogramOverTime
(
seriesList
);
result
.
push
(...
seriesList
);
}
else
{
for
(
let
metricData
of
prometheusResult
)
{
if
(
response
.
data
.
data
.
resultType
===
'matrix'
)
{
result
.
push
(
self
.
transformMetricData
(
metricData
,
activeTargets
[
index
],
start
,
end
,
queries
[
index
].
step
));
}
else
if
(
response
.
data
.
data
.
resultType
===
'vector'
)
{
result
.
push
(
self
.
transformInstantMetricData
(
metricData
,
activeTargets
[
index
]));
}
}
}
let
transformerOptions
=
{
format
:
activeTargets
[
index
].
format
,
step
:
queries
[
index
].
step
,
legendFormat
:
activeTargets
[
index
].
legendFormat
,
start
:
start
,
end
:
end
,
responseListLength
:
responseList
.
length
,
responseIndex
:
index
,
};
this
.
resultTransformer
.
transform
(
result
,
response
,
transformerOptions
);
});
return
{
data
:
result
};
...
...
@@ -276,9 +265,9 @@ export class PrometheusDatasource {
var
event
=
{
annotation
:
annotation
,
time
:
Math
.
floor
(
parseFloat
(
value
[
0
]))
*
1000
,
title
:
self
.
renderTemplate
(
titleFormat
,
series
.
metric
),
title
:
self
.
re
sultTransformer
.
re
nderTemplate
(
titleFormat
,
series
.
metric
),
tags
:
tags
,
text
:
self
.
renderTemplate
(
textFormat
,
series
.
metric
),
text
:
self
.
re
sultTransformer
.
re
nderTemplate
(
textFormat
,
series
.
metric
),
};
eventList
.
push
(
event
);
...
...
@@ -296,145 +285,6 @@ export class PrometheusDatasource {
});
}
transformMetricData
(
md
,
options
,
start
,
end
,
step
)
{
var
dps
=
[],
metricLabel
=
null
;
metricLabel
=
this
.
createMetricLabel
(
md
.
metric
,
options
);
var
stepMs
=
step
*
1000
;
var
baseTimestamp
=
start
*
1000
;
for
(
let
value
of
md
.
values
)
{
var
dp_value
=
parseFloat
(
value
[
1
]);
if
(
_
.
isNaN
(
dp_value
))
{
dp_value
=
null
;
}
var
timestamp
=
parseFloat
(
value
[
0
])
*
1000
;
for
(
let
t
=
baseTimestamp
;
t
<
timestamp
;
t
+=
stepMs
)
{
dps
.
push
([
null
,
t
]);
}
baseTimestamp
=
timestamp
+
stepMs
;
dps
.
push
([
dp_value
,
timestamp
]);
}
var
endTimestamp
=
end
*
1000
;
for
(
let
t
=
baseTimestamp
;
t
<=
endTimestamp
;
t
+=
stepMs
)
{
dps
.
push
([
null
,
t
]);
}
return
{
target
:
metricLabel
,
datapoints
:
dps
};
}
transformMetricDataToTable
(
md
,
resultCount
:
number
,
resultIndex
:
number
)
{
var
table
=
new
TableModel
();
var
i
,
j
;
var
metricLabels
=
{};
if
(
md
.
length
===
0
)
{
return
table
;
}
// Collect all labels across all metrics
_
.
each
(
md
,
function
(
series
)
{
for
(
var
label
in
series
.
metric
)
{
if
(
!
metricLabels
.
hasOwnProperty
(
label
))
{
metricLabels
[
label
]
=
1
;
}
}
});
// Sort metric labels, create columns for them and record their index
var
sortedLabels
=
_
.
keys
(
metricLabels
).
sort
();
table
.
columns
.
push
({
text
:
'Time'
,
type
:
'time'
});
_
.
each
(
sortedLabels
,
function
(
label
,
labelIndex
)
{
metricLabels
[
label
]
=
labelIndex
+
1
;
table
.
columns
.
push
({
text
:
label
});
});
let
valueText
=
resultCount
>
1
?
`Value #
${
String
.
fromCharCode
(
65
+
resultIndex
)}
`
:
'Value'
;
table
.
columns
.
push
({
text
:
valueText
});
// Populate rows, set value to empty string when label not present.
_
.
each
(
md
,
function
(
series
)
{
if
(
series
.
value
)
{
series
.
values
=
[
series
.
value
];
}
if
(
series
.
values
)
{
for
(
i
=
0
;
i
<
series
.
values
.
length
;
i
++
)
{
var
values
=
series
.
values
[
i
];
var
reordered
:
any
=
[
values
[
0
]
*
1000
];
if
(
series
.
metric
)
{
for
(
j
=
0
;
j
<
sortedLabels
.
length
;
j
++
)
{
var
label
=
sortedLabels
[
j
];
if
(
series
.
metric
.
hasOwnProperty
(
label
))
{
reordered
.
push
(
series
.
metric
[
label
]);
}
else
{
reordered
.
push
(
''
);
}
}
}
reordered
.
push
(
parseFloat
(
values
[
1
]));
table
.
rows
.
push
(
reordered
);
}
}
});
return
table
;
}
transformInstantMetricData
(
md
,
options
)
{
var
dps
=
[],
metricLabel
=
null
;
metricLabel
=
this
.
createMetricLabel
(
md
.
metric
,
options
);
dps
.
push
([
parseFloat
(
md
.
value
[
1
]),
md
.
value
[
0
]
*
1000
]);
return
{
target
:
metricLabel
,
datapoints
:
dps
};
}
transformToHistogramOverTime
(
seriesList
,
options
?)
{
/* t1 = timestamp1, t2 = timestamp2 etc.
t1 t2 t3 t1 t2 t3
le10 10 10 0 => 10 10 0
le20 20 10 30 => 10 0 30
le30 30 10 35 => 10 0 5
*/
for
(
let
i
=
seriesList
.
length
-
1
;
i
>
0
;
i
--
)
{
let
topSeries
=
seriesList
[
i
].
datapoints
;
let
bottomSeries
=
seriesList
[
i
-
1
].
datapoints
;
for
(
let
j
=
0
;
j
<
topSeries
.
length
;
j
++
)
{
topSeries
[
j
][
0
]
-=
bottomSeries
[
j
][
0
];
}
}
return
seriesList
;
}
createMetricLabel
(
labelData
,
options
)
{
if
(
_
.
isUndefined
(
options
)
||
_
.
isEmpty
(
options
.
legendFormat
))
{
return
this
.
getOriginalMetricName
(
labelData
);
}
return
this
.
renderTemplate
(
this
.
templateSrv
.
replace
(
options
.
legendFormat
),
labelData
)
||
'{}'
;
}
renderTemplate
(
aliasPattern
,
aliasData
)
{
var
aliasRegex
=
/
\{\{\s
*
(
.+
?)\s
*
\}\}
/g
;
return
aliasPattern
.
replace
(
aliasRegex
,
function
(
match
,
g1
)
{
if
(
aliasData
[
g1
])
{
return
aliasData
[
g1
];
}
return
g1
;
});
}
getOriginalMetricName
(
labelData
)
{
var
metricName
=
labelData
.
__name__
||
''
;
delete
labelData
.
__name__
;
var
labelPart
=
_
.
map
(
_
.
toPairs
(
labelData
),
function
(
label
)
{
return
label
[
0
]
+
'="'
+
label
[
1
]
+
'"'
;
}).
join
(
','
);
return
metricName
+
'{'
+
labelPart
+
'}'
;
}
getPrometheusTime
(
date
,
roundUp
)
{
if
(
_
.
isString
(
date
))
{
date
=
dateMath
.
parse
(
date
,
roundUp
);
...
...
@@ -442,33 +292,3 @@ export class PrometheusDatasource {
return
Math
.
ceil
(
date
.
valueOf
()
/
1000
);
}
}
function
sortSeriesByLabel
(
s1
,
s2
)
{
let
le1
,
le2
;
try
{
// fail if not integer. might happen with bad queries
le1
=
parseHistogramLabel
(
s1
.
metric
.
le
);
le2
=
parseHistogramLabel
(
s2
.
metric
.
le
);
}
catch
(
err
)
{
console
.
log
(
err
);
return
0
;
}
if
(
le1
>
le2
)
{
return
1
;
}
if
(
le1
<
le2
)
{
return
-
1
;
}
return
0
;
}
function
parseHistogramLabel
(
le
:
string
):
number
{
if
(
le
===
'+Inf'
)
{
return
+
Infinity
;
}
return
Number
(
le
);
}
public/app/plugins/datasource/prometheus/result_transformer.ts
0 → 100644
View file @
479209f4
import
_
from
'lodash'
;
import
TableModel
from
'app/core/table_model'
;
export
class
ResultTransformer
{
constructor
(
private
templateSrv
)
{}
transform
(
result
:
any
,
response
:
any
,
options
:
any
)
{
let
prometheusResult
=
response
.
data
.
data
.
result
;
if
(
options
.
format
===
'table'
)
{
result
.
push
(
this
.
transformMetricDataToTable
(
prometheusResult
,
options
.
responseListLength
,
options
.
responseIndex
));
}
else
if
(
options
.
format
===
'heatmap'
)
{
let
seriesList
=
[];
prometheusResult
.
sort
(
sortSeriesByLabel
);
for
(
let
metricData
of
prometheusResult
)
{
seriesList
.
push
(
this
.
transformMetricData
(
metricData
,
options
,
options
.
start
,
options
.
end
));
}
seriesList
=
this
.
transformToHistogramOverTime
(
seriesList
);
result
.
push
(...
seriesList
);
}
else
{
for
(
let
metricData
of
prometheusResult
)
{
if
(
response
.
data
.
data
.
resultType
===
'matrix'
)
{
result
.
push
(
this
.
transformMetricData
(
metricData
,
options
,
options
.
start
,
options
.
end
));
}
else
if
(
response
.
data
.
data
.
resultType
===
'vector'
)
{
result
.
push
(
this
.
transformInstantMetricData
(
metricData
,
options
));
}
}
}
}
transformMetricData
(
md
,
options
,
start
,
end
)
{
let
dps
=
[],
metricLabel
=
null
;
metricLabel
=
this
.
createMetricLabel
(
md
.
metric
,
options
);
const
stepMs
=
parseInt
(
options
.
step
)
*
1000
;
let
baseTimestamp
=
start
*
1000
;
for
(
let
value
of
md
.
values
)
{
let
dp_value
=
parseFloat
(
value
[
1
]);
if
(
_
.
isNaN
(
dp_value
))
{
dp_value
=
null
;
}
const
timestamp
=
parseFloat
(
value
[
0
])
*
1000
;
for
(
let
t
=
baseTimestamp
;
t
<
timestamp
;
t
+=
stepMs
)
{
dps
.
push
([
null
,
t
]);
}
baseTimestamp
=
timestamp
+
stepMs
;
dps
.
push
([
dp_value
,
timestamp
]);
}
const
endTimestamp
=
end
*
1000
;
for
(
let
t
=
baseTimestamp
;
t
<=
endTimestamp
;
t
+=
stepMs
)
{
dps
.
push
([
null
,
t
]);
}
return
{
target
:
metricLabel
,
datapoints
:
dps
};
}
transformMetricDataToTable
(
md
,
resultCount
:
number
,
resultIndex
:
number
)
{
var
table
=
new
TableModel
();
var
i
,
j
;
var
metricLabels
=
{};
if
(
md
.
length
===
0
)
{
return
table
;
}
// Collect all labels across all metrics
_
.
each
(
md
,
function
(
series
)
{
for
(
var
label
in
series
.
metric
)
{
if
(
!
metricLabels
.
hasOwnProperty
(
label
))
{
metricLabels
[
label
]
=
1
;
}
}
});
// Sort metric labels, create columns for them and record their index
var
sortedLabels
=
_
.
keys
(
metricLabels
).
sort
();
table
.
columns
.
push
({
text
:
'Time'
,
type
:
'time'
});
_
.
each
(
sortedLabels
,
function
(
label
,
labelIndex
)
{
metricLabels
[
label
]
=
labelIndex
+
1
;
table
.
columns
.
push
({
text
:
label
});
});
let
valueText
=
resultCount
>
1
?
`Value #
${
String
.
fromCharCode
(
65
+
resultIndex
)}
`
:
'Value'
;
table
.
columns
.
push
({
text
:
valueText
});
// Populate rows, set value to empty string when label not present.
_
.
each
(
md
,
function
(
series
)
{
if
(
series
.
value
)
{
series
.
values
=
[
series
.
value
];
}
if
(
series
.
values
)
{
for
(
i
=
0
;
i
<
series
.
values
.
length
;
i
++
)
{
var
values
=
series
.
values
[
i
];
var
reordered
:
any
=
[
values
[
0
]
*
1000
];
if
(
series
.
metric
)
{
for
(
j
=
0
;
j
<
sortedLabels
.
length
;
j
++
)
{
var
label
=
sortedLabels
[
j
];
if
(
series
.
metric
.
hasOwnProperty
(
label
))
{
reordered
.
push
(
series
.
metric
[
label
]);
}
else
{
reordered
.
push
(
''
);
}
}
}
reordered
.
push
(
parseFloat
(
values
[
1
]));
table
.
rows
.
push
(
reordered
);
}
}
});
return
table
;
}
transformInstantMetricData
(
md
,
options
)
{
var
dps
=
[],
metricLabel
=
null
;
metricLabel
=
this
.
createMetricLabel
(
md
.
metric
,
options
);
dps
.
push
([
parseFloat
(
md
.
value
[
1
]),
md
.
value
[
0
]
*
1000
]);
return
{
target
:
metricLabel
,
datapoints
:
dps
};
}
createMetricLabel
(
labelData
,
options
)
{
if
(
_
.
isUndefined
(
options
)
||
_
.
isEmpty
(
options
.
legendFormat
))
{
return
this
.
getOriginalMetricName
(
labelData
);
}
return
this
.
renderTemplate
(
this
.
templateSrv
.
replace
(
options
.
legendFormat
),
labelData
)
||
'{}'
;
}
renderTemplate
(
aliasPattern
,
aliasData
)
{
var
aliasRegex
=
/
\{\{\s
*
(
.+
?)\s
*
\}\}
/g
;
return
aliasPattern
.
replace
(
aliasRegex
,
function
(
match
,
g1
)
{
if
(
aliasData
[
g1
])
{
return
aliasData
[
g1
];
}
return
g1
;
});
}
getOriginalMetricName
(
labelData
)
{
var
metricName
=
labelData
.
__name__
||
''
;
delete
labelData
.
__name__
;
var
labelPart
=
_
.
map
(
_
.
toPairs
(
labelData
),
function
(
label
)
{
return
label
[
0
]
+
'="'
+
label
[
1
]
+
'"'
;
}).
join
(
','
);
return
metricName
+
'{'
+
labelPart
+
'}'
;
}
transformToHistogramOverTime
(
seriesList
)
{
/* t1 = timestamp1, t2 = timestamp2 etc.
t1 t2 t3 t1 t2 t3
le10 10 10 0 => 10 10 0
le20 20 10 30 => 10 0 30
le30 30 10 35 => 10 0 5
*/
for
(
let
i
=
seriesList
.
length
-
1
;
i
>
0
;
i
--
)
{
let
topSeries
=
seriesList
[
i
].
datapoints
;
let
bottomSeries
=
seriesList
[
i
-
1
].
datapoints
;
for
(
let
j
=
0
;
j
<
topSeries
.
length
;
j
++
)
{
topSeries
[
j
][
0
]
-=
bottomSeries
[
j
][
0
];
}
}
return
seriesList
;
}
}
function
sortSeriesByLabel
(
s1
,
s2
):
number
{
let
le1
,
le2
;
try
{
// fail if not integer. might happen with bad queries
le1
=
parseHistogramLabel
(
s1
.
metric
.
le
);
le2
=
parseHistogramLabel
(
s2
.
metric
.
le
);
}
catch
(
err
)
{
console
.
log
(
err
);
return
0
;
}
if
(
le1
>
le2
)
{
return
1
;
}
if
(
le1
<
le2
)
{
return
-
1
;
}
return
0
;
}
function
parseHistogramLabel
(
le
:
string
):
number
{
if
(
le
===
'+Inf'
)
{
return
+
Infinity
;
}
return
Number
(
le
);
}
public/app/plugins/datasource/prometheus/specs/datasource_specs.ts
View file @
479209f4
...
...
@@ -223,43 +223,6 @@ describe('PrometheusDatasource', function() {
expect
(
results
[
0
].
time
).
to
.
be
(
1443454528
*
1000
);
});
});
describe
(
'When resultFormat is table'
,
function
()
{
var
response
=
{
status
:
'success'
,
data
:
{
resultType
:
'matrix'
,
result
:
[
{
metric
:
{
__name__
:
'test'
,
job
:
'testjob'
},
values
:
[[
1443454528
,
'3846'
]],
},
{
metric
:
{
__name__
:
'test'
,
instance
:
'localhost:8080'
,
job
:
'otherjob'
,
},
values
:
[[
1443454529
,
'3847'
]],
},
],
},
};
it
(
'should return table model'
,
function
()
{
var
table
=
ctx
.
ds
.
transformMetricDataToTable
(
response
.
data
.
result
);
expect
(
table
.
type
).
to
.
be
(
'table'
);
expect
(
table
.
rows
).
to
.
eql
([
[
1443454528000
,
'test'
,
''
,
'testjob'
,
3846
],
[
1443454529000
,
'test'
,
'localhost:8080'
,
'otherjob'
,
3847
],
]);
expect
(
table
.
columns
).
to
.
eql
([
{
text
:
'Time'
,
type
:
'time'
},
{
text
:
'__name__'
},
{
text
:
'instance'
},
{
text
:
'job'
},
{
text
:
'Value'
},
]);
});
});
describe
(
'When resultFormat is table and instant = true'
,
function
()
{
var
results
;
...
...
@@ -293,19 +256,8 @@ describe('PrometheusDatasource', function() {
it
(
'should return result'
,
()
=>
{
expect
(
results
).
not
.
to
.
be
(
null
);
});
it
(
'should return table model'
,
function
()
{
var
table
=
ctx
.
ds
.
transformMetricDataToTable
(
response
.
data
.
result
);
expect
(
table
.
type
).
to
.
be
(
'table'
);
expect
(
table
.
rows
).
to
.
eql
([[
1443454528000
,
'test'
,
'testjob'
,
3846
]]);
expect
(
table
.
columns
).
to
.
eql
([
{
text
:
'Time'
,
type
:
'time'
},
{
text
:
'__name__'
},
{
text
:
'job'
},
{
text
:
'Value'
},
]);
});
});
describe
(
'The "step" query parameter'
,
function
()
{
var
response
=
{
status
:
'success'
,
...
...
public/app/plugins/datasource/prometheus/specs/result_transformer.jest.ts
0 → 100644
View file @
479209f4
import
{
ResultTransformer
}
from
'../result_transformer'
;
describe
(
'Prometheus Result Transformer'
,
()
=>
{
let
ctx
:
any
=
{};
beforeEach
(()
=>
{
ctx
.
templateSrv
=
{
replace
:
str
=>
str
,
};
ctx
.
resultTransformer
=
new
ResultTransformer
(
ctx
.
templateSrv
);
});
describe
(
'When resultFormat is table'
,
()
=>
{
var
response
=
{
status
:
'success'
,
data
:
{
resultType
:
'matrix'
,
result
:
[
{
metric
:
{
__name__
:
'test'
,
job
:
'testjob'
},
values
:
[[
1443454528
,
'3846'
]],
},
{
metric
:
{
__name__
:
'test'
,
instance
:
'localhost:8080'
,
job
:
'otherjob'
,
},
values
:
[[
1443454529
,
'3847'
]],
},
],
},
};
it
(
'should return table model'
,
()
=>
{
var
table
=
ctx
.
resultTransformer
.
transformMetricDataToTable
(
response
.
data
.
result
);
expect
(
table
.
type
).
toBe
(
'table'
);
expect
(
table
.
rows
).
toEqual
([
[
1443454528000
,
'test'
,
''
,
'testjob'
,
3846
],
[
1443454529000
,
'test'
,
'localhost:8080'
,
'otherjob'
,
3847
],
]);
expect
(
table
.
columns
).
toEqual
([
{
text
:
'Time'
,
type
:
'time'
},
{
text
:
'__name__'
},
{
text
:
'instance'
},
{
text
:
'job'
},
{
text
:
'Value'
},
]);
});
});
describe
(
'When resultFormat is table and instant = true'
,
()
=>
{
var
response
=
{
status
:
'success'
,
data
:
{
resultType
:
'vector'
,
result
:
[
{
metric
:
{
__name__
:
'test'
,
job
:
'testjob'
},
value
:
[
1443454528
,
'3846'
],
},
],
},
};
it
(
'should return table model'
,
()
=>
{
var
table
=
ctx
.
resultTransformer
.
transformMetricDataToTable
(
response
.
data
.
result
);
expect
(
table
.
type
).
toBe
(
'table'
);
expect
(
table
.
rows
).
toEqual
([[
1443454528000
,
'test'
,
'testjob'
,
3846
]]);
expect
(
table
.
columns
).
toEqual
([
{
text
:
'Time'
,
type
:
'time'
},
{
text
:
'__name__'
},
{
text
:
'job'
},
{
text
:
'Value'
},
]);
});
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment