From 610ee9bab0591964d8a7491e68599d3b7c9cf2b6 Mon Sep 17 00:00:00 2001 From: Julian Sommer <115516918+juliansommer@users.noreply.github.com> Date: Wed, 30 Sep 2026 11:44:17 +1000 Subject: [PATCH] chore: use slices.Sorted --- cmd/spinifex/cmd/admin_account_quota.go | 9 +++------ cmd/spinifex/cmd/admin_kv.go | 7 ++----- cmd/spinifex/cmd/admin_kv_compare.go | 7 ++----- internal/awsmodel/model.go | 7 +------ internal/awsmodel/page.go | 10 +++------- spinifex/cloud/oci/fake.go | 14 ++++---------- spinifex/daemon/daemon.go | 6 +----- .../gateway/conditionkeys_completeness_test.go | 7 +++---- spinifex/gateway/ec2.go | 1 + spinifex/gateway/ec2_dryrun_test.go | 7 ++----- spinifex/gateway/ec2_emptyresult_test.go | 4 ++++ spinifex/gateway/ecrapi/tags.go | 9 +++------ spinifex/handlers/ec2/instance/service_impl.go | 10 ++-------- spinifex/handlers/eks/addon_catalog.go | 7 ++----- spinifex/loadgen/loadgen.go | 9 +++------ spinifex/loadgen/ops.go | 9 ++------- spinifex/resource/resource_test.go | 8 ++------ spinifex/services/awsgw/awsgw.go | 7 +++---- spinifex/services/northstar/bootstrap.go | 10 +++------- spinifex/systemd/reconcile.go | 9 ++------- spinifex/utils/nats_trace.go | 8 +++----- spinifex/vm/manager.go | 7 ++----- spinifex/vm/manager_deps_test.go | 13 +++---------- spinifex/vm/mock/mock.go | 13 +++---------- tests/bench/ebsctl/compare.go | 9 +++------ tests/e2e/ddil/scenarios/coverage_drift_test.go | 10 +++------- tests/e2e/harness/account.go | 10 +++------- tests/e2e/harness/guest_data.go | 7 +++---- tests/e2e/kvquorum/node_loss_test.go | 8 +++----- tests/e2e/manifest-lint/lint.go | 8 +++----- tests/e2e/manifest-lint/subjects.go | 9 +++------ tests/e2e/single/guestchurn_test.go | 8 +++----- tests/integration/conformance.go | 8 +++----- tests/integration/conformance_policy.go | 10 +++------- 34 files changed, 89 insertions(+), 196 deletions(-) diff --git a/cmd/spinifex/cmd/admin_account_quota.go b/cmd/spinifex/cmd/admin_account_quota.go index 21b816caf..0d1f8f923 100644 --- a/cmd/spinifex/cmd/admin_account_quota.go +++ b/cmd/spinifex/cmd/admin_account_quota.go @@ -3,7 +3,8 @@ package cmd import ( "context" "fmt" - "sort" + "maps" + "slices" "strconv" "github.com/mulgadc/spinifex/spinifex/gateway" @@ -166,11 +167,7 @@ func printAccountQuota(resp *gateway.AccountQuotaResponse) { fmt.Printf("%-16s %10s %s\n", "DIMENSION", "LIMIT", "SOURCE") fmt.Printf("%-16s %10s %s\n", "---------", "-----", "------") - names := make([]string, 0, len(resp.Limits)) - for name := range resp.Limits { - names = append(names, name) - } - sort.Strings(names) + names := slices.Sorted(maps.Keys(resp.Limits)) for _, name := range names { limit := strconv.Itoa(resp.Limits[name]) if resp.Limits[name] == handlers_quota.Unlimited { diff --git a/cmd/spinifex/cmd/admin_kv.go b/cmd/spinifex/cmd/admin_kv.go index 3dfb5c4a7..bc5baf73c 100644 --- a/cmd/spinifex/cmd/admin_kv.go +++ b/cmd/spinifex/cmd/admin_kv.go @@ -11,6 +11,7 @@ import ( "fmt" "io" "io/fs" + "maps" "os" "path/filepath" "slices" @@ -420,11 +421,7 @@ func hashStoredMsg(m *jetstream.RawStreamMsg) string { field([]byte(m.Subject)) binary.BigEndian.PutUint64(n[:], uint64(m.Time.UnixNano())) h.Write(n[:]) - keys := make([]string, 0, len(m.Header)) - for k := range m.Header { - keys = append(keys, k) - } - sort.Strings(keys) + keys := slices.Sorted(maps.Keys(m.Header)) for _, k := range keys { field([]byte(k)) for _, v := range m.Header[k] { diff --git a/cmd/spinifex/cmd/admin_kv_compare.go b/cmd/spinifex/cmd/admin_kv_compare.go index 876776215..db47f8e3f 100644 --- a/cmd/spinifex/cmd/admin_kv_compare.go +++ b/cmd/spinifex/cmd/admin_kv_compare.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "maps" "os" "slices" "sort" @@ -153,11 +154,7 @@ func compareNodeDigests(nodes []nodeDigest) (kvCompareResult, error) { byName[d.Name] = append(byName[d.Name], v) } } - names := make([]string, 0, len(byName)) - for name := range byName { - names = append(names, name) - } - sort.Strings(names) + names := slices.Sorted(maps.Keys(byName)) var res kvCompareResult for _, name := range names { diff --git a/internal/awsmodel/model.go b/internal/awsmodel/model.go index 348d10f84..81adc8242 100644 --- a/internal/awsmodel/model.go +++ b/internal/awsmodel/model.go @@ -131,12 +131,7 @@ var modelCache sync.Map // Services returns the supported service identifiers in stable order. func Services() []Service { - services := make([]Service, 0, len(modelFiles)) - for service := range modelFiles { - services = append(services, service) - } - slices.Sort(services) - return services + return slices.Sorted(maps.Keys(modelFiles)) } // Load parses and indexes the embedded model for service. Each service is diff --git a/internal/awsmodel/page.go b/internal/awsmodel/page.go index 299beade9..7644443af 100644 --- a/internal/awsmodel/page.go +++ b/internal/awsmodel/page.go @@ -4,8 +4,9 @@ import ( "bytes" "encoding/json" "fmt" + "maps" "regexp" - "sort" + "slices" "strconv" "strings" "unicode/utf8" @@ -253,12 +254,7 @@ func validateFrontmatter(owner string, page PageMetadata) error { // key rather than by first use, so adding an operation cannot renumber a note // that is already published. func noteOrder(notes map[string]string) []string { - keys := make([]string, 0, len(notes)) - for key := range notes { - keys = append(keys, key) - } - sort.Strings(keys) - return keys + return slices.Sorted(maps.Keys(notes)) } // checkNotes rejects a note nothing references and a reference to a note that diff --git a/spinifex/cloud/oci/fake.go b/spinifex/cloud/oci/fake.go index ddd790120..efefc15b9 100644 --- a/spinifex/cloud/oci/fake.go +++ b/spinifex/cloud/oci/fake.go @@ -3,7 +3,9 @@ package oci import ( "context" "fmt" + "maps" "net/netip" + "slices" "sync" ) @@ -71,22 +73,14 @@ func (f *Fake) SeedPublicIP(p PublicIP) { func (f *Fake) PrivateIPs() []PrivateIP { f.mu.Lock() defer f.mu.Unlock() - out := make([]PrivateIP, 0, len(f.privateIPs)) - for _, p := range f.privateIPs { - out = append(out, p) - } - return out + return slices.Collect(maps.Values(f.privateIPs)) } // PublicIPs returns a snapshot. func (f *Fake) PublicIPs() []PublicIP { f.mu.Lock() defer f.mu.Unlock() - out := make([]PublicIP, 0, len(f.publicIPs)) - for _, p := range f.publicIPs { - out = append(out, p) - } - return out + return slices.Collect(maps.Values(f.publicIPs)) } // FailOp stages err for the next call to op. Locked, so a test may stage one diff --git a/spinifex/daemon/daemon.go b/spinifex/daemon/daemon.go index 39d03987e..5794427b6 100644 --- a/spinifex/daemon/daemon.go +++ b/spinifex/daemon/daemon.go @@ -2371,11 +2371,7 @@ func (d *Daemon) nodeRunningVMs() ([]*vm.VM, error) { if err != nil { return nil, err } - vms := make([]*vm.VM, 0, len(running)) - for _, v := range running { - vms = append(vms, v) - } - return vms, nil + return slices.Collect(maps.Values(running)), nil } // connectNATS connects to NATS with infinite retry (cap 60s backoff). Tests diff --git a/spinifex/gateway/conditionkeys_completeness_test.go b/spinifex/gateway/conditionkeys_completeness_test.go index 8e65fb99f..0c61d85ef 100644 --- a/spinifex/gateway/conditionkeys_completeness_test.go +++ b/spinifex/gateway/conditionkeys_completeness_test.go @@ -7,8 +7,10 @@ package gateway import ( "crypto/tls" "encoding/json" + "maps" "net/http" "net/http/httptest" + "slices" "testing" "github.com/mulgadc/bluebottle/pkg/iampolicy" @@ -117,10 +119,7 @@ func TestRequestConditionKeys_EveryEmittedKeyIsUsableInAPolicy(t *testing.T) { // The door's key set as a whole, so a key gained or lost here is a deliberate // change made at both doors rather than a drift between them. func TestRequestConditionKeys_MatchesTheDoorKeySet(t *testing.T) { - emitted := make([]string, 0, len(gatewayDoorKeys)) - for key := range emittedKeys(t) { - emitted = append(emitted, key) - } + emitted := slices.Collect(maps.Keys(emittedKeys(t))) assert.ElementsMatch(t, gatewayDoorKeys, emitted, "the AWS gateway door key set changed: update predastore's mirror in "+ "internal/gate/conditionkeys_completeness_test.go and the door table in bluebottle's door_test.go") diff --git a/spinifex/gateway/ec2.go b/spinifex/gateway/ec2.go index 3cb16f668..22d28611a 100644 --- a/spinifex/gateway/ec2.go +++ b/spinifex/gateway/ec2.go @@ -118,6 +118,7 @@ var ec2ListsAsSet = map[reflect.Type][]string{ reflect.TypeFor[ec2.RevokeSecurityGroupEgressOutput](): {"UnknownIpPermissions"}, reflect.TypeFor[ec2.NetworkInterface](): {"Ipv4Prefixes", "Ipv6Prefixes"}, reflect.TypeFor[ec2.Vpc](): {"Ipv6CidrBlockAssociationSet"}, + reflect.TypeFor[ec2.Subnet](): {"Tags"}, } // marshalEC2Response renders an EC2 handler's output into the action's XML diff --git a/spinifex/gateway/ec2_dryrun_test.go b/spinifex/gateway/ec2_dryrun_test.go index 9027f062b..f1053e6d4 100644 --- a/spinifex/gateway/ec2_dryrun_test.go +++ b/spinifex/gateway/ec2_dryrun_test.go @@ -4,6 +4,7 @@ package gateway import ( + "maps" "net/http" "net/http/httptest" "reflect" @@ -43,11 +44,7 @@ func serveEC2(gw *GatewayConfig, body string) *httptest.ResponseRecorder { func TestEC2Request_DryRunAnswersEveryAction(t *testing.T) { gw := &GatewayConfig{DisableLogging: true, Region: authzRegion, IAMService: allowAllIAMService()} - actions := make([]string, 0, len(ec2Actions)) - for action := range ec2Actions { - actions = append(actions, action) - } - slices.Sort(actions) + actions := slices.Sorted(maps.Keys(ec2Actions)) for _, action := range actions { t.Run(action, func(t *testing.T) { diff --git a/spinifex/gateway/ec2_emptyresult_test.go b/spinifex/gateway/ec2_emptyresult_test.go index 02e9a77c0..30177f49a 100644 --- a/spinifex/gateway/ec2_emptyresult_test.go +++ b/spinifex/gateway/ec2_emptyresult_test.go @@ -180,4 +180,8 @@ func TestEC2_NetworkListsAWSOmitsWhenEmpty(t *testing.T) { Ipv6CidrBlockAssociationSet: []*ec2.VpcIpv6CidrBlockAssociation{}, }}) assert.Contains(t, created, "") + + subnet := render[ec2.CreateSubnetInput](t, "CreateSubnet", ec2.CreateSubnetOutput{Subnet: &ec2.Subnet{SubnetId: aws.String("subnet-1")}}) + assert.NotContains(t, subnet, "tagSet") + assert.Contains(t, subnet, "") } diff --git a/spinifex/gateway/ecrapi/tags.go b/spinifex/gateway/ecrapi/tags.go index 14b0f9743..8fbad162b 100644 --- a/spinifex/gateway/ecrapi/tags.go +++ b/spinifex/gateway/ecrapi/tags.go @@ -4,7 +4,8 @@ import ( "context" "encoding/json" "errors" - "sort" + "maps" + "slices" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ecr" @@ -123,11 +124,7 @@ func ListTagsForResource(ctx context.Context, nc *nats.Conn, accountID string, b if err != nil { return nil, err } - keys := make([]string, 0, len(meta.Tags)) - for k := range meta.Tags { - keys = append(keys, k) - } - sort.Strings(keys) + keys := slices.Sorted(maps.Keys(meta.Tags)) tags := make([]*ecr.Tag, 0, len(keys)) for _, k := range keys { tags = append(tags, &ecr.Tag{Key: aws.String(k), Value: aws.String(meta.Tags[k])}) diff --git a/spinifex/handlers/ec2/instance/service_impl.go b/spinifex/handlers/ec2/instance/service_impl.go index ce4651fe0..0316634bf 100644 --- a/spinifex/handlers/ec2/instance/service_impl.go +++ b/spinifex/handlers/ec2/instance/service_impl.go @@ -2116,10 +2116,7 @@ func (s *InstanceServiceImpl) DescribeInstances(ctx context.Context, input *ec2. } }) - reservations := make([]*ec2.Reservation, 0, len(reservationMap)) - for _, reservation := range reservationMap { - reservations = append(reservations, reservation) - } + reservations := slices.Collect(maps.Values(reservationMap)) slog.InfoContext(ctx, "DescribeInstances completed", "count", len(reservations)) return &ec2.DescribeInstancesOutput{Reservations: reservations}, nil @@ -2242,10 +2239,7 @@ func (s *InstanceServiceImpl) describeInstancesFromKV(ctx context.Context, input reservationMap[resID].Instances = append(reservationMap[resID].Instances, projected) } - reservations := make([]*ec2.Reservation, 0, len(reservationMap)) - for _, reservation := range reservationMap { - reservations = append(reservations, reservation) - } + reservations := slices.Collect(maps.Values(reservationMap)) slog.InfoContext(ctx, opName+" completed", "count", len(reservations)) return &ec2.DescribeInstancesOutput{Reservations: reservations}, nil diff --git a/spinifex/handlers/eks/addon_catalog.go b/spinifex/handlers/eks/addon_catalog.go index 29980b02b..90146a64e 100644 --- a/spinifex/handlers/eks/addon_catalog.go +++ b/spinifex/handlers/eks/addon_catalog.go @@ -2,6 +2,7 @@ package handlers_eks import ( "fmt" + "maps" "slices" ) @@ -111,11 +112,7 @@ func (s AddonSpec) supportsVersion(version string) bool { // catalogSpecs returns the catalog entries sorted by name for stable output. func catalogSpecs() []AddonSpec { - names := make([]string, 0, len(addonCatalog)) - for n := range addonCatalog { - names = append(names, n) - } - slices.Sort(names) + names := slices.Sorted(maps.Keys(addonCatalog)) out := make([]AddonSpec, 0, len(names)) for _, n := range names { out = append(out, addonCatalog[n]) diff --git a/spinifex/loadgen/loadgen.go b/spinifex/loadgen/loadgen.go index 0a878bd16..61e1921e8 100644 --- a/spinifex/loadgen/loadgen.go +++ b/spinifex/loadgen/loadgen.go @@ -12,7 +12,9 @@ import ( "context" "errors" "fmt" + "maps" "math" + "slices" "sort" "sync" "time" @@ -503,10 +505,5 @@ func Summary(report *Report) string { } func sortedOps(ops map[string]OpStats) []string { - names := make([]string, 0, len(ops)) - for name := range ops { - names = append(names, name) - } - sort.Strings(names) - return names + return slices.Sorted(maps.Keys(ops)) } diff --git a/spinifex/loadgen/ops.go b/spinifex/loadgen/ops.go index 126d7fe24..fb560e5ac 100644 --- a/spinifex/loadgen/ops.go +++ b/spinifex/loadgen/ops.go @@ -3,8 +3,8 @@ package loadgen import ( "context" "fmt" + "maps" "slices" - "sort" "strings" "github.com/aws/aws-sdk-go/aws" @@ -103,12 +103,7 @@ var DefaultOps = []string{"DescribeInstances", "DescribeVpcs", "DescribeVolumes" // OpNames lists every operation the registry knows, for the usage text. func OpNames() []string { - names := make([]string, 0, len(registry)) - for name := range registry { - names = append(names, name) - } - sort.Strings(names) - return names + return slices.Sorted(maps.Keys(registry)) } // ResolveOps turns names into operations, rejecting an unknown one rather than diff --git a/spinifex/resource/resource_test.go b/spinifex/resource/resource_test.go index 7c1736c5f..29dfa2177 100644 --- a/spinifex/resource/resource_test.go +++ b/spinifex/resource/resource_test.go @@ -2,6 +2,7 @@ package resource_test import ( "encoding/json" + "maps" "slices" "testing" "time" @@ -202,10 +203,5 @@ func TestObjectJSON_RoundTrips(t *testing.T) { } func sortedKeys(m map[string]json.RawMessage) []string { - keys := make([]string, 0, len(m)) - for k := range m { - keys = append(keys, k) - } - slices.Sort(keys) - return keys + return slices.Sorted(maps.Keys(m)) } diff --git a/spinifex/services/awsgw/awsgw.go b/spinifex/services/awsgw/awsgw.go index 79c830a44..29a9a7bb3 100644 --- a/spinifex/services/awsgw/awsgw.go +++ b/spinifex/services/awsgw/awsgw.go @@ -6,10 +6,12 @@ import ( "crypto/x509" "fmt" "log/slog" + "maps" "net" "net/http" "os" "path/filepath" + "slices" "strings" "time" @@ -443,10 +445,7 @@ func launchService(config *config.ClusterConfig) error { // nodeIDs is the configured cluster node set, in the same namespace as the // daemon reply header, so a fan-out's completeness can be judged by // responder identity rather than by count. - nodeIDs := make([]string, 0, len(config.Nodes)) - for nodeID := range config.Nodes { - nodeIDs = append(nodeIDs, nodeID) - } + nodeIDs := slices.Collect(maps.Keys(config.Nodes)) gw := gateway.GatewayConfig{ Debug: nodeConfig.AWSGW.Debug, diff --git a/spinifex/services/northstar/bootstrap.go b/spinifex/services/northstar/bootstrap.go index 756ae7c35..d70ba99b7 100644 --- a/spinifex/services/northstar/bootstrap.go +++ b/spinifex/services/northstar/bootstrap.go @@ -3,7 +3,8 @@ package northstar import ( "fmt" "log/slog" - "sort" + "maps" + "slices" "strings" "time" @@ -150,10 +151,5 @@ func ensureZone(s3cfg *nsconfig.S3Config, seed nsconfig.BaseZoneSeed) error { // nodeNames returns the sorted node keys of the cluster, for diagnostics. func nodeNames(cluster *config.ClusterConfig) []string { - names := make([]string, 0, len(cluster.Nodes)) - for name := range cluster.Nodes { - names = append(names, name) - } - sort.Strings(names) - return names + return slices.Sorted(maps.Keys(cluster.Nodes)) } diff --git a/spinifex/systemd/reconcile.go b/spinifex/systemd/reconcile.go index 47583cb84..192a8e4a5 100644 --- a/spinifex/systemd/reconcile.go +++ b/spinifex/systemd/reconcile.go @@ -9,12 +9,12 @@ package systemd import ( "errors" "fmt" + "maps" "os" "os/exec" "path/filepath" "regexp" "slices" - "sort" "strconv" "strings" "time" @@ -98,12 +98,7 @@ var systemctlDaemonReload = func() error { } func sortedUnitNames() []string { - names := make([]string, 0, len(Units)) - for n := range Units { - names = append(names, n) - } - sort.Strings(names) - return names + return slices.Sorted(maps.Keys(Units)) } // Reconcile compares each embedded unit (Units, generated from diff --git a/spinifex/utils/nats_trace.go b/spinifex/utils/nats_trace.go index 1401ff137..174772da6 100644 --- a/spinifex/utils/nats_trace.go +++ b/spinifex/utils/nats_trace.go @@ -2,6 +2,8 @@ package utils import ( "context" + "maps" + "slices" "github.com/nats-io/nats.go" "go.opentelemetry.io/otel" @@ -22,11 +24,7 @@ type natsHeaderCarrier nats.Header func (c natsHeaderCarrier) Get(key string) string { return nats.Header(c).Get(key) } func (c natsHeaderCarrier) Set(key, value string) { nats.Header(c).Set(key, value) } func (c natsHeaderCarrier) Keys() []string { - keys := make([]string, 0, len(c)) - for k := range c { - keys = append(keys, k) - } - return keys + return slices.Collect(maps.Keys(c)) } // InjectTraceContext writes ctx's span context into hdr (traceparent/tracestate). diff --git a/spinifex/vm/manager.go b/spinifex/vm/manager.go index 2251f0de6..6e96267b3 100644 --- a/spinifex/vm/manager.go +++ b/spinifex/vm/manager.go @@ -2,6 +2,7 @@ package vm import ( "maps" + "slices" "sync" "time" ) @@ -191,11 +192,7 @@ func (m *Manager) ForEach(fn func(*VM)) { func (m *Manager) Snapshot() []*VM { m.mu.Lock() defer m.mu.Unlock() - out := make([]*VM, 0, len(m.vms)) - for _, v := range m.vms { - out = append(out, v) - } - return out + return slices.Collect(maps.Values(m.vms)) } // SnapshotMap returns a copy of the id→VM map for serialization outside the lock. diff --git a/spinifex/vm/manager_deps_test.go b/spinifex/vm/manager_deps_test.go index c18709a5c..b5e116eb0 100644 --- a/spinifex/vm/manager_deps_test.go +++ b/spinifex/vm/manager_deps_test.go @@ -4,6 +4,7 @@ import ( "context" "errors" "maps" + "slices" "sync" "github.com/mulgadc/spinifex/spinifex/types" @@ -76,11 +77,7 @@ func (f *fakeStateStore) DeleteStoppedInstance(id string) error { func (f *fakeStateStore) ListStoppedInstances() ([]*VM, error) { f.mu.Lock() defer f.mu.Unlock() - out := make([]*VM, 0, len(f.stopped)) - for _, v := range f.stopped { - out = append(out, v) - } - return out, nil + return slices.Collect(maps.Values(f.stopped)), nil } // ClaimStoppedInstance mimics the real atomic-delete claim for tests: under @@ -107,11 +104,7 @@ func (f *fakeStateStore) WriteTerminatedInstance(id string, v *VM) error { func (f *fakeStateStore) ListTerminatedInstances() ([]*VM, error) { f.mu.Lock() defer f.mu.Unlock() - out := make([]*VM, 0, len(f.terminated)) - for _, v := range f.terminated { - out = append(out, v) - } - return out, nil + return slices.Collect(maps.Values(f.terminated)), nil } func (f *fakeStateStore) DeleteTerminatedInstance(id string) error { diff --git a/spinifex/vm/mock/mock.go b/spinifex/vm/mock/mock.go index 1633ade04..58475a28f 100644 --- a/spinifex/vm/mock/mock.go +++ b/spinifex/vm/mock/mock.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "maps" + "slices" "sync" "github.com/mulgadc/spinifex/spinifex/kvstore" @@ -170,11 +171,7 @@ func (s *StateStore) ListStoppedInstances() ([]*vm.VM, error) { if s.ListStoppedErr != nil { return nil, s.ListStoppedErr } - out := make([]*vm.VM, 0, len(s.Stopped)) - for _, v := range s.Stopped { - out = append(out, v) - } - return out, nil + return slices.Collect(maps.Values(s.Stopped)), nil } // ClaimStoppedInstance mimics the real atomic delete-as-claim: under the @@ -237,11 +234,7 @@ func (s *StateStore) ListTerminatedInstances() ([]*vm.VM, error) { if s.ListTerminatedErr != nil { return nil, s.ListTerminatedErr } - out := make([]*vm.VM, 0, len(s.Terminated)) - for _, v := range s.Terminated { - out = append(out, v) - } - return out, nil + return slices.Collect(maps.Values(s.Terminated)), nil } func (s *StateStore) DeleteTerminatedInstance(id string) error { diff --git a/tests/bench/ebsctl/compare.go b/tests/bench/ebsctl/compare.go index 0bbbc3841..59afc2e0b 100644 --- a/tests/bench/ebsctl/compare.go +++ b/tests/bench/ebsctl/compare.go @@ -3,8 +3,10 @@ package ebsctl import ( "encoding/json" "fmt" + "maps" "math/rand/v2" "os" + "slices" "sort" "strconv" "strings" @@ -74,12 +76,7 @@ func unionOps(a, b *RunResult) []string { for name := range b.Operations { seen[name] = struct{}{} } - out := make([]string, 0, len(seen)) - for name := range seen { - out = append(out, name) - } - sort.Strings(out) - return out + return slices.Sorted(maps.Keys(seen)) } // seriesFor picks the api or settle series from op, or nil if op is nil or diff --git a/tests/e2e/ddil/scenarios/coverage_drift_test.go b/tests/e2e/ddil/scenarios/coverage_drift_test.go index 09eb243fe..b4c3f8f21 100644 --- a/tests/e2e/ddil/scenarios/coverage_drift_test.go +++ b/tests/e2e/ddil/scenarios/coverage_drift_test.go @@ -6,11 +6,12 @@ import ( "go/ast" "go/parser" "go/token" + "maps" "os" "path/filepath" "regexp" "runtime" - "sort" + "slices" "strings" "testing" ) @@ -117,12 +118,7 @@ func lettersFromDoc(path string) ([]string, error) { } func sortedKeys(m map[string]struct{}) []string { - out := make([]string, 0, len(m)) - for k := range m { - out = append(out, k) - } - sort.Strings(out) - return out + return slices.Sorted(maps.Keys(m)) } // setDiff returns elements in a that are not in b (both inputs must be sorted). diff --git a/tests/e2e/harness/account.go b/tests/e2e/harness/account.go index 9ed44bba3..5be8cdf3f 100644 --- a/tests/e2e/harness/account.go +++ b/tests/e2e/harness/account.go @@ -3,7 +3,8 @@ package harness import ( - "sort" + "maps" + "slices" "sync" "testing" ) @@ -59,10 +60,5 @@ func (a *AccountCarousel) Get(name string) *Profile { func (a *AccountCarousel) Names() []string { a.mu.RLock() defer a.mu.RUnlock() - out := make([]string, 0, len(a.profiles)) - for k := range a.profiles { - out = append(out, k) - } - sort.Strings(out) - return out + return slices.Sorted(maps.Keys(a.profiles)) } diff --git a/tests/e2e/harness/guest_data.go b/tests/e2e/harness/guest_data.go index 88dec1bc9..04e77615e 100644 --- a/tests/e2e/harness/guest_data.go +++ b/tests/e2e/harness/guest_data.go @@ -5,8 +5,10 @@ package harness import ( "context" "fmt" + "maps" "os/exec" "regexp" + "slices" "strconv" "strings" "testing" @@ -115,10 +117,7 @@ func WaitForNewGuestDisk(t *testing.T, tgt SSHTarget, before map[string]struct{} return nil } } - names := make([]string, 0, len(now)) - for name := range now { - names = append(names, name) - } + names := slices.Collect(maps.Keys(now)) return fmt.Errorf("no new disk yet (visible: %s)", strings.Join(names, ",")) }, timeout, 2*time.Second) return found diff --git a/tests/e2e/kvquorum/node_loss_test.go b/tests/e2e/kvquorum/node_loss_test.go index d2beafaef..680d835f3 100644 --- a/tests/e2e/kvquorum/node_loss_test.go +++ b/tests/e2e/kvquorum/node_loss_test.go @@ -4,6 +4,8 @@ package kvquorum import ( "fmt" + "maps" + "slices" "sort" "strings" "testing" @@ -180,10 +182,6 @@ func peerNames(reports []kvutil.BucketReport) string { seen[p] = struct{}{} } } - out := make([]string, 0, len(seen)) - for p := range seen { - out = append(out, p) - } - sort.Strings(out) + out := slices.Sorted(maps.Keys(seen)) return strings.Join(out, ",") } diff --git a/tests/e2e/manifest-lint/lint.go b/tests/e2e/manifest-lint/lint.go index 1946947e9..ed2c1218a 100644 --- a/tests/e2e/manifest-lint/lint.go +++ b/tests/e2e/manifest-lint/lint.go @@ -21,7 +21,9 @@ package manifestlint import ( "bufio" + "maps" "os" + "slices" "sort" "strings" ) @@ -75,11 +77,7 @@ func WriteBaseline(path string, keys []string) error { for _, k := range keys { uniq[k] = true } - out := make([]string, 0, len(uniq)) - for k := range uniq { - out = append(out, k) - } - sort.Strings(out) + out := slices.Sorted(maps.Keys(uniq)) var b strings.Builder b.WriteString("# manifest-lint baseline — pre-existing drift accepted by the ratchet.\n") diff --git a/tests/e2e/manifest-lint/subjects.go b/tests/e2e/manifest-lint/subjects.go index d6479e950..4e445a08d 100644 --- a/tests/e2e/manifest-lint/subjects.go +++ b/tests/e2e/manifest-lint/subjects.go @@ -5,9 +5,11 @@ import ( "go/ast" "go/parser" "go/token" + "maps" "os" "path/filepath" "regexp" + "slices" "sort" "strconv" "strings" @@ -137,12 +139,7 @@ func serviceDirs(m *manifestcheck.Manifest) []string { set[p] = true } } - out := make([]string, 0, len(set)) - for d := range set { - out = append(out, d) - } - sort.Strings(out) - return out + return slices.Sorted(maps.Keys(set)) } // scanSubjectsInDir walks dir recursively, parsing every non-test .go file and diff --git a/tests/e2e/single/guestchurn_test.go b/tests/e2e/single/guestchurn_test.go index ae2a62647..47d6549d5 100644 --- a/tests/e2e/single/guestchurn_test.go +++ b/tests/e2e/single/guestchurn_test.go @@ -4,8 +4,10 @@ package single import ( "fmt" + "maps" "net" "os/exec" + "slices" "strconv" "strings" "testing" @@ -692,11 +694,7 @@ func guestMACSet(t *testing.T, tgt harness.SSHTarget) map[string]struct{} { // setKeys returns the keys of a string set as a slice for log/Detail output. func setKeys(m map[string]struct{}) []string { - keys := make([]string, 0, len(m)) - for k := range m { - keys = append(keys, k) - } - return keys + return slices.Collect(maps.Keys(m)) } // describeENI returns the single ENI record for eniID, erroring if absent. diff --git a/tests/integration/conformance.go b/tests/integration/conformance.go index 374cfc725..cee3835e6 100644 --- a/tests/integration/conformance.go +++ b/tests/integration/conformance.go @@ -6,8 +6,10 @@ import ( "bytes" "fmt" "io" + "maps" "net/http" "net/url" + "slices" "sort" "strings" "sync" @@ -210,11 +212,7 @@ func (c *conformanceCollector) report(policy conformancePolicy, mode conformance for service := range policy.promoted { checkedServices[service] = true } - services := make([]awsmodel.Service, 0, len(checkedServices)) - for service := range checkedServices { - services = append(services, service) - } - sort.Slice(services, func(i, j int) bool { return services[i] < services[j] }) + services := slices.Sorted(maps.Keys(checkedServices)) for _, service := range services { fmt.Fprintf(&report, "CHECKED %s success=%d errors=%d unmodelled_errors=%d promoted=%t\n", service, c.checkedByService[service], c.errorCheckedByService[service], c.errorUnmodelledByService[service], policy.isPromoted(service)) diff --git a/tests/integration/conformance_policy.go b/tests/integration/conformance_policy.go index 486016a6b..8b9a85bd2 100644 --- a/tests/integration/conformance_policy.go +++ b/tests/integration/conformance_policy.go @@ -6,8 +6,9 @@ import ( _ "embed" "encoding/json" "fmt" + "maps" "os" - "sort" + "slices" "strings" "github.com/mulgadc/spinifex/internal/awsmodel" @@ -89,12 +90,7 @@ func (p conformancePolicy) isRequestPromoted(service awsmodel.Service) bool { } func (p conformancePolicy) services() []awsmodel.Service { - services := make([]awsmodel.Service, 0, len(p.promoted)) - for service := range p.promoted { - services = append(services, service) - } - sort.Slice(services, func(i, j int) bool { return services[i] < services[j] }) - return services + return slices.Sorted(maps.Keys(p.promoted)) } func conformanceModeFromEnvironment() (conformanceMode, error) {