Rename @status to @state

Fixes #104

@status filter was added to the master branch to support new status key from Alertmanager >=0.6.1
status ended up being nested in Alertmanager (it was added to solve AM issue 609 and that was a long PR with lots of changes), current unsee implementation ended being slightly off with how Alertmanager is naming this, it should actually be @state rather than @status.
This commit is contained in:
Łukasz Mierzwa
2017-05-23 21:52:08 +01:00
parent 62fea808bc
commit 8a77d620fd
18 changed files with 115 additions and 115 deletions

View File

@@ -52,7 +52,7 @@ run: $(NAME)
COLOR_LABELS_UNIQUE="instance cluster" \
COLOR_LABELS_STATIC="job" \
DEBUG="$(GIN_DEBUG)" \
FILTER_DEFAULT="@status=active" \
FILTER_DEFAULT="@state=active" \
PORT=$(PORT) \
./$(NAME)

View File

@@ -30,14 +30,14 @@ var Autocomplete = (function() {
// this is used to generate quick filters for label modal
var generateHints = function(label_key, label_val) {
var hints = [];
if (label_key == "@status") {
if (label_key == "@state") {
// static list of hints for @silenced label
hints.push("@status=active");
hints.push("@status=suppressed");
hints.push("@status=unprocessed");
hints.push("@status!=active");
hints.push("@status!=suppressed");
hints.push("@status!=unprocessed");
hints.push("@state=active");
hints.push("@state=suppressed");
hints.push("@state=unprocessed");
hints.push("@state!=active");
hints.push("@state!=suppressed");
hints.push("@state!=unprocessed");
} else {
// equal and non-equal hints for everything else
hints.push(label_key + "=" + label_val);

View File

@@ -5,9 +5,9 @@ var Colors = (function() {
staticColorLabels;
var specialLabels = {
"@status: unprocessed": "label-default",
"@status: active": "label-danger",
"@status: suppressed": "label-success",
"@state: unprocessed": "label-default",
"@state: active": "label-danger",
"@state: suppressed": "label-success",
};
var update = function(colorData) {

View File

@@ -50,7 +50,7 @@
<script type="application/json" id="alert-group-elements">
<% var cls_indicator = 'incident-indicator-danger' %>
<% if (alert.status === "suppressed") { cls_indicator = 'incident-indicator-success' } %>
<% if (alert.state === "suppressed") { cls_indicator = 'incident-indicator-success' } %>
<div>
<% if (alert.generatorURL) { %>
<a class="label label-list label-default"
@@ -74,8 +74,8 @@
<%- text %>
</a>
<% }) %>
<% var attrs = Alerts.GetLabelAttrs("@status", alert.status) %>
<%= Templates.Render('buttonLabel', {elem: 'span', attrs: attrs, label: {key: '@status', value: alert.status, text: '@status: ' + alert.status}}) %>
<% var attrs = Alerts.GetLabelAttrs("@state", alert.state) %>
<%= Templates.Render('buttonLabel', {elem: 'span', attrs: attrs, label: {key: '@state', value: alert.state, text: '@state: ' + alert.state}}) %>
<% if (alert.silencedBy.length == 0) { %>
<% var labels = [] %>
<% _.each(Alerts.SortMapByKey(alert.labels), function(label) { %>
@@ -197,9 +197,9 @@
<script type="application/json" id="alert-group">
<div class="incident" id="<%= group.id %>" data-hash="<%= group.hash %>">
<% var cls_panel = 'panel-default' %>
<% if (group.statusCount.active > 0) { %>
<% if (group.stateCount.active > 0) { %>
<% cls_panel = 'panel-danger' %>
<% } else if (group.statusCount.suppressed > 0) { %>
<% } else if (group.stateCount.suppressed > 0) { %>
<% cls_panel = 'panel-success' %>
<% } %>
<div class="panel <%= cls_panel %>">
@@ -218,9 +218,9 @@
<% labelMap[text].hits++ %>
<% } %>
<% }) %>
<% var statusText = '@status: ' + alert.status %>
<% if (labelMap[statusText] == undefined) { labelMap[statusText] = {key: '@status', value: alert.status, hits: 0} } %>
<% labelMap[statusText].hits++ %>
<% var stateText = '@state: ' + alert.state %>
<% if (labelMap[stateText] == undefined) { labelMap[stateText] = {key: '@state', value: alert.state, hits: 0} } %>
<% labelMap[stateText].hits++ %>
<% } else { %>
<% var cls_body = '' %>
<% if (i < group.alerts.length - 1) { cls_body = 'incident-group-separator' } %>

View File

@@ -130,23 +130,23 @@
</thead>
<tbody>
<tr>
<td id="help-status">
<code>@status=(active suppresed unprocessed)</code>
<td id="help-state">
<code>@state=(active suppresed unprocessed)</code>
</td>
<td>
<p>Match alerts based on the status.</p>
<p>Match alerts based on the state.</p>
<table class="table examples">
<tbody>
<tr>
<td><span class="label label-info">@status=active</span></td>
<td><span class="label label-info">@state=active</span></td>
<td>Match only active alerts.</td>
</tr>
<tr>
<td><span class="label label-info">@status=suppressed</span></td>
<td><span class="label label-info">@state=suppressed</span></td>
<td>Match only suppressed alerts.</td>
</tr>
<tr>
<td><span class="label label-info">@status=unprocessed</span></td>
<td><span class="label label-info">@state=unprocessed</span></td>
<td>Match only unprocessed alerts.</td>
</tr>
</tbody>
@@ -163,15 +163,15 @@
<tbody>
<tr>
<td><span class="label label-info">@silence_author=me@domain1.com</span></td>
<td>Match alerts status by <em>me@domain1.com</em>.</td>
<td>Match alerts silenced by <em>me@domain1.com</em>.</td>
</tr>
<tr>
<td><span class="label label-info">@silence_author!=me@domain1.com</span></td>
<td>Match alerts not status by <em>me@domain1.com</em>.</td>
<td>Match alerts not silenced by <em>me@domain1.com</em>.</td>
</tr>
<tr>
<td><span class="label label-info">@silence_author=~@domain2.com</span></td>
<td>Match alerts status by username that match regular expression <code>/.*@domain2.com.*/</code>.</td>
<td>Match alerts silenced by username that match regular expression <code>/.*@domain2.com.*/</code>.</td>
</tr>
</tbody>
</table>
@@ -187,15 +187,15 @@
<tbody>
<tr>
<td><span class="label label-info">@silence_jira=PROJECT-123</span></td>
<td>Match status alerts where detected JIRA issue id is equal to <em>PROJECT-123</em>.</td>
<td>Match silenced alerts where detected JIRA issue id is equal to <em>PROJECT-123</em>.</td>
</tr>
<tr>
<td><span class="label label-info">@silence_jira!=PROJECT-123</span></td>
<td>Match status alerts where there was no JIRA issue id detected or it was not equal to <em>PROJECT-123</em>.</td>
<td>Match silenced alerts where there was no JIRA issue id detected or it was not equal to <em>PROJECT-123</em>.</td>
</tr>
<tr>
<td><span class="label label-info">@silence_jira=~PROJECT</span></td>
<td>Match status alerts where dectected JIRA issue id matches regular expression <code>/.*PROJECT.*/</code>.</td>
<td>Match silenced alerts where dectected JIRA issue id matches regular expression <code>/.*PROJECT.*/</code>.</td>
</tr>
</tbody>
</table>

File diff suppressed because one or more lines are too long

View File

@@ -7,11 +7,11 @@ import (
"github.com/cloudflare/unsee/models"
)
type statusFilter struct {
type stateFilter struct {
alertFilter
}
func (filter *statusFilter) init(name string, matcher *matcherT, rawText string, isValid bool, value string) {
func (filter *stateFilter) init(name string, matcher *matcherT, rawText string, isValid bool, value string) {
filter.Matched = name
if matcher != nil {
filter.Matcher = *matcher
@@ -24,9 +24,9 @@ func (filter *statusFilter) init(name string, matcher *matcherT, rawText string,
}
}
func (filter *statusFilter) Match(alert *models.Alert, matches int) bool {
func (filter *stateFilter) Match(alert *models.Alert, matches int) bool {
if filter.IsValid {
isMatch := filter.Matcher.Compare(alert.Status, filter.Value)
isMatch := filter.Matcher.Compare(alert.State, filter.Value)
if isMatch {
filter.Hits++
}
@@ -36,17 +36,17 @@ func (filter *statusFilter) Match(alert *models.Alert, matches int) bool {
panic(e)
}
func newstatusFilter() FilterT {
f := statusFilter{}
func newstateFilter() FilterT {
f := stateFilter{}
return &f
}
func statusAutocomplete(name string, operators []string, alerts []models.Alert) []models.Autocomplete {
func stateAutocomplete(name string, operators []string, alerts []models.Alert) []models.Autocomplete {
tokens := []models.Autocomplete{}
for _, operator := range operators {
for _, alert := range alerts {
tokens = append(tokens, makeAC(
name+operator+alert.Status,
name+operator+alert.State,
[]string{
name,
strings.TrimPrefix(name, "@"),

View File

@@ -20,135 +20,135 @@ type filterTest struct {
var tests = []filterTest{
filterTest{
Expression: "@status=active",
Expression: "@state=active",
IsValid: true,
Alert: models.Alert{},
IsMatch: false,
},
filterTest{
Expression: "@status!=active",
Expression: "@state!=active",
IsValid: true,
Alert: models.Alert{},
IsMatch: true,
},
filterTest{
Expression: "@status=suppressed",
Expression: "@state=suppressed",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
IsMatch: true,
},
filterTest{
Expression: "@status!=suppressed",
Expression: "@state!=suppressed",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
IsMatch: false,
},
filterTest{
Expression: "@status=xx",
Expression: "@state=xx",
IsValid: false,
},
filterTest{
Expression: "@status=:xx",
Expression: "@state=:xx",
IsValid: false,
},
filterTest{
Expression: "@status==xx",
Expression: "@state==xx",
IsValid: false,
},
filterTest{
Expression: "@status=~true",
Expression: "@state=~true",
IsValid: false,
},
filterTest{
Expression: "@status=~false",
Expression: "@state=~false",
IsValid: false,
},
filterTest{
Expression: "@status=suppressed",
Expression: "@state=suppressed",
IsValid: true,
Alert: models.Alert{Status: "suppressed", InhibitedBy: []string{"999"}},
Alert: models.Alert{State: "suppressed", InhibitedBy: []string{"999"}},
IsMatch: true,
},
filterTest{
Expression: "@status=suppressed",
Expression: "@state=suppressed",
IsValid: true,
Alert: models.Alert{Status: "active"},
Alert: models.Alert{State: "active"},
IsMatch: false,
},
filterTest{
Expression: "@status!=suppressed",
Expression: "@state!=suppressed",
IsValid: true,
Alert: models.Alert{Status: "suppressed", InhibitedBy: []string{"999"}},
Alert: models.Alert{State: "suppressed", InhibitedBy: []string{"999"}},
IsMatch: false,
},
filterTest{
Expression: "@silence_jira=1",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", JiraID: "1"},
IsMatch: true,
},
filterTest{
Expression: "@silence_jira=2",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1"},
IsMatch: false,
},
filterTest{
Expression: "@silence_jira!=3",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", JiraID: "x"},
IsMatch: true,
},
filterTest{
Expression: "@silence_jira!=4",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", JiraID: "4"},
IsMatch: false,
},
filterTest{
Expression: "@silence_jira!=5",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1"},
IsMatch: true,
},
filterTest{
Expression: "@silence_jira=~abc",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", JiraID: "xxabcxx"},
IsMatch: true,
},
filterTest{
Expression: "@silence_jira=~abc",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", JiraID: "xxx"},
IsMatch: false,
},
filterTest{
Expression: "@silence_jira=~",
IsValid: false,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", JiraID: "xxx"},
IsMatch: false,
},
filterTest{
Expression: "@silence_jira~=",
IsValid: false,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", JiraID: "xxx"},
IsMatch: false,
},
filterTest{
Expression: "@silence_jira~=1",
IsValid: false,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", JiraID: "xxx"},
IsMatch: false,
},
@@ -156,56 +156,56 @@ var tests = []filterTest{
filterTest{
Expression: "@silence_author=john",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", CreatedBy: "john"},
IsMatch: true,
},
filterTest{
Expression: "@silence_author=john",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", CreatedBy: "bob"},
IsMatch: false,
},
filterTest{
Expression: "@silence_author!=john",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", CreatedBy: "bob"},
IsMatch: true,
},
filterTest{
Expression: "@silence_author!=john",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", CreatedBy: "john"},
IsMatch: false,
},
filterTest{
Expression: "@silence_author!=john",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1"},
IsMatch: true,
},
filterTest{
Expression: "@silence_author=~",
IsValid: false,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1"},
IsMatch: false,
},
filterTest{
Expression: "@silence_author===x",
IsValid: false,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1"},
IsMatch: false,
},
filterTest{
Expression: "@silence_author=!!xxx",
IsValid: false,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1"},
IsMatch: false,
},
@@ -371,28 +371,28 @@ var tests = []filterTest{
filterTest{
Expression: "abc",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", Comment: "abc"},
IsMatch: true,
},
filterTest{
Expression: "abc",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", Comment: "abcxxx"},
IsMatch: true,
},
filterTest{
Expression: "abc",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", Comment: "ABCD"},
IsMatch: true,
},
filterTest{
Expression: "abc",
IsValid: true,
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
Alert: models.Alert{State: "suppressed", SilencedBy: []string{"1"}},
Silence: models.Silence{ID: "1", Comment: "xzc"},
IsMatch: false,
},

View File

@@ -41,11 +41,11 @@ type filterConfig struct {
// support
var AllFilters = []filterConfig{
filterConfig{
Label: "@status",
LabelRe: regexp.MustCompile("^@status$"),
Label: "@state",
LabelRe: regexp.MustCompile("^@state$"),
SupportedOperators: []string{equalOperator, notEqualOperator},
Factory: newstatusFilter,
Autocomplete: statusAutocomplete,
Factory: newstateFilter,
Autocomplete: stateAutocomplete,
},
filterConfig{
Label: "@age",

View File

@@ -45,7 +45,7 @@ var (
Name: "unsee_collected_alerts",
Help: "Total number of alerts collected from Alertmanager API",
},
[]string{"status"},
[]string{"state"},
)
metricAlertGroups = prometheus.NewGauge(
prometheus.GaugeOpts{

View File

@@ -93,7 +93,7 @@ func (m AlertMapper) GetAlerts() ([]models.AlertGroup, error) {
StartsAt: a.StartsAt,
EndsAt: a.EndsAt,
GeneratorURL: a.GeneratorURL,
Status: status,
State: status,
InhibitedBy: inhibitedBy,
SilencedBy: silencedBy,
}

View File

@@ -90,7 +90,7 @@ func (m AlertMapper) GetAlerts() ([]models.AlertGroup, error) {
StartsAt: a.StartsAt,
EndsAt: a.EndsAt,
GeneratorURL: a.GeneratorURL,
Status: status,
State: status,
InhibitedBy: inhibitedBy,
SilencedBy: silencedBy,
}

View File

@@ -89,7 +89,7 @@ func (m AlertMapper) GetAlerts() ([]models.AlertGroup, error) {
StartsAt: a.StartsAt,
EndsAt: a.EndsAt,
GeneratorURL: a.GeneratorURL,
Status: a.Status,
State: a.Status,
InhibitedBy: inhibitedBy,
SilencedBy: silencedBy,
}

View File

@@ -93,7 +93,7 @@ func (m AlertMapper) GetAlerts() ([]models.AlertGroup, error) {
StartsAt: a.StartsAt,
EndsAt: a.EndsAt,
GeneratorURL: a.GeneratorURL,
Status: a.Status.State,
State: a.Status.State,
InhibitedBy: inhibitedBy,
SilencedBy: silencedBy,
}

View File

@@ -52,7 +52,7 @@ type Alert struct {
StartsAt time.Time `json:"startsAt"`
EndsAt time.Time `json:"endsAt"`
GeneratorURL string `json:"generatorURL"`
Status string `json:"status"`
State string `json:"state"`
SilencedBy []string `json:"silencedBy"`
InhibitedBy []string `json:"inhibitedBy"`
// unsee fields
@@ -62,17 +62,17 @@ type Alert struct {
// IsSilenced will return true if alert should be considered silenced
func (a Alert) IsSilenced() bool {
return (a.Status == AlertStateSuppressed && len(a.SilencedBy) > 0)
return (a.State == AlertStateSuppressed && len(a.SilencedBy) > 0)
}
// IsInhibited will return true if alert should be considered silenced
func (a Alert) IsInhibited() bool {
return (a.Status == AlertStateSuppressed && len(a.InhibitedBy) > 0)
return (a.State == AlertStateSuppressed && len(a.InhibitedBy) > 0)
}
// IsActive will return true if alert is not suppressed in any way
func (a Alert) IsActive() bool {
return (a.Status == AlertStateActive)
return (a.State == AlertStateActive)
}
// AlertList is flat list of UnseeAlert objects
@@ -100,11 +100,11 @@ func (a AlertList) Less(i, j int) bool {
// There is a hash computed from all alerts, it's used by UI to quickly tell
// if there was any change in a group and it needs to refresh it
type AlertGroup struct {
Labels map[string]string `json:"labels"`
Alerts AlertList `json:"alerts"`
ID string `json:"id"`
Hash string `json:"hash"`
StatusCount map[string]int `json:"statusCount"`
Labels map[string]string `json:"labels"`
Alerts AlertList `json:"alerts"`
ID string `json:"id"`
Hash string `json:"hash"`
StateCount map[string]int `json:"stateCount"`
}
// Filter holds returned data on any filter passed by the user as part of the query

View File

@@ -63,7 +63,7 @@ func PullFromAlertmanager() {
acMap := map[string]models.Autocomplete{}
for _, state := range models.AlertStateList {
metricAlerts.With(prometheus.Labels{"status": state}).Set(0)
metricAlerts.With(prometheus.Labels{"state": state}).Set(0)
}
uniqueAlerts := map[string]bool{}
@@ -113,7 +113,7 @@ func PullFromAlertmanager() {
ag.Alerts = []models.Alert{}
for _, alert := range alerts {
ag.Alerts = append(ag.Alerts, alert)
metricAlerts.With(prometheus.Labels{"status": alert.Status}).Inc()
metricAlerts.With(prometheus.Labels{"state": alert.State}).Inc()
}
for _, hint := range transform.BuildAutocomplete(ag.Alerts) {

View File

@@ -135,13 +135,13 @@ func alerts(c *gin.Context) {
var matches int
for _, ag := range store.Store.Alerts {
agCopy := models.AlertGroup{
ID: ag.ID,
Labels: ag.Labels,
Alerts: []models.Alert{},
StatusCount: map[string]int{},
ID: ag.ID,
Labels: ag.Labels,
Alerts: []models.Alert{},
StateCount: map[string]int{},
}
for _, s := range models.AlertStateList {
agCopy.StatusCount[s] = 0
agCopy.StateCount[s] = 0
}
h := sha1.New()
@@ -173,9 +173,9 @@ func alerts(c *gin.Context) {
}
}
countLabel(counters, "@status", alert.Status)
countLabel(counters, "@state", alert.State)
agCopy.StatusCount[alert.Status]++
agCopy.StateCount[alert.State]++
for key, value := range alert.Labels {
if keyMap, foundKey := store.Store.Colors[key]; foundKey {

View File

@@ -183,8 +183,8 @@ func TestValidateAllAlerts(t *testing.T) {
json.Unmarshal(resp.Body.Bytes(), &ur)
for _, ag := range ur.AlertGroups {
for _, a := range ag.Alerts {
if !stringInSlice(models.AlertStateList, a.Status) {
t.Errorf("Invalid alert status '%s', not in %v", a.Status, models.AlertStateList)
if !stringInSlice(models.AlertStateList, a.State) {
t.Errorf("Invalid alert status '%s', not in %v", a.State, models.AlertStateList)
}
if a.InhibitedBy == nil {
t.Errorf("InhibitedBy is nil, %v", a)
@@ -286,10 +286,10 @@ var acTests = []acTestCase{
"@silence_author!~john@example.com",
"@silence_author=john@example.com",
"@silence_author=~john@example.com",
"@status!=active",
"@status!=suppressed",
"@status=active",
"@status=suppressed",
"@state!=active",
"@state!=suppressed",
"@state=active",
"@state=suppressed",
},
},
acTestCase{