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
c140d7aa
Commit
c140d7aa
authored
Sep 25, 2017
by
Mitsuhiro Tanda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
re-implement annotation query
parent
8f3b0609
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
263 additions
and
224 deletions
+263
-224
pkg/tsdb/cloudwatch/annotation_query.go
+218
-0
pkg/tsdb/cloudwatch/cloudwatch.go
+3
-0
public/app/plugins/datasource/cloudwatch/annotation_query.d.ts
+0
-2
public/app/plugins/datasource/cloudwatch/annotation_query.js
+0
-106
public/app/plugins/datasource/cloudwatch/datasource.js
+42
-35
public/app/plugins/datasource/cloudwatch/specs/annotation_query_specs.ts
+0
-81
No files found.
pkg/tsdb/cloudwatch/annotation_query.go
0 → 100644
View file @
c140d7aa
package
cloudwatch
import
(
"context"
"errors"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/tsdb"
)
func
(
e
*
CloudWatchExecutor
)
executeAnnotationQuery
(
ctx
context
.
Context
,
queryContext
*
tsdb
.
TsdbQuery
)
(
*
tsdb
.
Response
,
error
)
{
result
:=
&
tsdb
.
Response
{
Results
:
make
(
map
[
string
]
*
tsdb
.
QueryResult
),
}
firstQuery
:=
queryContext
.
Queries
[
0
]
queryResult
:=
&
tsdb
.
QueryResult
{
Meta
:
simplejson
.
New
(),
RefId
:
firstQuery
.
RefId
}
parameters
:=
firstQuery
.
Model
usePrefixMatch
:=
parameters
.
Get
(
"prefixMatching"
)
.
MustBool
()
region
:=
parameters
.
Get
(
"region"
)
.
MustString
(
""
)
namespace
:=
parameters
.
Get
(
"namespace"
)
.
MustString
(
""
)
metricName
:=
parameters
.
Get
(
"metricName"
)
.
MustString
(
""
)
dimensions
:=
parameters
.
Get
(
"dimensions"
)
.
MustMap
()
statistics
:=
parameters
.
Get
(
"statistics"
)
.
MustStringArray
()
extendedStatistics
:=
parameters
.
Get
(
"extendedStatistics"
)
.
MustStringArray
()
period
:=
int64
(
300
)
if
usePrefixMatch
{
period
=
int64
(
parameters
.
Get
(
"period"
)
.
MustInt
(
0
))
}
actionPrefix
:=
parameters
.
Get
(
"actionPrefix"
)
.
MustString
(
""
)
alarmNamePrefix
:=
parameters
.
Get
(
"alarmNamePrefix"
)
.
MustString
(
""
)
dsInfo
:=
e
.
getDsInfo
(
region
)
cfg
,
err
:=
getAwsConfig
(
dsInfo
)
if
err
!=
nil
{
return
nil
,
errors
.
New
(
"Failed to call cloudwatch:ListMetrics"
)
}
sess
,
err
:=
session
.
NewSession
(
cfg
)
if
err
!=
nil
{
return
nil
,
errors
.
New
(
"Failed to call cloudwatch:ListMetrics"
)
}
svc
:=
cloudwatch
.
New
(
sess
,
cfg
)
var
alarmNames
[]
*
string
if
usePrefixMatch
{
params
:=
&
cloudwatch
.
DescribeAlarmsInput
{
MaxRecords
:
aws
.
Int64
(
100
),
ActionPrefix
:
aws
.
String
(
actionPrefix
),
AlarmNamePrefix
:
aws
.
String
(
alarmNamePrefix
),
}
resp
,
err
:=
svc
.
DescribeAlarms
(
params
)
if
err
!=
nil
{
return
nil
,
errors
.
New
(
"Failed to call cloudwatch:DescribeAlarms"
)
}
alarmNames
=
filterAlarms
(
resp
,
namespace
,
metricName
,
dimensions
,
statistics
,
extendedStatistics
,
period
)
}
else
{
if
region
==
""
||
namespace
==
""
||
metricName
==
""
||
len
(
statistics
)
==
0
{
return
result
,
nil
}
var
qd
[]
*
cloudwatch
.
Dimension
for
k
,
v
:=
range
dimensions
{
if
vv
,
ok
:=
v
.
(
string
);
ok
{
qd
=
append
(
qd
,
&
cloudwatch
.
Dimension
{
Name
:
aws
.
String
(
k
),
Value
:
aws
.
String
(
vv
),
})
}
}
for
_
,
s
:=
range
statistics
{
params
:=
&
cloudwatch
.
DescribeAlarmsForMetricInput
{
Namespace
:
aws
.
String
(
namespace
),
MetricName
:
aws
.
String
(
metricName
),
Period
:
aws
.
Int64
(
int64
(
period
)),
Dimensions
:
qd
,
Statistic
:
aws
.
String
(
s
),
}
resp
,
err
:=
svc
.
DescribeAlarmsForMetric
(
params
)
if
err
!=
nil
{
return
nil
,
errors
.
New
(
"Failed to call cloudwatch:DescribeAlarmsForMetric"
)
}
for
_
,
alarm
:=
range
resp
.
MetricAlarms
{
alarmNames
=
append
(
alarmNames
,
alarm
.
AlarmName
)
}
}
for
_
,
s
:=
range
extendedStatistics
{
params
:=
&
cloudwatch
.
DescribeAlarmsForMetricInput
{
Namespace
:
aws
.
String
(
namespace
),
MetricName
:
aws
.
String
(
metricName
),
Period
:
aws
.
Int64
(
int64
(
period
)),
Dimensions
:
qd
,
ExtendedStatistic
:
aws
.
String
(
s
),
}
resp
,
err
:=
svc
.
DescribeAlarmsForMetric
(
params
)
if
err
!=
nil
{
return
nil
,
errors
.
New
(
"Failed to call cloudwatch:DescribeAlarmsForMetric"
)
}
for
_
,
alarm
:=
range
resp
.
MetricAlarms
{
alarmNames
=
append
(
alarmNames
,
alarm
.
AlarmName
)
}
}
}
startTime
,
err
:=
queryContext
.
TimeRange
.
ParseFrom
()
if
err
!=
nil
{
return
nil
,
err
}
endTime
,
err
:=
queryContext
.
TimeRange
.
ParseTo
()
if
err
!=
nil
{
return
nil
,
err
}
annotations
:=
make
([]
map
[
string
]
string
,
0
)
for
_
,
alarmName
:=
range
alarmNames
{
params
:=
&
cloudwatch
.
DescribeAlarmHistoryInput
{
AlarmName
:
alarmName
,
StartDate
:
aws
.
Time
(
startTime
),
EndDate
:
aws
.
Time
(
endTime
),
}
resp
,
err
:=
svc
.
DescribeAlarmHistory
(
params
)
if
err
!=
nil
{
return
nil
,
errors
.
New
(
"Failed to call cloudwatch:DescribeAlarmHistory"
)
}
for
_
,
history
:=
range
resp
.
AlarmHistoryItems
{
annotation
:=
make
(
map
[
string
]
string
)
annotation
[
"time"
]
=
history
.
Timestamp
.
UTC
()
.
Format
(
time
.
RFC3339
)
annotation
[
"title"
]
=
*
history
.
AlarmName
annotation
[
"tags"
]
=
*
history
.
HistoryItemType
annotation
[
"text"
]
=
*
history
.
HistorySummary
annotations
=
append
(
annotations
,
annotation
)
}
}
transformAnnotationToTable
(
annotations
,
queryResult
)
result
.
Results
[
firstQuery
.
RefId
]
=
queryResult
return
result
,
err
}
func
transformAnnotationToTable
(
data
[]
map
[
string
]
string
,
result
*
tsdb
.
QueryResult
)
{
table
:=
&
tsdb
.
Table
{
Columns
:
make
([]
tsdb
.
TableColumn
,
4
),
Rows
:
make
([]
tsdb
.
RowValues
,
0
),
}
table
.
Columns
[
0
]
.
Text
=
"time"
table
.
Columns
[
1
]
.
Text
=
"title"
table
.
Columns
[
2
]
.
Text
=
"tags"
table
.
Columns
[
3
]
.
Text
=
"text"
for
_
,
r
:=
range
data
{
values
:=
make
([]
interface
{},
4
)
values
[
0
]
=
r
[
"time"
]
values
[
1
]
=
r
[
"title"
]
values
[
2
]
=
r
[
"tags"
]
values
[
3
]
=
r
[
"text"
]
table
.
Rows
=
append
(
table
.
Rows
,
values
)
}
result
.
Tables
=
append
(
result
.
Tables
,
table
)
result
.
Meta
.
Set
(
"rowCount"
,
len
(
data
))
}
func
filterAlarms
(
alarms
*
cloudwatch
.
DescribeAlarmsOutput
,
namespace
string
,
metricName
string
,
dimensions
map
[
string
]
interface
{},
statistics
[]
string
,
extendedStatistics
[]
string
,
period
int64
)
[]
*
string
{
alarmNames
:=
make
([]
*
string
,
0
)
for
_
,
alarm
:=
range
alarms
.
MetricAlarms
{
if
namespace
!=
""
&&
*
alarm
.
Namespace
!=
namespace
{
continue
}
if
metricName
!=
""
&&
*
alarm
.
MetricName
!=
metricName
{
continue
}
match
:=
true
for
_
,
d
:=
range
alarm
.
Dimensions
{
if
_
,
ok
:=
dimensions
[
*
d
.
Name
];
!
ok
{
match
=
false
}
}
if
!
match
{
continue
}
if
period
!=
0
&&
*
alarm
.
Period
!=
period
{
continue
}
if
len
(
statistics
)
!=
0
{
found
:=
false
for
_
,
s
:=
range
statistics
{
if
*
alarm
.
Statistic
==
s
{
found
=
true
}
}
if
!
found
{
continue
}
}
if
len
(
extendedStatistics
)
!=
0
{
found
:=
false
for
_
,
s
:=
range
extendedStatistics
{
if
*
alarm
.
Statistic
==
s
{
found
=
true
}
}
if
!
found
{
continue
}
}
alarmNames
=
append
(
alarmNames
,
alarm
.
AlarmName
)
}
return
alarmNames
}
pkg/tsdb/cloudwatch/cloudwatch.go
View file @
c140d7aa
...
...
@@ -60,6 +60,9 @@ func (e *CloudWatchExecutor) Query(ctx context.Context, dsInfo *models.DataSourc
case
"metricFindQuery"
:
result
,
err
=
e
.
executeMetricFindQuery
(
ctx
,
queryContext
)
break
case
"annotationQuery"
:
result
,
err
=
e
.
executeAnnotationQuery
(
ctx
,
queryContext
)
break
case
"timeSeriesQuery"
:
fallthrough
default
:
...
...
public/app/plugins/datasource/cloudwatch/annotation_query.d.ts
deleted
100644 → 0
View file @
8f3b0609
declare
var
test
:
any
;
export
default
test
;
public/app/plugins/datasource/cloudwatch/annotation_query.js
deleted
100644 → 0
View file @
8f3b0609
define
([
'lodash'
,
],
function
(
_
)
{
'use strict'
;
function
CloudWatchAnnotationQuery
(
datasource
,
annotation
,
$q
,
templateSrv
)
{
this
.
datasource
=
datasource
;
this
.
annotation
=
annotation
;
this
.
$q
=
$q
;
this
.
templateSrv
=
templateSrv
;
}
CloudWatchAnnotationQuery
.
prototype
.
process
=
function
(
from
,
to
)
{
var
self
=
this
;
var
usePrefixMatch
=
this
.
annotation
.
prefixMatching
;
var
region
=
this
.
templateSrv
.
replace
(
this
.
annotation
.
region
);
var
namespace
=
this
.
templateSrv
.
replace
(
this
.
annotation
.
namespace
);
var
metricName
=
this
.
templateSrv
.
replace
(
this
.
annotation
.
metricName
);
var
dimensions
=
this
.
datasource
.
convertDimensionFormat
(
this
.
annotation
.
dimensions
);
var
statistics
=
_
.
map
(
this
.
annotation
.
statistics
,
function
(
s
)
{
return
self
.
templateSrv
.
replace
(
s
);
});
var
defaultPeriod
=
usePrefixMatch
?
''
:
'300'
;
var
period
=
this
.
annotation
.
period
||
defaultPeriod
;
period
=
parseInt
(
period
,
10
);
var
actionPrefix
=
this
.
annotation
.
actionPrefix
||
''
;
var
alarmNamePrefix
=
this
.
annotation
.
alarmNamePrefix
||
''
;
var
d
=
this
.
$q
.
defer
();
var
allQueryPromise
;
if
(
usePrefixMatch
)
{
allQueryPromise
=
[
this
.
datasource
.
performDescribeAlarms
(
region
,
actionPrefix
,
alarmNamePrefix
,
[],
''
).
then
(
function
(
alarms
)
{
alarms
.
MetricAlarms
=
self
.
filterAlarms
(
alarms
,
namespace
,
metricName
,
dimensions
,
statistics
,
period
);
return
alarms
;
})
];
}
else
{
if
(
!
region
||
!
namespace
||
!
metricName
||
_
.
isEmpty
(
statistics
))
{
return
this
.
$q
.
when
([]);
}
allQueryPromise
=
_
.
map
(
statistics
,
function
(
statistic
)
{
return
self
.
datasource
.
performDescribeAlarmsForMetric
(
region
,
namespace
,
metricName
,
dimensions
,
statistic
,
period
);
});
}
this
.
$q
.
all
(
allQueryPromise
).
then
(
function
(
alarms
)
{
var
eventList
=
[];
var
start
=
self
.
datasource
.
convertToCloudWatchTime
(
from
,
false
);
var
end
=
self
.
datasource
.
convertToCloudWatchTime
(
to
,
true
);
_
.
chain
(
alarms
)
.
map
(
'MetricAlarms'
)
.
flatten
()
.
each
(
function
(
alarm
)
{
if
(
!
alarm
)
{
d
.
resolve
(
eventList
);
return
;
}
self
.
datasource
.
performDescribeAlarmHistory
(
region
,
alarm
.
AlarmName
,
start
,
end
).
then
(
function
(
history
)
{
_
.
each
(
history
.
AlarmHistoryItems
,
function
(
h
)
{
var
event
=
{
annotation
:
self
.
annotation
,
time
:
Date
.
parse
(
h
.
Timestamp
),
title
:
h
.
AlarmName
,
tags
:
[
h
.
HistoryItemType
],
text
:
h
.
HistorySummary
};
eventList
.
push
(
event
);
});
d
.
resolve
(
eventList
);
});
})
.
value
();
});
return
d
.
promise
;
};
CloudWatchAnnotationQuery
.
prototype
.
filterAlarms
=
function
(
alarms
,
namespace
,
metricName
,
dimensions
,
statistics
,
period
)
{
return
_
.
filter
(
alarms
.
MetricAlarms
,
function
(
alarm
)
{
if
(
!
_
.
isEmpty
(
namespace
)
&&
alarm
.
Namespace
!==
namespace
)
{
return
false
;
}
if
(
!
_
.
isEmpty
(
metricName
)
&&
alarm
.
MetricName
!==
metricName
)
{
return
false
;
}
var
sd
=
function
(
d
)
{
return
d
.
Name
;
};
var
isSameDimensions
=
JSON
.
stringify
(
_
.
sortBy
(
alarm
.
Dimensions
,
sd
))
===
JSON
.
stringify
(
_
.
sortBy
(
dimensions
,
sd
));
if
(
!
_
.
isEmpty
(
dimensions
)
&&
!
isSameDimensions
)
{
return
false
;
}
if
(
!
_
.
isEmpty
(
statistics
)
&&
!
_
.
includes
(
statistics
,
alarm
.
Statistic
))
{
return
false
;
}
if
(
!
_
.
isNaN
(
period
)
&&
alarm
.
Period
!==
period
)
{
return
false
;
}
return
true
;
});
};
return
CloudWatchAnnotationQuery
;
});
public/app/plugins/datasource/cloudwatch/datasource.js
View file @
c140d7aa
...
...
@@ -5,9 +5,8 @@ define([
'app/core/utils/datemath'
,
'app/core/utils/kbn'
,
'app/features/templating/variable'
,
'./annotation_query'
,
],
function
(
angular
,
_
,
moment
,
dateMath
,
kbn
,
templatingVariable
,
CloudWatchAnnotationQuery
)
{
function
(
angular
,
_
,
moment
,
dateMath
,
kbn
,
templatingVariable
)
{
'use strict'
;
/** @ngInject */
...
...
@@ -262,44 +261,52 @@ function (angular, _, moment, dateMath, kbn, templatingVariable, CloudWatchAnnot
return
$q
.
when
([]);
};
this
.
performDescribeAlarms
=
function
(
region
,
actionPrefix
,
alarmNamePrefix
,
alarmNames
,
stateValue
)
{
return
this
.
awsRequest
({
region
:
region
,
action
:
'DescribeAlarms'
,
parameters
:
{
actionPrefix
:
actionPrefix
,
alarmNamePrefix
:
alarmNamePrefix
,
alarmNames
:
alarmNames
,
stateValue
:
stateValue
}
});
};
this
.
performDescribeAlarmsForMetric
=
function
(
region
,
namespace
,
metricName
,
dimensions
,
statistic
,
period
)
{
var
s
=
_
.
includes
(
self
.
standardStatistics
,
statistic
)
?
statistic
:
''
;
var
es
=
_
.
includes
(
self
.
standardStatistics
,
statistic
)
?
''
:
statistic
;
return
this
.
awsRequest
({
region
:
region
,
action
:
'DescribeAlarmsForMetric'
,
parameters
:
{
namespace
:
namespace
,
metricName
:
metricName
,
dimensions
:
dimensions
,
statistic
:
s
,
extendedStatistic
:
es
,
period
:
period
}
this
.
annotationQuery
=
function
(
options
)
{
var
annotation
=
options
.
annotation
;
var
defaultPeriod
=
annotation
.
prefixMatching
?
''
:
'300'
;
var
period
=
annotation
.
period
||
defaultPeriod
;
period
=
parseInt
(
period
,
10
);
var
dimensions
=
{};
_
.
each
(
annotation
.
dimensions
,
function
(
value
,
key
)
{
dimensions
[
templateSrv
.
replace
(
key
,
options
.
scopedVars
)]
=
templateSrv
.
replace
(
value
,
options
.
scopedVars
);
});
};
var
parameters
=
{
prefixMatching
:
annotation
.
prefixMatching
,
region
:
templateSrv
.
replace
(
annotation
.
region
),
namespace
:
templateSrv
.
replace
(
annotation
.
namespace
),
metricName
:
templateSrv
.
replace
(
annotation
.
metricName
),
dimensions
:
dimensions
,
statistics
:
_
.
map
(
annotation
.
statistics
,
function
(
s
)
{
return
templateSrv
.
replace
(
s
);
}),
period
:
period
,
actionPrefix
:
annotation
.
actionPrefix
||
''
,
alarmNamePrefix
:
annotation
.
alarmNamePrefix
||
''
};
this
.
performDescribeAlarmHistory
=
function
(
region
,
alarmName
,
startDate
,
endDate
)
{
return
this
.
awsRequest
({
region
:
region
,
action
:
'DescribeAlarmHistory'
,
parameters
:
{
alarmName
:
alarmName
,
startDate
:
startDate
,
endDate
:
endDate
}
return
backendSrv
.
post
(
'/api/tsdb/query'
,
{
from
:
options
.
range
.
from
,
to
:
options
.
range
.
to
,
queries
:
[
_
.
extend
({
refId
:
'annotationQuery'
,
intervalMs
:
1
,
// dummy
maxDataPoints
:
1
,
// dummy
datasourceId
:
this
.
instanceSettings
.
id
,
type
:
'annotationQuery'
},
parameters
)
]
}).
then
(
function
(
r
)
{
return
_
.
map
(
r
.
results
[
'annotationQuery'
].
tables
[
0
].
rows
,
function
(
v
)
{
return
{
annotation
:
annotation
,
time
:
Date
.
parse
(
v
[
0
]),
title
:
v
[
1
],
tags
:
[
v
[
2
]],
text
:
v
[
3
]
};
});
});
};
this
.
annotationQuery
=
function
(
options
)
{
var
annotationQuery
=
new
CloudWatchAnnotationQuery
(
this
,
options
.
annotation
,
$q
,
templateSrv
);
return
annotationQuery
.
process
(
options
.
range
.
from
,
options
.
range
.
to
);
};
this
.
testDatasource
=
function
()
{
/* use billing metrics for test */
var
region
=
this
.
defaultRegion
;
...
...
public/app/plugins/datasource/cloudwatch/specs/annotation_query_specs.ts
deleted
100644 → 0
View file @
8f3b0609
import
"../datasource"
;
import
{
describe
,
beforeEach
,
it
,
expect
,
angularMocks
}
from
'test/lib/common'
;
import
moment
from
'moment'
;
import
helpers
from
'test/specs/helpers'
;
import
CloudWatchDatasource
from
"../datasource"
;
import
CloudWatchAnnotationQuery
from
'../annotation_query'
;
describe
(
'CloudWatchAnnotationQuery'
,
function
()
{
var
ctx
=
new
helpers
.
ServiceTestContext
();
var
instanceSettings
=
{
jsonData
:
{
defaultRegion
:
'us-east-1'
,
access
:
'proxy'
},
};
beforeEach
(
angularMocks
.
module
(
'grafana.core'
));
beforeEach
(
angularMocks
.
module
(
'grafana.services'
));
beforeEach
(
angularMocks
.
module
(
'grafana.controllers'
));
beforeEach
(
ctx
.
providePhase
([
'templateSrv'
,
'backendSrv'
]));
beforeEach
(
angularMocks
.
inject
(
function
(
$q
,
$rootScope
,
$httpBackend
,
$injector
)
{
ctx
.
$q
=
$q
;
ctx
.
$httpBackend
=
$httpBackend
;
ctx
.
$rootScope
=
$rootScope
;
ctx
.
ds
=
$injector
.
instantiate
(
CloudWatchDatasource
,
{
instanceSettings
:
instanceSettings
});
}));
describe
(
'When performing annotationQuery'
,
function
()
{
var
parameter
=
{
annotation
:
{
region
:
'us-east-1'
,
namespace
:
'AWS/EC2'
,
metricName
:
'CPUUtilization'
,
dimensions
:
{
InstanceId
:
'i-12345678'
},
statistics
:
[
'Average'
],
period
:
300
},
range
:
{
from
:
moment
(
1443438674760
),
to
:
moment
(
1443460274760
)
}
};
var
alarmResponse
=
{
MetricAlarms
:
[
{
AlarmName
:
'test_alarm_name'
}
]
};
var
historyResponse
=
{
AlarmHistoryItems
:
[
{
Timestamp
:
'2015-01-01T00:00:00.000Z'
,
HistoryItemType
:
'StateUpdate'
,
AlarmName
:
'test_alarm_name'
,
HistoryData
:
'{}'
,
HistorySummary
:
'test_history_summary'
}
]
};
beforeEach
(
function
()
{
ctx
.
backendSrv
.
datasourceRequest
=
function
(
params
)
{
switch
(
params
.
data
.
action
)
{
case
'DescribeAlarmsForMetric'
:
return
ctx
.
$q
.
when
({
data
:
alarmResponse
});
case
'DescribeAlarmHistory'
:
return
ctx
.
$q
.
when
({
data
:
historyResponse
});
}
};
});
it
(
'should return annotation list'
,
function
(
done
)
{
var
annotationQuery
=
new
CloudWatchAnnotationQuery
(
ctx
.
ds
,
parameter
.
annotation
,
ctx
.
$q
,
ctx
.
templateSrv
);
annotationQuery
.
process
(
parameter
.
range
.
from
,
parameter
.
range
.
to
).
then
(
function
(
result
)
{
expect
(
result
[
0
].
title
).
to
.
be
(
'test_alarm_name'
);
expect
(
result
[
0
].
text
).
to
.
be
(
'test_history_summary'
);
done
();
});
ctx
.
$rootScope
.
$apply
();
});
});
});
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