1
0
mirror of https://github.com/TwiN/gatus.git synced 2026-02-09 05:04:17 +00:00

refactor: Simplify and modernize loops (#1522)

* refactor: Simplify loops

* refactor: Modernize loops using range over int

---------

Co-authored-by: TwiN <twin@linux.com>
This commit is contained in:
PythonGermany
2026-02-09 01:08:59 +01:00
committed by GitHub
parent e5b4e0d381
commit f09d959c97
17 changed files with 45 additions and 78 deletions

View File

@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"io"
"maps"
"net/http"
"strconv"
"strings"
@@ -170,9 +171,7 @@ func (provider *AlertProvider) buildRequestBody(cfg *Config, ep *endpoint.Endpoi
// Merge metadata: cfg.Metadata + ep.ExtraLabels (if present)
mergedMetadata := map[string]interface{}{}
// Copy cfg.Metadata
for k, v := range cfg.Metadata {
mergedMetadata[k] = v
}
maps.Copy(mergedMetadata, cfg.Metadata)
// Add extra labels from endpoint (if present)
if ep.ExtraLabels != nil && len(ep.ExtraLabels) > 0 {
for k, v := range ep.ExtraLabels {

View File

@@ -299,7 +299,7 @@ func getBadgeColorFromResponseTime(responseTime int, key string, cfg *config.Con
thresholds = endpoint.UIConfig.Badge.ResponseTime.Thresholds
}
// the threshold config requires 5 values, so we can be sure it's set here
for i := 0; i < 5; i++ {
for i := range 5 {
if responseTime <= thresholds[i] {
return badgeColors[i]
}

View File

@@ -6,6 +6,7 @@ import (
"io/fs"
"os"
"path/filepath"
"slices"
"sort"
"strings"
"time"
@@ -136,7 +137,7 @@ func (config *Config) GetUniqueExtraMetricLabels() []string {
continue
}
for label := range ep.ExtraLabels {
if contains(labels, label) {
if slices.Contains(labels, label) {
continue
}
labels = append(labels, label)

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"slices"
"testing"
"time"
@@ -2052,7 +2053,7 @@ func TestConfig_GetUniqueExtraMetricLabels(t *testing.T) {
t.Errorf("expected %d labels, got %d", len(tt.expected), len(labels))
}
for _, label := range tt.expected {
if !contains(labels, label) {
if !slices.Contains(labels, label) {
t.Errorf("expected label %s to be present", label)
}
}

View File

@@ -216,7 +216,7 @@ func sanitizeAndResolveNumericalWithContext(list []string, result *Result, conte
func prettifyNumericalParameters(parameters []string, resolvedParameters []int64, operator string) string {
resolvedStrings := make([]string, 2)
for i := 0; i < 2; i++ {
for i := range 2 {
// Check if the parameter is a certificate or domain expiration placeholder
if parameters[i] == CertificateExpirationPlaceholder || parameters[i] == DomainExpirationPlaceholder {
// Format as duration string (convert milliseconds back to duration)

View File

@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"io"
"maps"
"math/rand"
"net"
"net/http"
@@ -489,9 +490,7 @@ func (e *Endpoint) call(result *Result) {
} else if endpointType == TypeWS {
wsHeaders := map[string]string{}
if e.Headers != nil {
for k, v := range e.Headers {
wsHeaders[k] = v
}
maps.Copy(wsHeaders, e.Headers)
}
if !hasHeader(wsHeaders, UserAgentHeader) {
wsHeaders[UserAgentHeader] = GatusUserAgent

View File

@@ -1,6 +1,7 @@
package endpoint
import (
"slices"
"time"
)
@@ -66,11 +67,7 @@ type Result struct {
// AddError adds an error to the result's list of errors.
// It also ensures that there are no duplicates.
func (r *Result) AddError(error string) {
for _, resultError := range r.Errors {
if resultError == error {
// If the error already exists, don't add it
return
}
if !slices.Contains(r.Errors, error) {
r.Errors = append(r.Errors, error+"")
}
r.Errors = append(r.Errors, error+"")
}

View File

@@ -340,9 +340,9 @@ func TestGontext_ConcurrentAccess(t *testing.T) {
done := make(chan bool, 10)
// Start 5 goroutines that read values
for i := 0; i < 5; i++ {
for i := range 5 {
go func(id int) {
for j := 0; j < 100; j++ {
for range 100 {
_, err := ctx.Get("counter")
if err != nil {
t.Errorf("Reader %d error: %v", id, err)
@@ -353,9 +353,9 @@ func TestGontext_ConcurrentAccess(t *testing.T) {
}
// Start 5 goroutines that write values
for i := 0; i < 5; i++ {
for i := range 5 {
go func(id int) {
for j := 0; j < 100; j++ {
for j := range 100 {
err := ctx.Set("counter", id*1000+j)
if err != nil {
t.Errorf("Writer %d error: %v", id, err)
@@ -366,7 +366,7 @@ func TestGontext_ConcurrentAccess(t *testing.T) {
}
// Wait for all goroutines to complete
for i := 0; i < 10; i++ {
for range 10 {
<-done
}
}

View File

@@ -3,6 +3,7 @@ package maintenance
import (
"errors"
"fmt"
"slices"
"strconv"
"strings"
"time"
@@ -70,13 +71,7 @@ func (c *Config) ValidateAndSetDefaults() error {
return nil
}
for _, day := range c.Every {
isDayValid := false
for _, longDayName := range longDayNames {
if day == longDayName {
isDayValid = true
break
}
}
isDayValid := slices.Contains(longDayNames, day)
if !isDayValid {
return errInvalidDayName
}
@@ -118,7 +113,7 @@ func (c *Config) IsUnderMaintenance() bool {
// Set to midnight prior to adding duration
dayWhereMaintenancePeriodWouldStart := time.Date(now.Year(), now.Month(), adjustedDate, 0, 0, 0, 0, now.Location())
hasMaintenanceEveryDay := len(c.Every) == 0
hasMaintenancePeriodScheduledToStartOnThatWeekday := c.hasDay(dayWhereMaintenancePeriodWouldStart.Weekday().String())
hasMaintenancePeriodScheduledToStartOnThatWeekday := slices.Contains(c.Every, dayWhereMaintenancePeriodWouldStart.Weekday().String())
if !hasMaintenanceEveryDay && !hasMaintenancePeriodScheduledToStartOnThatWeekday {
// The day when the maintenance period would start is not scheduled
// to have any maintenance, so we can just return false.
@@ -129,15 +124,6 @@ func (c *Config) IsUnderMaintenance() bool {
return now.After(startOfMaintenancePeriod) && now.Before(endOfMaintenancePeriod)
}
func (c *Config) hasDay(day string) bool {
for _, d := range c.Every {
if d == day {
return true
}
}
return false
}
func hhmmToDuration(s string) (time.Duration, error) {
if len(s) != 5 {
return 0, errInvalidMaintenanceStartFormat

View File

@@ -133,7 +133,7 @@ func (t *SSHTunnel) Dial(network, addr string) (net.Conn, error) {
const maxRetries = 3
const baseDelay = 500 * time.Millisecond
var lastErr error
for attempt := 0; attempt < maxRetries; attempt++ {
for attempt := range maxRetries {
if attempt > 0 {
// Exponential backoff: 500ms, 1s, 2s
delay := baseDelay << (attempt - 1)

View File

@@ -4,13 +4,3 @@ package config
func toPtr[T any](value T) *T {
return &value
}
// contains checks if a key exists in the slice
func contains[T comparable](slice []T, key T) bool {
for _, item := range slice {
if item == key {
return true
}
}
return false
}

View File

@@ -1,6 +1,7 @@
package memory
import (
"slices"
"sort"
"sync"
"time"
@@ -237,13 +238,7 @@ func (s *Store) InsertSuiteResult(su *suite.Suite, result *suite.Result) error {
func (s *Store) DeleteAllEndpointStatusesNotInKeys(keys []string) int {
var keysToDelete []string
for _, existingKey := range s.endpointCache.GetKeysByPattern("*", 0) {
shouldDelete := true
for _, k := range keys {
if existingKey == k {
shouldDelete = false
break
}
}
shouldDelete := !slices.Contains(keys, existingKey)
if shouldDelete {
keysToDelete = append(keysToDelete, existingKey)
}

View File

@@ -797,7 +797,7 @@ func TestSuiteResultOrdering(t *testing.T) {
baseTime := time.Now().Add(-5 * time.Hour)
timestamps := make([]time.Time, 5)
for i := 0; i < 5; i++ {
for i := range 5 {
timestamp := baseTime.Add(time.Duration(i) * time.Hour)
timestamps[i] = timestamp
result := &suite.Result{
@@ -878,7 +878,7 @@ func TestSuiteResultOrdering(t *testing.T) {
smallSuite := &suite.Suite{Name: "small-suite", Group: "test"}
// Insert 6 results, should keep only the newest 3
for i := 0; i < 6; i++ {
for i := range 6 {
result := &suite.Result{
Name: smallSuite.Name,
Group: smallSuite.Group,
@@ -925,7 +925,7 @@ func TestStore_ConcurrentAccess(t *testing.T) {
// Create endpoints for concurrent testing
endpoints := make([]*endpoint.Endpoint, numGoroutines)
for i := 0; i < numGoroutines; i++ {
for i := range numGoroutines {
endpoints[i] = &endpoint.Endpoint{
Name: "endpoint-" + string(rune('A'+i)),
Group: "concurrent",
@@ -934,12 +934,12 @@ func TestStore_ConcurrentAccess(t *testing.T) {
}
// Concurrently insert results for different endpoints
for i := 0; i < numGoroutines; i++ {
for i := range numGoroutines {
wg.Add(1)
go func(endpointIndex int) {
defer wg.Done()
ep := endpoints[endpointIndex]
for j := 0; j < resultsPerGoroutine; j++ {
for j := range resultsPerGoroutine {
result := &endpoint.Result{
Success: j%2 == 0,
Timestamp: time.Now().Add(time.Duration(j) * time.Minute),
@@ -978,7 +978,7 @@ func TestStore_ConcurrentAccess(t *testing.T) {
// Create suites for concurrent testing
suites := make([]*suite.Suite, numGoroutines)
for i := 0; i < numGoroutines; i++ {
for i := range numGoroutines {
suites[i] = &suite.Suite{
Name: "suite-" + string(rune('A'+i)),
Group: "concurrent",
@@ -986,12 +986,12 @@ func TestStore_ConcurrentAccess(t *testing.T) {
}
// Concurrently insert results for different suites
for i := 0; i < numGoroutines; i++ {
for i := range numGoroutines {
wg.Add(1)
go func(suiteIndex int) {
defer wg.Done()
su := suites[suiteIndex]
for j := 0; j < resultsPerGoroutine; j++ {
for j := range resultsPerGoroutine {
result := &suite.Result{
Name: su.Name,
Group: su.Group,
@@ -1036,7 +1036,7 @@ func TestStore_ConcurrentAccess(t *testing.T) {
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 5; i++ {
for i := range 5 {
result := &endpoint.Result{
Success: true,
Timestamp: time.Now(),
@@ -1050,7 +1050,7 @@ func TestStore_ConcurrentAccess(t *testing.T) {
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 5; i++ {
for i := range 5 {
result := &suite.Result{
Name: testSuite.Name,
Group: testSuite.Group,
@@ -1066,7 +1066,7 @@ func TestStore_ConcurrentAccess(t *testing.T) {
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 10; i++ {
for range 10 {
store.GetAllEndpointStatuses(&paging.EndpointStatusParams{})
store.GetAllSuiteStatuses(&paging.SuiteStatusParams{})
time.Sleep(1 * time.Millisecond)

View File

@@ -11,10 +11,10 @@ import (
func BenchmarkShallowCopyEndpointStatus(b *testing.B) {
ep := &testEndpoint
status := endpoint.NewStatus(ep.Group, ep.Name)
for i := 0; i < storage.DefaultMaximumNumberOfResults; i++ {
for range storage.DefaultMaximumNumberOfResults {
AddResult(status, &testSuccessfulResult, storage.DefaultMaximumNumberOfResults, storage.DefaultMaximumNumberOfEvents)
}
for n := 0; n < b.N; n++ {
for b.Loop() {
ShallowCopyEndpointStatus(status, paging.NewEndpointStatusParams().WithResults(1, 20))
}
b.ReportAllocs()

View File

@@ -13,7 +13,7 @@ import (
func TestAddResult(t *testing.T) {
ep := &endpoint.Endpoint{Name: "name", Group: "group"}
endpointStatus := endpoint.NewStatus(ep.Group, ep.Name)
for i := 0; i < (storage.DefaultMaximumNumberOfResults+storage.DefaultMaximumNumberOfEvents)*2; i++ {
for i := range (storage.DefaultMaximumNumberOfResults + storage.DefaultMaximumNumberOfEvents) * 2 {
AddResult(endpointStatus, &endpoint.Result{Success: i%2 == 0, Timestamp: time.Now()}, storage.DefaultMaximumNumberOfResults, storage.DefaultMaximumNumberOfEvents)
}
if len(endpointStatus.Results) != storage.DefaultMaximumNumberOfResults {
@@ -30,7 +30,7 @@ func TestShallowCopyEndpointStatus(t *testing.T) {
ep := &endpoint.Endpoint{Name: "name", Group: "group"}
endpointStatus := endpoint.NewStatus(ep.Group, ep.Name)
ts := time.Now().Add(-25 * time.Hour)
for i := 0; i < 25; i++ {
for i := range 25 {
AddResult(endpointStatus, &endpoint.Result{Success: i%2 == 0, Timestamp: ts}, storage.DefaultMaximumNumberOfResults, storage.DefaultMaximumNumberOfEvents)
ts = ts.Add(time.Hour)
}
@@ -74,9 +74,9 @@ func TestShallowCopySuiteStatus(t *testing.T) {
Key: testSuite.Key(),
Results: []*suite.Result{},
}
ts := time.Now().Add(-25 * time.Hour)
for i := 0; i < 25; i++ {
for i := range 25 {
result := &suite.Result{
Name: testSuite.Name,
Group: testSuite.Group,
@@ -169,4 +169,3 @@ func TestShallowCopySuiteStatus(t *testing.T) {
}
})
}

View File

@@ -900,7 +900,7 @@ func TestEventOrderingFix(t *testing.T) {
}
// Create many events over time
baseTime := time.Now().Add(-100 * time.Hour) // Start 100 hours ago
for i := 0; i < 50; i++ {
for i := range 50 {
result := &endpoint.Result{
Success: i%2 == 0, // Alternate between true/false to create events
Timestamp: baseTime.Add(time.Duration(i) * time.Hour),

View File

@@ -53,11 +53,11 @@ func BenchmarkStore_GetAllEndpointStatuses(b *testing.B) {
numberOfEndpoints := []int{10, 25, 50, 100}
for _, numberOfEndpointsToCreate := range numberOfEndpoints {
// Create endpoints and insert results
for i := 0; i < numberOfEndpointsToCreate; i++ {
for i := range numberOfEndpointsToCreate {
ep := testEndpoint
ep.Name = "endpoint" + strconv.Itoa(i)
// InsertEndpointResult 20 results for each endpoint
for j := 0; j < 20; j++ {
for range 20 {
scenario.Store.InsertEndpointResult(&ep, &testSuccessfulResult)
}
}
@@ -191,7 +191,7 @@ func BenchmarkStore_GetEndpointStatusByKey(b *testing.B) {
},
}
for _, scenario := range scenarios {
for i := 0; i < 50; i++ {
for range 50 {
scenario.Store.InsertEndpointResult(&testEndpoint, &testSuccessfulResult)
scenario.Store.InsertEndpointResult(&testEndpoint, &testUnsuccessfulResult)
}