script/fmt now runs golines -m 77 after gofmt, repeating golines until it changes nothing, since one pass can leave a line the next splits. script/fmt-check fails when either would change a file. script/bootstrap installs golines v0.13.0 with go install, pinned to its commit, and checks the installed version with go version -m. The tree is reformatted. The longer lines this makes are fixed by hand: nolint directives moved onto their own line above the statement, one string split, and 20 functions over funlen's 80 lines shortened or split, RunWAF and limitPercentages among them. Model: opus-5-5
This commit is contained in:
1 parent
63e58e326b
commit
7f8a59de04
118 files changed
+9447
-2670
No files matched your search
+194
-63
@@ -111,8 +111,12 @@ func (o *output) lineBeforeExit(
|
||||
|
||||
select {
|
||||
case status := <-exited:
|
||||
t.Fatalf("exit status %d while waiting for a line with msg %q; output:\n%s",
|
||||
status, msg, o.text())
|
||||
t.Fatalf(
|
||||
"exit status %d while waiting for a line with msg %q; output:\n%s",
|
||||
status,
|
||||
msg,
|
||||
o.text(),
|
||||
)
|
||||
case <-time.After(pollInterval):
|
||||
}
|
||||
}
|
||||
@@ -227,7 +231,11 @@ func TestShortTokenStopsTheStartUnshown(t *testing.T) {
|
||||
func TestAddressInUseStopsTheStart(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
taken, err := (&net.ListenConfig{}).Listen(t.Context(), "tcp", localhost+":0")
|
||||
taken, err := (&net.ListenConfig{}).Listen(
|
||||
t.Context(),
|
||||
"tcp",
|
||||
localhost+":0",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("listen: %v", err)
|
||||
}
|
||||
@@ -325,7 +333,11 @@ func TestLogLevelHoldsBackTheLessSevereProcessLines(t *testing.T) {
|
||||
select {
|
||||
case status := <-exited:
|
||||
if status != 0 {
|
||||
t.Fatalf("exit status %d, want 0; output:\n%s", status, out.text())
|
||||
t.Fatalf(
|
||||
"exit status %d, want 0; output:\n%s",
|
||||
status,
|
||||
out.text(),
|
||||
)
|
||||
}
|
||||
case <-time.After(waitLimit):
|
||||
t.Fatal("still running after being told to stop")
|
||||
@@ -479,7 +491,14 @@ func TestBanAddedAndLiftedByEditingBansJSON(t *testing.T) {
|
||||
runUntilStopped(t, env, func(url string) {
|
||||
path := filepath.Join(dir, "bans.json")
|
||||
|
||||
saveUntilAnswered(t, path, oneBan, url, "203.0.113.9", http.StatusForbidden)
|
||||
saveUntilAnswered(
|
||||
t,
|
||||
path,
|
||||
oneBan,
|
||||
url,
|
||||
"203.0.113.9",
|
||||
http.StatusForbidden,
|
||||
)
|
||||
wantStatus(t, url, "198.51.100.7", http.StatusOK)
|
||||
saveUntilAnswered(t, path, noBan, url, "203.0.113.9", http.StatusOK)
|
||||
})
|
||||
@@ -568,12 +587,20 @@ func TestRuleFileThatDoesNotParseStopsTheStart(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "00-default.rules")
|
||||
|
||||
err := os.WriteFile(path, []byte("# probes\nenv-file path bann ^/\\.env$\n"), 0o600)
|
||||
err := os.WriteFile(
|
||||
path,
|
||||
[]byte("# probes\nenv-file path bann ^/\\.env$\n"),
|
||||
0o600,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("write the rule file: %v", err)
|
||||
}
|
||||
|
||||
wantRulesRefused(t, dir, path+`, line 2: the action "bann" is not log, block or ban`)
|
||||
wantRulesRefused(
|
||||
t,
|
||||
dir,
|
||||
path+`, line 2: the action "bann" is not log, block or ban`,
|
||||
)
|
||||
}
|
||||
|
||||
func TestRulesDirThatDoesNotExistStopsTheStart(t *testing.T) {
|
||||
@@ -585,7 +612,9 @@ func TestRulesDirThatDoesNotExistStopsTheStart(t *testing.T) {
|
||||
": no such file or directory")
|
||||
}
|
||||
|
||||
func TestCoreRuleSetExclusionsFileThatCannotBeReadStopsTheStart(t *testing.T) {
|
||||
func TestCoreRuleSetExclusionsFileThatCannotBeReadStopsTheStart(
|
||||
t *testing.T,
|
||||
) {
|
||||
t.Parallel()
|
||||
|
||||
path := filepath.Join(t.TempDir(), "crs-exclusions.conf")
|
||||
@@ -686,23 +715,38 @@ func TestLookupDatabaseReplacedWhileRunningTakesEffect(t *testing.T) {
|
||||
}
|
||||
|
||||
// One that cannot be read leaves the file read before in use.
|
||||
err := os.WriteFile(replacement, []byte("not a lookup database\n"), 0o600)
|
||||
err := os.WriteFile(
|
||||
replacement,
|
||||
[]byte("not a lookup database\n"),
|
||||
0o600,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("write %s: %v", replacement, err)
|
||||
}
|
||||
|
||||
rename(t, replacement, path)
|
||||
|
||||
metrics := metricsWith(t, url+"_sww/metrics", token,
|
||||
`sww_lookup_database_read_failures_total{instance="fsn1app1/blog"} 1`)
|
||||
lastRead = seriesValue(t, metrics,
|
||||
`sww_lookup_database_last_read_timestamp_seconds{instance="fsn1app1/blog"}`)
|
||||
metrics := metricsWith(
|
||||
t,
|
||||
url+"_sww/metrics",
|
||||
token,
|
||||
`sww_lookup_database_read_failures_total{instance="fsn1app1/blog"} 1`,
|
||||
)
|
||||
lastRead = seriesValue(
|
||||
t,
|
||||
metrics,
|
||||
`sww_lookup_database_last_read_timestamp_seconds{instance="fsn1app1/blog"}`,
|
||||
)
|
||||
|
||||
wantStatus(t, url, placed, http.StatusOK)
|
||||
})
|
||||
|
||||
if lastRead < float64(began.Unix()) || lastRead > float64(time.Now().Unix()) {
|
||||
t.Errorf("the lookup database was last read at %v, want a time in the test", lastRead)
|
||||
if lastRead < float64(began.Unix()) ||
|
||||
lastRead > float64(time.Now().Unix()) {
|
||||
t.Errorf(
|
||||
"the lookup database was last read at %v, want a time in the test",
|
||||
lastRead,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -776,8 +820,8 @@ func TestBlocklistTriesAndCopiesKeptInListsJSONAcrossRestarts(t *testing.T) {
|
||||
})
|
||||
wantDeniedByList(t, out.line(t, "action", "client_denied"), dropURL)
|
||||
|
||||
if fetches := torFetches.Load(); fetches != 1 {
|
||||
t.Errorf("tor.txt fetched %d times, want once, before the restart", fetches)
|
||||
if n := torFetches.Load(); n != 1 {
|
||||
t.Errorf("tor.txt fetched %d times before the restart, want 1", n)
|
||||
}
|
||||
|
||||
// After another restart, with the server failing, the copy of drop.txt
|
||||
@@ -792,10 +836,10 @@ func TestBlocklistTriesAndCopiesKeptInListsJSONAcrossRestarts(t *testing.T) {
|
||||
|
||||
path := filepath.Join(cache, "lists.json")
|
||||
|
||||
kept, err := os.ReadFile(path) //nolint:gosec // a file in the test's directory
|
||||
//nolint:gosec // a file in the test's directory
|
||||
kept, err := os.ReadFile(path)
|
||||
if err != nil || !strings.Contains(string(kept), `"`+copyright+`"`) {
|
||||
t.Errorf("lists.json holds\n%s\nwant the copy with %q (%v)", kept, copyright,
|
||||
err)
|
||||
t.Errorf("lists.json holds\n%s\nwant %q (%v)", kept, copyright, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -815,9 +859,12 @@ func TestCrowdSecDecisionListKeptInListsJSONAcrossARestart(t *testing.T) {
|
||||
case down.Load():
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
default:
|
||||
_, _ = io.WriteString(w, `[{"duration": "4h0m0s", "origin": "crowdsec", `+
|
||||
`"scenario": "crowdsecurity/http-probing", "scope": "Range", `+
|
||||
`"type": "ban", "value": "203.0.113.0/24"}]`)
|
||||
_, _ = io.WriteString(
|
||||
w,
|
||||
`[{"duration": "4h0m0s", "origin": "crowdsec", `+
|
||||
`"scenario": "crowdsecurity/http-probing", "scope": "Range", `+
|
||||
`"type": "ban", "value": "203.0.113.0/24"}]`,
|
||||
)
|
||||
}
|
||||
}))
|
||||
t.Cleanup(engine.Close)
|
||||
@@ -842,7 +889,11 @@ func TestCrowdSecDecisionListKeptInListsJSONAcrossARestart(t *testing.T) {
|
||||
ban := onlyBan(t, dir)
|
||||
if ban["netblock"] != placed+"/32" || ban["cause"] != "crowdsec" ||
|
||||
ban["reason"] != "CrowdSec's decision for crowdsecurity/http-probing" {
|
||||
t.Errorf("bans.json holds %v, want the ban for crowdsec on %s", ban, placed)
|
||||
t.Errorf(
|
||||
"bans.json holds %v, want the ban for crowdsec on %s",
|
||||
ban,
|
||||
placed,
|
||||
)
|
||||
}
|
||||
|
||||
// Restarted with the engine down, the copy kept in lists.json bans
|
||||
@@ -871,7 +922,10 @@ func TestCrowdSecDecisionListKeptInListsJSONAcrossARestart(t *testing.T) {
|
||||
}
|
||||
|
||||
if all := strings.Join(shown, "\n"); strings.Contains(all, bouncerKey) {
|
||||
t.Errorf("the key is shown in the output or the state and cache files:\n%s", all)
|
||||
t.Errorf(
|
||||
"the key is shown in the output or the state and cache files:\n%s",
|
||||
all,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -883,7 +937,11 @@ func wantDeniedByList(t *testing.T, line map[string]any, listURL string) {
|
||||
reputation, _ := line["reputation"].([]any)
|
||||
if line["action"] != "client_denied" || len(reputation) != 1 ||
|
||||
reputation[0] != listURL {
|
||||
t.Errorf("request log line %v, want one denied for %s", line, listURL)
|
||||
t.Errorf(
|
||||
"request log line %v, want one denied for %s",
|
||||
line,
|
||||
listURL,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -918,7 +976,11 @@ func TestLookupDatabaseThatCannotBeReadStopsTheStart(t *testing.T) {
|
||||
func TestEveryLineIsAlsoSentToTheRemoteLogEndpoint(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
endpoint, err := (&net.ListenConfig{}).Listen(t.Context(), "tcp", localhost+":0")
|
||||
endpoint, err := (&net.ListenConfig{}).Listen(
|
||||
t.Context(),
|
||||
"tcp",
|
||||
localhost+":0",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("listen: %v", err)
|
||||
}
|
||||
@@ -973,7 +1035,11 @@ func TestStalledRemoteLogEndpointHoldsUpNoRequest(t *testing.T) {
|
||||
|
||||
// The endpoint takes connections and never answers, so the TLS
|
||||
// handshake of each waits on it, and no line is ever sent.
|
||||
endpoint, err := (&net.ListenConfig{}).Listen(t.Context(), "tcp", localhost+":0")
|
||||
endpoint, err := (&net.ListenConfig{}).Listen(
|
||||
t.Context(),
|
||||
"tcp",
|
||||
localhost+":0",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("listen: %v", err)
|
||||
}
|
||||
@@ -1009,7 +1075,8 @@ func TestStalledRemoteLogEndpointHoldsUpNoRequest(t *testing.T) {
|
||||
|
||||
const dropped = "\nsww_remote_log_lines_dropped_total" +
|
||||
`{instance="fsn1app1/blog"} `
|
||||
if strings.Contains(metrics, dropped+"0\n") || !strings.Contains(metrics, dropped) {
|
||||
if strings.Contains(metrics, dropped+"0\n") ||
|
||||
!strings.Contains(metrics, dropped) {
|
||||
t.Errorf("no line dropped in the metrics:\n%s", metrics)
|
||||
}
|
||||
|
||||
@@ -1035,7 +1102,11 @@ func TestStalledRemoteLogEndpointHoldsUpNoRequest(t *testing.T) {
|
||||
// too.
|
||||
line := out.line(t, "msg", "starting")
|
||||
if line["instance"] != instance {
|
||||
t.Errorf("start logged with instance %v, want %s", line["instance"], instance)
|
||||
t.Errorf(
|
||||
"start logged with instance %v, want %s",
|
||||
line["instance"],
|
||||
instance,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1066,10 +1137,14 @@ func TestBanIsAlertedAndAnAlertNotSentIsKeptAcrossARestart(t *testing.T) {
|
||||
wantRefused(t, url+".env")
|
||||
|
||||
post := webhook.waitFor(t, "ban", true)
|
||||
if post.alert["client"] != localhost || post.alert["netblock"] != localhost+"/32" ||
|
||||
if post.alert["client"] != localhost ||
|
||||
post.alert["netblock"] != localhost+"/32" ||
|
||||
post.authorization != "Bearer "+adminSecret {
|
||||
t.Errorf("the webhook was sent %v, with Authorization %q", post.alert,
|
||||
post.authorization)
|
||||
t.Errorf(
|
||||
"the webhook was sent %v, with Authorization %q",
|
||||
post.alert,
|
||||
post.authorization,
|
||||
)
|
||||
}
|
||||
|
||||
// The webhook fails, so the alert for the ban made permanent by the
|
||||
@@ -1081,24 +1156,7 @@ func TestBanIsAlertedAndAnAlertNotSentIsKeptAcrossARestart(t *testing.T) {
|
||||
|
||||
// alerts.json keeps it as sww stops, and once started again,
|
||||
// sww sends it.
|
||||
var file struct {
|
||||
Waiting map[string][]struct {
|
||||
Event string `json:"event"`
|
||||
} `json:"waiting"`
|
||||
}
|
||||
|
||||
path := filepath.Join(dir, "alerts.json")
|
||||
|
||||
data, err := os.ReadFile(path) //nolint:gosec // a file in the test's directory
|
||||
if err == nil {
|
||||
err = json.Unmarshal(data, &file)
|
||||
}
|
||||
|
||||
waiting := file.Waiting["webhook"]
|
||||
if err != nil || len(waiting) != 1 || waiting[0].Event != "permanent_ban" {
|
||||
t.Fatalf("alerts.json holds %s (%v), want the permanent_ban alert waiting for "+
|
||||
"the webhook", data, err)
|
||||
}
|
||||
wantPermanentBanAlertWaiting(t, dir)
|
||||
|
||||
// It counts the alert sent in the metrics, read here from a client the
|
||||
// ban does not cover.
|
||||
@@ -1130,6 +1188,37 @@ func TestBanIsAlertedAndAnAlertNotSentIsKeptAcrossARestart(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
// wantPermanentBanAlertWaiting checks that alerts.json in dir holds one
|
||||
// alert waiting for the webhook, the permanent_ban alert.
|
||||
func wantPermanentBanAlertWaiting(t *testing.T, dir string) {
|
||||
t.Helper()
|
||||
|
||||
var file struct {
|
||||
Waiting map[string][]struct {
|
||||
Event string `json:"event"`
|
||||
} `json:"waiting"`
|
||||
}
|
||||
|
||||
path := filepath.Join(dir, "alerts.json")
|
||||
|
||||
//nolint:gosec // a file in the test's directory
|
||||
data, err := os.ReadFile(path)
|
||||
if err == nil {
|
||||
err = json.Unmarshal(data, &file)
|
||||
}
|
||||
|
||||
waiting := file.Waiting["webhook"]
|
||||
if err != nil || len(waiting) != 1 ||
|
||||
waiting[0].Event != "permanent_ban" {
|
||||
t.Fatalf(
|
||||
"alerts.json holds %s (%v), want the permanent_ban alert waiting for "+
|
||||
"the webhook",
|
||||
data,
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBanIsAlertedToSlackAndNtfy(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -1167,7 +1256,8 @@ func TestBanIsAlertedToSlackAndNtfy(t *testing.T) {
|
||||
slackPost := slack.firstPost(t)
|
||||
err := json.Unmarshal([]byte(slackPost.body), &message)
|
||||
|
||||
if err != nil || !strings.HasPrefix(message.Text, "*fsn1app1/blog: ban*\n") ||
|
||||
if err != nil ||
|
||||
!strings.HasPrefix(message.Text, "*fsn1app1/blog: ban*\n") ||
|
||||
!strings.Contains(message.Text, "\nclient: "+client+"\n") {
|
||||
t.Errorf("Slack was sent %s", slackPost.body)
|
||||
}
|
||||
@@ -1202,14 +1292,22 @@ func TestStateFileThatDoesNotParseStopsTheStart(t *testing.T) {
|
||||
|
||||
dir := t.TempDir()
|
||||
|
||||
err := os.WriteFile(filepath.Join(dir, "bans.json"), []byte("{\n"), 0o600)
|
||||
err := os.WriteFile(
|
||||
filepath.Join(dir, "bans.json"),
|
||||
[]byte("{\n"),
|
||||
0o600,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("write bans.json: %v", err)
|
||||
}
|
||||
|
||||
// The file ends at the newline that is the second byte of its first
|
||||
// line.
|
||||
wantStartRefused(t, dir, filepath.Join(dir, "bans.json")+", line 1, column 2: ")
|
||||
wantStartRefused(
|
||||
t,
|
||||
dir,
|
||||
filepath.Join(dir, "bans.json")+", line 1, column 2: ",
|
||||
)
|
||||
}
|
||||
|
||||
func TestUnwritableStateDirStopsTheStart(t *testing.T) {
|
||||
@@ -1264,7 +1362,11 @@ func wantStartRefused(t *testing.T, dir, want string) {
|
||||
message, _ := line["error"].(string)
|
||||
|
||||
if !strings.HasPrefix(message, want) {
|
||||
t.Errorf("start refused with %q, want an error starting %q", message, want)
|
||||
t.Errorf(
|
||||
"start refused with %q, want an error starting %q",
|
||||
message,
|
||||
want,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1329,7 +1431,11 @@ func runUntilStopped(
|
||||
select {
|
||||
case status := <-exited:
|
||||
if status != 0 {
|
||||
t.Fatalf("exit status %d, want 0; output:\n%s", status, out.text())
|
||||
t.Fatalf(
|
||||
"exit status %d, want 0; output:\n%s",
|
||||
status,
|
||||
out.text(),
|
||||
)
|
||||
}
|
||||
case <-time.After(waitLimit):
|
||||
t.Fatal("still running after being told to stop")
|
||||
@@ -1371,7 +1477,12 @@ func wantStartingLine(t *testing.T, line map[string]any, dir string) {
|
||||
|
||||
for name, value := range want {
|
||||
if settings[name] != value {
|
||||
t.Errorf("starting line gives %s=%v, want %v", name, settings[name], value)
|
||||
t.Errorf(
|
||||
"starting line gives %s=%v, want %v",
|
||||
name,
|
||||
settings[name],
|
||||
value,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1411,7 +1522,11 @@ func messages(t *testing.T, received string) []string {
|
||||
|
||||
_, message, ok := strings.Cut(record, header)
|
||||
if !ok || !strings.HasPrefix(record, "<134>1 ") {
|
||||
t.Fatalf("record %q, want priority <134> and header %q", record, header)
|
||||
t.Fatalf(
|
||||
"record %q, want priority <134> and header %q",
|
||||
record,
|
||||
header,
|
||||
)
|
||||
}
|
||||
|
||||
found = append(found, message+"\n")
|
||||
@@ -1476,7 +1591,10 @@ func seriesValue(t *testing.T, metrics, series string) float64 {
|
||||
t.Helper()
|
||||
|
||||
for line := range strings.Lines(metrics) {
|
||||
value, found := strings.CutPrefix(strings.TrimSpace(line), series+" ")
|
||||
value, found := strings.CutPrefix(
|
||||
strings.TrimSpace(line),
|
||||
series+" ",
|
||||
)
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
@@ -1510,7 +1628,11 @@ func writeLookupDatabase(t *testing.T, path, country string) {
|
||||
t.Helper()
|
||||
|
||||
lookuptest.Write(t, path, map[string]lookuptest.Network{
|
||||
placed + "/32": {ASN: "AS64496", ASName: "Example Net", Country: country},
|
||||
placed + "/32": {
|
||||
ASN: "AS64496",
|
||||
ASName: "Example Net",
|
||||
Country: country,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1548,7 +1670,8 @@ func onlyBan(t *testing.T, dir string) map[string]any {
|
||||
|
||||
path := filepath.Join(dir, "bans.json")
|
||||
|
||||
data, err := os.ReadFile(path) //nolint:gosec // a file in the test's directory
|
||||
//nolint:gosec // a file in the test's directory
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("read bans.json: %v", err)
|
||||
}
|
||||
@@ -1590,7 +1713,11 @@ func wantStatus(t *testing.T, url, from string, status int) {
|
||||
// request, since sww may not watch its directory yet when it is
|
||||
// first written. It waits as long as that takes, so that a slow test
|
||||
// process cannot fail the test.
|
||||
func saveUntilAnswered(t *testing.T, path, content, url, from string, status int) {
|
||||
func saveUntilAnswered(
|
||||
t *testing.T,
|
||||
path, content, url, from string,
|
||||
status int,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
for {
|
||||
@@ -1722,7 +1849,11 @@ func startWebhook(t *testing.T) *webhook {
|
||||
// waitFor waits until the webhook has been sent an alert for event that
|
||||
// it took, or, unless answered, failed, and returns it. It waits as long
|
||||
// as that takes, so that a slow test process cannot fail the test.
|
||||
func (w *webhook) waitFor(t *testing.T, event string, answered bool) webhookPost {
|
||||
func (w *webhook) waitFor(
|
||||
t *testing.T,
|
||||
event string,
|
||||
answered bool,
|
||||
) webhookPost {
|
||||
t.Helper()
|
||||
|
||||
for {
|
||||
|
||||
Reference in new issue
Block a user