diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d0f207fea..39a286858 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -185,6 +185,11 @@ A test file is named for the production file it tests. Where tests grow too large to read, split the production file first so each test file keeps a counterpart, rather than splitting tests away from the file they cover. +A test file that holds no tests is named for what it holds, not for the fact +that other tests use it. `support`, `fixture` and `helper` describe where the +code was put; `sha256_public_test.go` and `test_agent_public_test.go` say what +is in them. Where only one test file needs the code, it belongs in that file. + ### Go patterns - Error wrapping: `fmt.Errorf("context: %w", err)`, so the chain names each @@ -302,6 +307,10 @@ just go-unit-cov-check # Report coverage and fail below the target The target is declared in `.github/codecov.yml` and in the shared `go` justfile module. Change both together. +What the figure covers is narrowed by `.coverignore`, which excludes `/cmd/`, +`/gen/`, `/mocks/`, `/ui/` and `main.go`. A percentage read without that file in +mind will not match what the gate measures. + ### Test file conventions - Public tests: `*_public_test.go` in the package's `_test` package, exercising diff --git a/README.md b/README.md index 5e08b314e..55ae7c2dd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ [![release](https://img.shields.io/github/release/osapi-io/osapi.svg?style=for-the-badge)](https://github.com/osapi-io/osapi/releases/latest) [![codecov](https://img.shields.io/codecov/c/github/osapi-io/osapi?token=NF0T86B1EP&style=for-the-badge)](https://codecov.io/gh/osapi-io/osapi) -[![go report card](https://goreportcard.com/badge/github.com/osapi-io/osapi?style=for-the-badge)](https://goreportcard.com/report/github.com/osapi-io/osapi) [![license](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=for-the-badge)](LICENSE) [![build](https://img.shields.io/github/actions/workflow/status/osapi-io/osapi/go.yml?style=for-the-badge)](https://github.com/osapi-io/osapi/actions/workflows/go.yml) [![docker](https://img.shields.io/badge/ghcr.io-osapi-blue?style=for-the-badge&logo=docker&logoColor=white)](https://github.com/osapi-io/osapi/pkgs/container/osapi) diff --git a/cmd/client_audit_export.go b/cmd/client_audit_export.go index 84b3d904f..943c20759 100644 --- a/cmd/client_audit_export.go +++ b/cmd/client_audit_export.go @@ -23,6 +23,7 @@ package cmd import ( "context" "fmt" + "log/slog" "strconv" "github.com/osapi-io/osapi/pkg/sdk/client" @@ -81,7 +82,7 @@ func writeExport( defer func() { if closeErr := exporter.Close(ctx); closeErr != nil { - logger.Error("closing exporter", "error", closeErr) + logger.Error("closing exporter", slog.Any("error", closeErr)) } }() diff --git a/cmd/controller_setup.go b/cmd/controller_setup.go index 42cdc6483..118ef3518 100644 --- a/cmd/controller_setup.go +++ b/cmd/controller_setup.go @@ -387,7 +387,9 @@ func newHealthChecker( // configuredKVBuckets returns the namespaced names of all KV buckets // declared in osapi.yaml. Only non-empty bucket configs are included. -func configuredKVBuckets(namespace string) []string { +func configuredKVBuckets( + namespace string, +) []string { var buckets []string for _, info := range appConfig.NATS.AllKVBuckets() { if info.Bucket != "" { @@ -400,7 +402,9 @@ func configuredKVBuckets(namespace string) []string { // configuredObjectBuckets returns the namespaced names of all Object Store // buckets declared in osapi.yaml. -func configuredObjectBuckets(namespace string) []string { +func configuredObjectBuckets( + namespace string, +) []string { var buckets []string for _, info := range appConfig.NATS.AllObjectStoreBuckets() { if info.Bucket != "" { diff --git a/cmd/start.go b/cmd/start.go index b5c8fbb3e..03b96073a 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -46,7 +46,9 @@ func (c *compositeLifecycle) Start() { } } -func (c *compositeLifecycle) Stop(ctx context.Context) { +func (c *compositeLifecycle) Stop( + ctx context.Context, +) { var wg sync.WaitGroup for _, comp := range c.components { wg.Add(1) diff --git a/examples/sdk/client/go.mod b/examples/sdk/client/go.mod index 3b524696d..c7507cec3 100644 --- a/examples/sdk/client/go.mod +++ b/examples/sdk/client/go.mod @@ -1,6 +1,6 @@ module github.com/osapi-io/osapi/examples/sdk/client -go 1.25.0 +go 1.26.0 replace github.com/osapi-io/osapi => ../../../ @@ -9,12 +9,12 @@ require github.com/osapi-io/osapi v0.0.0 require ( github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/oapi-codegen/runtime v1.6.0 // indirect + github.com/oapi-codegen/runtime v1.7.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect + go.opentelemetry.io/otel v1.46.0 // indirect + go.opentelemetry.io/otel/metric v1.46.0 // indirect + go.opentelemetry.io/otel/trace v1.46.0 // indirect ) diff --git a/examples/sdk/client/go.sum b/examples/sdk/client/go.sum index 93bfa01f1..5ee9cea55 100644 --- a/examples/sdk/client/go.sum +++ b/examples/sdk/client/go.sum @@ -5,11 +5,9 @@ github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvF github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= @@ -19,23 +17,21 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/oapi-codegen/nullable v1.1.0 h1:eAh8JVc5430VtYVnq00Hrbpag9PFRGWLjxR1/3KntMs= github.com/oapi-codegen/nullable v1.1.0/go.mod h1:KUZ3vUzkmEKY90ksAmit2+5juDIhIZhfDl+0PwOQlFY= -github.com/oapi-codegen/runtime v1.6.0 h1:7Xx+GlueD6nRuyKoCPzL434Jfi3BetbiJOrzCHp/VPU= -github.com/oapi-codegen/runtime v1.6.0/go.mod h1:GwV7hC2hviaMzj+ITfHVRESK5J2W/GefVwIND/bMGvU= +github.com/oapi-codegen/runtime v1.7.0 h1:t7358VYPvNbWJ9gdAkIK/smVeHpBf6yp8VTsaZsb/7k= +github.com/oapi-codegen/runtime v1.7.0/go.mod h1:GwV7hC2hviaMzj+ITfHVRESK5J2W/GefVwIND/bMGvU= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= +github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +go.opentelemetry.io/otel v1.46.0 h1:FHt5/CDyVxi/8IM1CH7VE/rRgq3kLHa2mSTVMO8AWyc= +go.opentelemetry.io/otel v1.46.0/go.mod h1:Gj3SEScelsNC45tp4nSxRYlS+f5iez7W8XPMCt905kE= +go.opentelemetry.io/otel/metric v1.46.0 h1:yBnkXvgV7AXFILZc5K6IZe/CBFF3OS7BJ8ov6/lj0K8= +go.opentelemetry.io/otel/metric v1.46.0/go.mod h1:iPmdWqifKUdzziPkvvzIJXITl56fQx2mGM/DHLB3/2o= +go.opentelemetry.io/otel/trace v1.46.0 h1:OULy7ccdJnZtJ0UDYFOIGaCmiWzJ8Vi2G/Rsu60qs1c= +go.opentelemetry.io/otel/trace v1.46.0/go.mod h1:J7GAXweO77XSFkB/rmAqk9D6ihszhFjLU+d9WuUxDLI= +go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= +go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= diff --git a/examples/sdk/platform/go.mod b/examples/sdk/platform/go.mod index 074e1d46d..d6c0ec22f 100644 --- a/examples/sdk/platform/go.mod +++ b/examples/sdk/platform/go.mod @@ -1,6 +1,6 @@ module github.com/osapi-io/osapi/examples/sdk/platform -go 1.25.0 +go 1.26.0 replace github.com/osapi-io/osapi => ../../../ @@ -12,7 +12,7 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/shirou/gopsutil/v4 v4.26.7 // indirect + github.com/shirou/gopsutil/v4 v4.26.8 // indirect github.com/tklauser/go-sysconf v0.3.16 // indirect github.com/tklauser/numcpus v0.11.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect diff --git a/examples/sdk/platform/go.sum b/examples/sdk/platform/go.sum index ab67acbce..f4fd9140c 100644 --- a/examples/sdk/platform/go.sum +++ b/examples/sdk/platform/go.sum @@ -1,7 +1,5 @@ github.com/avfs/avfs v0.35.0 h1:dc0noSyEoVDtAUQlhHX0uRYBfI2aFbI8nF0XPtV/Ozw= github.com/avfs/avfs v0.35.0/go.mod h1:LnzrUO5acMU5NCkohHcUN15YrnkxiJ/lRLQOZSp39ow= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/ebitengine/purego v0.10.2 h1:W809HbnvzAxgdm+aOvlSekrM16wGCdT/e76+9tS7gzE= github.com/ebitengine/purego v0.10.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= @@ -11,24 +9,22 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/shirou/gopsutil/v4 v4.26.7 h1:IXzpHz/dkMRYAhKkOXr1HB6SuzWU3eoyyeWe7g3bNZc= -github.com/shirou/gopsutil/v4 v4.26.7/go.mod h1:5O9FjBiXoTDFatIWjZZosqj4pV0DRtLx598xGbBehzM= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/shirou/gopsutil/v4 v4.26.8 h1:YQMTF/1J50B5+Y0vlo1eDRf5DoR7Gk69hY+8wjYkQeo= +github.com/shirou/gopsutil/v4 v4.26.8/go.mod h1:5O9FjBiXoTDFatIWjZZosqj4pV0DRtLx598xGbBehzM= +github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= +github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= +go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go.mod b/go.mod index 7cfd54d55..e862eb3ab 100644 --- a/go.mod +++ b/go.mod @@ -41,6 +41,7 @@ require ( go.opentelemetry.io/proto/otlp v1.11.0 go.uber.org/mock v0.6.0 golang.org/x/term v0.45.0 + k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 ) require ( diff --git a/go.sum b/go.sum index 8ea156a46..46b9f48d0 100644 --- a/go.sum +++ b/go.sum @@ -1542,6 +1542,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.7.0 h1:w6WUp1VbkqPEgLz4rkBzH/CSU6HkoqNLp6GstyTx3lU= honnef.co/go/tools v0.7.0/go.mod h1:pm29oPxeP3P82ISxZDgIYeOaf9ta6Pi0EWvCFoLG2vc= +k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 h1:jVkFFVfXdXP74B/zbO3hM3hpSFD0xvhQ5U686DPurkE= +k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3/go.mod h1:M2s5JB1lIYP3jzZdorPLHXIPJzt9vv2muW5a6L9DtNM= mvdan.cc/gofumpt v0.11.0 h1:0H01XB95PnN2QgCSR9ELdZyTlJqNZ7181B0BTMh5VZc= mvdan.cc/gofumpt v0.11.0/go.mod h1:BeT5wCsOJt6J9zT2MZIOGszjUHzFkn1/l9g6xAzqsXo= mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 h1:ssMzja7PDPJV8FStj7hq9IKiuiKhgz9ErWw+m68e7DI= diff --git a/internal/agent/agent_public_test.go b/internal/agent/agent_public_test.go index 711858015..51a0fbe1c 100644 --- a/internal/agent/agent_public_test.go +++ b/internal/agent/agent_public_test.go @@ -144,22 +144,24 @@ func (s *AgentPublicTestSuite) buildAgent() *agent.Agent { func (s *AgentPublicTestSuite) TestNew() { tests := []struct { - name string + name string + validateFunc func(*agent.Agent) }{ { name: "creates agent with all providers", + validateFunc: func(a *agent.Agent) { + s.NotNil(a) + + a.SetSubComponents(map[string]job.SubComponentInfo{ + "agent.heartbeat": {Status: "ok"}, + }) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - a := s.buildAgent() - - s.NotNil(a) - - a.SetSubComponents(map[string]job.SubComponentInfo{ - "agent.heartbeat": {Status: "ok"}, - }) + tt.validateFunc(s.buildAgent()) }) } } @@ -449,18 +451,19 @@ func (s *AgentPublicTestSuite) TestStart() { func (s *AgentPublicTestSuite) TestIsReady() { tests := []struct { - name string - setupFunc func() *agent.Agent - wantErr bool - errMsg string + name string + setupFunc func() *agent.Agent + validateFunc func(error) }{ { name: "returns error when agent not started", setupFunc: func() *agent.Agent { return s.buildAgent() }, - wantErr: true, - errMsg: "agent not started", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "agent not started") + }, }, { name: "returns nil when agent is started", @@ -486,31 +489,34 @@ func (s *AgentPublicTestSuite) TestIsReady() { return a }, - wantErr: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { a := tt.setupFunc() - err := a.IsReady() - - if tt.wantErr { - s.Error(err) - s.Contains(err.Error(), tt.errMsg) - } else { - s.NoError(err) - } + tt.validateFunc(a.IsReady()) }) } } func (s *AgentPublicTestSuite) TestSetMeterProvider() { tests := []struct { - name string + name string + validateFunc func(*metrics.Server, *agent.Agent) }{ { name: "creates OTEL instruments without panic", + validateFunc: func(srv *metrics.Server, a *agent.Agent) { + s.Require().NotNil(srv) + + s.NotPanics(func() { + a.SetMeterProvider(srv.MeterProvider()) + }) + }, }, } @@ -520,11 +526,7 @@ func (s *AgentPublicTestSuite) TestSetMeterProvider() { port := s.getFreePort() srv := metrics.New("127.0.0.1", port, slog.Default()) - s.Require().NotNil(srv) - - s.NotPanics(func() { - a.SetMeterProvider(srv.MeterProvider()) - }) + tt.validateFunc(srv, a) ctx, cancel := context.WithTimeout( context.Background(), @@ -539,12 +541,14 @@ func (s *AgentPublicTestSuite) TestSetMeterProvider() { func (s *AgentPublicTestSuite) TestLastHeartbeatTime() { tests := []struct { - name string - wantZero bool + name string + validateFunc func(time.Time) }{ { - name: "returns zero time before any heartbeat", - wantZero: true, + name: "returns zero time before any heartbeat", + validateFunc: func(got time.Time) { + s.True(got.IsZero()) + }, }, } @@ -552,14 +556,13 @@ func (s *AgentPublicTestSuite) TestLastHeartbeatTime() { s.Run(tt.name, func() { a := s.buildAgent() - got := a.LastHeartbeatTime() - if tt.wantZero { - s.True(got.IsZero()) - } + tt.validateFunc(a.LastHeartbeatTime()) }) } } -func TestAgentPublicTestSuite(t *testing.T) { +func TestAgentPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentPublicTestSuite)) } diff --git a/internal/agent/condition_public_test.go b/internal/agent/condition_public_test.go index 2e72a36eb..f930b13bc 100644 --- a/internal/agent/condition_public_test.go +++ b/internal/agent/condition_public_test.go @@ -615,6 +615,8 @@ func (s *ConditionPublicTestSuite) TestLastTransitionTimeTracking() { } } -func TestConditionPublicTestSuite(t *testing.T) { +func TestConditionPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ConditionPublicTestSuite)) } diff --git a/internal/agent/consumer_public_test.go b/internal/agent/consumer_public_test.go index 271e5507f..4d417cdc7 100644 --- a/internal/agent/consumer_public_test.go +++ b/internal/agent/consumer_public_test.go @@ -133,11 +133,11 @@ func (s *ConsumerPublicTestSuite) TestConsumerNamePrefix() { func (s *ConsumerPublicTestSuite) TestConsumeQueryJobs() { tests := []struct { - name string - hostname string - labels map[string]string - setupMocks func() - expectErr bool + name string + hostname string + labels map[string]string + setupMocks func() + validateFunc func(error) }{ { name: "successful query job consumption", @@ -155,7 +155,16 @@ func (s *ConsumerPublicTestSuite) TestConsumeQueryJobs() { Return(context.Canceled). Times(3) }, - expectErr: false, + validateFunc: func(err error) { + if false { + s.Error(err) + } else { + s.NoError(err) + } + + // Allow goroutines to execute before cleanup + time.Sleep(10 * time.Millisecond) + }, }, { name: "consumer creation failure", @@ -169,7 +178,16 @@ func (s *ConsumerPublicTestSuite) TestConsumeQueryJobs() { // No consumption should happen since creation failed }, - expectErr: false, // Should not return error, just log and continue + validateFunc: func(err error) { + if false { + s.Error(err) + } else { + s.NoError(err) + } + + // Allow goroutines to execute before cleanup + time.Sleep(10 * time.Millisecond) + }, }, { name: "partial consumer creation failure", @@ -193,7 +211,16 @@ func (s *ConsumerPublicTestSuite) TestConsumeQueryJobs() { Return(context.Canceled). Times(1) }, - expectErr: false, + validateFunc: func(err error) { + if false { + s.Error(err) + } else { + s.NoError(err) + } + + // Allow goroutines to execute before cleanup + time.Sleep(10 * time.Millisecond) + }, }, { name: "empty hostname", @@ -209,7 +236,16 @@ func (s *ConsumerPublicTestSuite) TestConsumeQueryJobs() { Return(context.Canceled). Times(3) }, - expectErr: false, + validateFunc: func(err error) { + if false { + s.Error(err) + } else { + s.NoError(err) + } + + // Allow goroutines to execute before cleanup + time.Sleep(10 * time.Millisecond) + }, }, { name: "consume error logged", @@ -225,7 +261,16 @@ func (s *ConsumerPublicTestSuite) TestConsumeQueryJobs() { Return(errors.New("connection lost")). Times(3) }, - expectErr: false, + validateFunc: func(err error) { + if false { + s.Error(err) + } else { + s.NoError(err) + } + + // Allow goroutines to execute before cleanup + time.Sleep(10 * time.Millisecond) + }, }, { name: "with labels creates extra consumers", @@ -245,7 +290,16 @@ func (s *ConsumerPublicTestSuite) TestConsumeQueryJobs() { Return(context.Canceled). Times(6) }, - expectErr: false, + validateFunc: func(err error) { + if false { + s.Error(err) + } else { + s.NoError(err) + } + + // Allow goroutines to execute before cleanup + time.Sleep(10 * time.Millisecond) + }, }, } @@ -260,27 +314,18 @@ func (s *ConsumerPublicTestSuite) TestConsumeQueryJobs() { tt.setupMocks() - err := agent.ExportConsumeQueryJobs(ctx, s.testAgent, tt.hostname) - - if tt.expectErr { - s.Error(err) - } else { - s.NoError(err) - } - - // Allow goroutines to execute before cleanup - time.Sleep(10 * time.Millisecond) + tt.validateFunc(agent.ExportConsumeQueryJobs(ctx, s.testAgent, tt.hostname)) }) } } func (s *ConsumerPublicTestSuite) TestConsumeModifyJobs() { tests := []struct { - name string - hostname string - labels map[string]string - setupMocks func() - expectErr bool + name string + hostname string + labels map[string]string + setupMocks func() + validateFunc func(error) }{ { name: "successful modify job consumption", @@ -298,7 +343,16 @@ func (s *ConsumerPublicTestSuite) TestConsumeModifyJobs() { Return(context.Canceled). Times(3) }, - expectErr: false, + validateFunc: func(err error) { + if false { + s.Error(err) + } else { + s.NoError(err) + } + + // Allow goroutines to execute before cleanup + time.Sleep(10 * time.Millisecond) + }, }, { name: "consumer creation failure", @@ -310,7 +364,16 @@ func (s *ConsumerPublicTestSuite) TestConsumeModifyJobs() { Return(errors.New("consumer creation failed")). Times(3) }, - expectErr: false, // Should not return error, just log and continue + validateFunc: func(err error) { + if false { + s.Error(err) + } else { + s.NoError(err) + } + + // Allow goroutines to execute before cleanup + time.Sleep(10 * time.Millisecond) + }, }, { name: "hostname with special characters", @@ -326,7 +389,16 @@ func (s *ConsumerPublicTestSuite) TestConsumeModifyJobs() { Return(context.Canceled). Times(3) }, - expectErr: false, + validateFunc: func(err error) { + if false { + s.Error(err) + } else { + s.NoError(err) + } + + // Allow goroutines to execute before cleanup + time.Sleep(10 * time.Millisecond) + }, }, { name: "consume error logged", @@ -342,7 +414,16 @@ func (s *ConsumerPublicTestSuite) TestConsumeModifyJobs() { Return(errors.New("connection lost")). Times(3) }, - expectErr: false, + validateFunc: func(err error) { + if false { + s.Error(err) + } else { + s.NoError(err) + } + + // Allow goroutines to execute before cleanup + time.Sleep(10 * time.Millisecond) + }, }, { name: "with labels creates extra consumers", @@ -362,7 +443,16 @@ func (s *ConsumerPublicTestSuite) TestConsumeModifyJobs() { Return(context.Canceled). Times(6) }, - expectErr: false, + validateFunc: func(err error) { + if false { + s.Error(err) + } else { + s.NoError(err) + } + + // Allow goroutines to execute before cleanup + time.Sleep(10 * time.Millisecond) + }, }, } @@ -377,16 +467,7 @@ func (s *ConsumerPublicTestSuite) TestConsumeModifyJobs() { tt.setupMocks() - err := agent.ExportConsumeModifyJobs(ctx, s.testAgent, tt.hostname) - - if tt.expectErr { - s.Error(err) - } else { - s.NoError(err) - } - - // Allow goroutines to execute before cleanup - time.Sleep(10 * time.Millisecond) + tt.validateFunc(agent.ExportConsumeModifyJobs(ctx, s.testAgent, tt.hostname)) }) } } @@ -399,8 +480,7 @@ func (s *ConsumerPublicTestSuite) TestCreateConsumer() { filterSubject string agentConsumer config.AgentConsumer setupMocks func() - expectErr bool - errorMsg string + validateFunc func(error) }{ { name: "successful consumer creation with instant replay", @@ -430,7 +510,9 @@ func (s *ConsumerPublicTestSuite) TestCreateConsumer() { }). Return(nil) }, - expectErr: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "successful consumer creation with original replay", @@ -458,7 +540,9 @@ func (s *ConsumerPublicTestSuite) TestCreateConsumer() { }). Return(nil) }, - expectErr: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "consumer creation failure", @@ -477,8 +561,10 @@ func (s *ConsumerPublicTestSuite) TestCreateConsumer() { CreateOrUpdateConsumer(gomock.Any(), "test-stream", gomock.Any()). Return(errors.New("stream not found")) }, - expectErr: true, - errorMsg: "stream not found", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "stream not found") + }, }, { name: "invalid duration in config", @@ -502,7 +588,9 @@ func (s *ConsumerPublicTestSuite) TestCreateConsumer() { }). Return(nil) }, - expectErr: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, } @@ -515,32 +603,24 @@ func (s *ConsumerPublicTestSuite) TestCreateConsumer() { tt.setupMocks() - err := agent.ExportCreateConsumer( + tt.validateFunc(agent.ExportCreateConsumer( context.Background(), s.testAgent, tt.streamName, tt.consumerName, tt.filterSubject, - ) - - if tt.expectErr { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - } else { - s.NoError(err) - } + )) }) } } func (s *ConsumerPublicTestSuite) TestHandleJobMessageJS() { tests := []struct { - name string - msgData []byte - msgSubject string - setupMocks func() - expectErr bool - errorMsg string + name string + msgData []byte + msgSubject string + setupMocks func() + validateFunc func(error) }{ { name: "successful message handling", @@ -576,7 +656,9 @@ func (s *ConsumerPublicTestSuite) TestHandleJobMessageJS() { WriteJobResponse(gomock.Any(), "test-job-key", gomock.Any(), gomock.Any(), "completed", "", gomock.Any()). Return(nil) }, - expectErr: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "job processing failure", @@ -588,8 +670,10 @@ func (s *ConsumerPublicTestSuite) TestHandleJobMessageJS() { GetJobData(gomock.Any(), "jobs.failed-job-key"). Return(nil, errors.New("job not found")) }, - expectErr: true, - errorMsg: "job not found", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "job not found") + }, }, { name: "invalid subject", @@ -598,8 +682,10 @@ func (s *ConsumerPublicTestSuite) TestHandleJobMessageJS() { setupMocks: func() { // No mocks needed as it should fail early }, - expectErr: true, - errorMsg: "failed to parse subject", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "failed to parse subject") + }, }, } @@ -612,18 +698,13 @@ func (s *ConsumerPublicTestSuite) TestHandleJobMessageJS() { mockMsg.EXPECT().Data().Return(tt.msgData).AnyTimes() mockMsg.EXPECT().Headers().Return(nil).AnyTimes() - err := agent.ExportHandleJobMessageJS(s.testAgent, mockMsg) - - if tt.expectErr { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - } else { - s.NoError(err) - } + tt.validateFunc(agent.ExportHandleJobMessageJS(s.testAgent, mockMsg)) }) } } -func TestConsumerPublicTestSuite(t *testing.T) { +func TestConsumerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ConsumerPublicTestSuite)) } diff --git a/internal/agent/drain_public_test.go b/internal/agent/drain_public_test.go index 69242d6be..805193a51 100644 --- a/internal/agent/drain_public_test.go +++ b/internal/agent/drain_public_test.go @@ -135,10 +135,10 @@ func (s *DrainPublicTestSuite) TestCheckDrainFlag() { func (s *DrainPublicTestSuite) TestHandleDrainDetection() { tests := []struct { - name string - initialState string - setupMock func() - expectedState string + name string + initialState string + setupMock func() + validateFunc func(string) }{ { name: "when drain flag set and agent is Ready transitions to Cordoned", @@ -164,7 +164,9 @@ func (s *DrainPublicTestSuite) TestHandleDrainDetection() { ). Return(nil) }, - expectedState: job.AgentStateCordoned, + validateFunc: func(got string) { + s.Equal(job.AgentStateCordoned, got) + }, }, { name: "when drain flag removed and agent is Draining transitions to Ready", @@ -191,7 +193,9 @@ func (s *DrainPublicTestSuite) TestHandleDrainDetection() { Return(context.Canceled). AnyTimes() }, - expectedState: job.AgentStateReady, + validateFunc: func(got string) { + s.Equal(job.AgentStateReady, got) + }, }, { name: "when drain flag removed and agent is Cordoned transitions to Ready", @@ -218,7 +222,9 @@ func (s *DrainPublicTestSuite) TestHandleDrainDetection() { Return(context.Canceled). AnyTimes() }, - expectedState: job.AgentStateReady, + validateFunc: func(got string) { + s.Equal(job.AgentStateReady, got) + }, }, { name: "when drain flag still set and agent is already Draining stays Draining", @@ -228,7 +234,9 @@ func (s *DrainPublicTestSuite) TestHandleDrainDetection() { CheckDrainFlag(gomock.Any(), "test-machine-id"). Return(true) }, - expectedState: job.AgentStateDraining, + validateFunc: func(got string) { + s.Equal(job.AgentStateDraining, got) + }, }, { name: "when no drain flag and agent is Ready stays Ready", @@ -238,7 +246,9 @@ func (s *DrainPublicTestSuite) TestHandleDrainDetection() { CheckDrainFlag(gomock.Any(), "test-machine-id"). Return(false) }, - expectedState: job.AgentStateReady, + validateFunc: func(got string) { + s.Equal(job.AgentStateReady, got) + }, }, } @@ -252,11 +262,13 @@ func (s *DrainPublicTestSuite) TestHandleDrainDetection() { "test-machine-id", "test-agent", ) - s.Equal(tt.expectedState, agent.GetAgentState(s.testAgent)) + tt.validateFunc(agent.GetAgentState(s.testAgent)) }) } } -func TestDrainPublicTestSuite(t *testing.T) { +func TestDrainPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DrainPublicTestSuite)) } diff --git a/internal/agent/enrollment_public_test.go b/internal/agent/enrollment_public_test.go index 308297d41..5ec3e9c72 100644 --- a/internal/agent/enrollment_public_test.go +++ b/internal/agent/enrollment_public_test.go @@ -244,8 +244,7 @@ func (suite *EnrollmentPublicTestSuite) TestPublishEnrollmentRequest() { tests := []struct { name string setupAgent func() *agent.Agent - wantErr bool - wantContains string + validateFunc func(error) }{ { name: "when natsClient is nil returns error", @@ -273,8 +272,10 @@ func (suite *EnrollmentPublicTestSuite) TestPublishEnrollmentRequest() { return a }, - wantErr: true, - wantContains: "NATS client not available", + validateFunc: func(err error) { + require.Error(suite.T(), err) + assert.Contains(suite.T(), err.Error(), "NATS client not available") + }, }, { name: "when publish succeeds without namespace", @@ -307,7 +308,9 @@ func (suite *EnrollmentPublicTestSuite) TestPublishEnrollmentRequest() { return a }, - wantErr: false, + validateFunc: func(err error) { + require.NoError(suite.T(), err) + }, }, { name: "when publish succeeds with namespace", @@ -343,7 +346,9 @@ func (suite *EnrollmentPublicTestSuite) TestPublishEnrollmentRequest() { return a }, - wantErr: false, + validateFunc: func(err error) { + require.NoError(suite.T(), err) + }, }, { name: "when publish fails returns error", @@ -376,8 +381,10 @@ func (suite *EnrollmentPublicTestSuite) TestPublishEnrollmentRequest() { return a }, - wantErr: true, - wantContains: "publish enrollment request", + validateFunc: func(err error) { + require.Error(suite.T(), err) + assert.Contains(suite.T(), err.Error(), "publish enrollment request") + }, }, { name: "when marshal fails returns error", @@ -414,8 +421,10 @@ func (suite *EnrollmentPublicTestSuite) TestPublishEnrollmentRequest() { return a }, - wantErr: true, - wantContains: "marshal enrollment request", + validateFunc: func(err error) { + require.Error(suite.T(), err) + assert.Contains(suite.T(), err.Error(), "marshal enrollment request") + }, }, } @@ -423,14 +432,7 @@ func (suite *EnrollmentPublicTestSuite) TestPublishEnrollmentRequest() { suite.Run(tc.name, func() { a := tc.setupAgent() - err := agent.ExportPublishEnrollmentRequest(a) - - if tc.wantErr { - require.Error(suite.T(), err) - assert.Contains(suite.T(), err.Error(), tc.wantContains) - } else { - require.NoError(suite.T(), err) - } + tc.validateFunc(agent.ExportPublishEnrollmentRequest(a)) }) } } @@ -873,7 +875,9 @@ func (suite *EnrollmentPublicTestSuite) TestHandleEnrollmentResponse() { } } -func TestEnrollmentPublicTestSuite(t *testing.T) { +func TestEnrollmentPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(EnrollmentPublicTestSuite)) } diff --git a/internal/agent/export_test.go b/internal/agent/export_test.go index 70b2a211c..dbbeb0b36 100644 --- a/internal/agent/export_test.go +++ b/internal/agent/export_test.go @@ -52,7 +52,9 @@ import ( ) // SetEmbeddedFS overrides the embedded filesystem for testing. -func SetEmbeddedFS(f fs.FS) { +func SetEmbeddedFS( + f fs.FS, +) { embeddedFS = f } @@ -62,7 +64,9 @@ func ResetEmbeddedFS() { } // SetReadEmbeddedFile overrides the read function for testing. -func SetReadEmbeddedFile(fn func(string) ([]byte, error)) { +func SetReadEmbeddedFile( + fn func(string) ([]byte, error), +) { readEmbeddedFile = fn } @@ -315,7 +319,9 @@ func ExportEvaluateDiskPressure( // --- Package-level variable accessors for testing --- // SetMarshalJSON overrides the marshalJSON function for testing. -func SetMarshalJSON(fn func(interface{}) ([]byte, error)) { +func SetMarshalJSON( + fn func(interface{}) ([]byte, error), +) { marshalJSON = fn } @@ -325,7 +331,9 @@ func ResetMarshalJSON() { } // SetUnmarshalJSON overrides the unmarshalJSON function for testing. -func SetUnmarshalJSON(fn func([]byte, interface{}) error) { +func SetUnmarshalJSON( + fn func([]byte, interface{}) error, +) { unmarshalJSON = fn } @@ -335,7 +343,9 @@ func ResetUnmarshalJSON() { } // SetDefaultFactsInterval overrides the defaultFactsInterval for testing. -func SetDefaultFactsInterval(d time.Duration) { +func SetDefaultFactsInterval( + d time.Duration, +) { defaultFactsInterval = d } @@ -345,7 +355,9 @@ func ResetDefaultFactsInterval() { } // SetHeartbeatInterval overrides the heartbeatInterval for testing. -func SetHeartbeatInterval(d time.Duration) { +func SetHeartbeatInterval( + d time.Duration, +) { heartbeatInterval = d } @@ -355,7 +367,9 @@ func ResetHeartbeatInterval() { } // SetGetAgentHostnameFn overrides the getAgentHostnameFn for testing. -func SetGetAgentHostnameFn(fn func(string) (string, error)) { +func SetGetAgentHostnameFn( + fn func(string) (string, error), +) { getAgentHostnameFn = fn } @@ -382,7 +396,9 @@ func SetAgentHostname( // SetDockerNewFn overrides the dockerNewFn used by the factory for testing. // NOTE: This overrides the package-level var in the agent package, not cmd. // For cmd-level tests, use the cmd package's own override. -func SetDockerNewFn(fn func() (*dockerProv.Client, error)) { +func SetDockerNewFn( + fn func() (*dockerProv.Client, error), +) { _ = fn // no-op: dockerNewFn lives in cmd package now } @@ -390,7 +406,9 @@ func SetDockerNewFn(fn func() (*dockerProv.Client, error)) { func ResetDockerNewFn() {} // SetProcStatusPath overrides the procStatusPath for testing. -func SetProcStatusPath(p string) { +func SetProcStatusPath( + p string, +) { procStatusPath = p } @@ -643,7 +661,9 @@ func WaitAgentWG( } // SetGetIdentityFn overrides the getIdentityFn variable for testing. -func SetGetIdentityFn(fn func(avfs.VFS, string) (*identity.Identity, error)) { +func SetGetIdentityFn( + fn func(avfs.VFS, string) (*identity.Identity, error), +) { getIdentityFn = fn } @@ -683,7 +703,9 @@ func ExportPublishEnrollmentRequest( } // SetMarshalJSONEnrollment overrides the marshalJSONEnrollment function for testing. -func SetMarshalJSONEnrollment(fn func(interface{}) ([]byte, error)) { +func SetMarshalJSONEnrollment( + fn func(interface{}) ([]byte, error), +) { marshalJSONEnrollment = fn } diff --git a/internal/agent/factref_public_test.go b/internal/agent/factref_public_test.go index 89894771c..fbc0efb8e 100644 --- a/internal/agent/factref_public_test.go +++ b/internal/agent/factref_public_test.go @@ -401,6 +401,8 @@ func (s *FactRefPublicTestSuite) TestResolveFacts() { } } -func TestFactRefPublicTestSuite(t *testing.T) { +func TestFactRefPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FactRefPublicTestSuite)) } diff --git a/internal/agent/facts_public_test.go b/internal/agent/facts_public_test.go index 786198df2..990caecfe 100644 --- a/internal/agent/facts_public_test.go +++ b/internal/agent/facts_public_test.go @@ -399,30 +399,36 @@ func (s *FactsPublicTestSuite) TestGetFacts() { func (s *FactsPublicTestSuite) TestFactsKey() { tests := []struct { - name string - machineID string - expected string + name string + machineID string + validateFunc func(string) }{ { name: "simple machine ID", machineID: "abc-123-def", - expected: "facts.abc_123_def", + validateFunc: func(got string) { + s.Equal("facts.abc_123_def", got) + }, }, { name: "machine ID with dots", machineID: "A1B2C3D4-E5F6.7890", - expected: "facts.A1B2C3D4_E5F6_7890", + validateFunc: func(got string) { + s.Equal("facts.A1B2C3D4_E5F6_7890", got) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { result := agent.ExportFactsKey(tt.machineID) - s.Equal(tt.expected, result) + tt.validateFunc(result) }) } } -func TestFactsPublicTestSuite(t *testing.T) { +func TestFactsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FactsPublicTestSuite)) } diff --git a/internal/agent/handler_public_test.go b/internal/agent/handler_public_test.go index 777465daa..07a053dcb 100644 --- a/internal/agent/handler_public_test.go +++ b/internal/agent/handler_public_test.go @@ -31,6 +31,8 @@ import ( "net" "testing" + "k8s.io/utils/ptr" + "github.com/avfs/avfs/vfs/memfs" "github.com/nats-io/nats.go/jetstream" "github.com/stretchr/testify/suite" @@ -134,13 +136,12 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestWriteStatusEvent() { tests := []struct { - name string - jobID string - event string - data map[string]interface{} - setupMocks func() - expectError bool - errorMsg string + name string + jobID string + event string + data map[string]interface{} + setupMocks func() + validateFunc func(error) }{ { name: "when successful status event write", @@ -152,7 +153,9 @@ func (s *HandlerPublicTestSuite) TestWriteStatusEvent() { WriteStatusEvent(gomock.Any(), "test-job-123", "started", gomock.Any(), gomock.Any()). Return(nil) }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when status event write with nil data", @@ -164,7 +167,9 @@ func (s *HandlerPublicTestSuite) TestWriteStatusEvent() { WriteStatusEvent(gomock.Any(), "test-job-456", "completed", gomock.Any(), nil). Return(nil) }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when status event write failure", @@ -176,8 +181,12 @@ func (s *HandlerPublicTestSuite) TestWriteStatusEvent() { WriteStatusEvent(gomock.Any(), "test-job-789", "failed", gomock.Any(), gomock.Any()). Return(errors.New("KV storage failed")) }, - expectError: true, - errorMsg: "KV storage failed", + validateFunc: func(err error) { + s.Error(err) + if "KV storage failed" != "" { + s.Contains(err.Error(), "KV storage failed") + } + }, }, { name: "when empty job ID", @@ -189,7 +198,9 @@ func (s *HandlerPublicTestSuite) TestWriteStatusEvent() { WriteStatusEvent(gomock.Any(), "", "started", gomock.Any(), gomock.Any()). Return(nil) }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, } @@ -197,33 +208,23 @@ func (s *HandlerPublicTestSuite) TestWriteStatusEvent() { s.Run(tt.name, func() { tt.setupMocks() - err := agent.ExportWriteStatusEvent( + tt.validateFunc(agent.ExportWriteStatusEvent( context.Background(), s.testAgent, tt.jobID, tt.event, tt.data, - ) - - if tt.expectError { - s.Error(err) - if tt.errorMsg != "" { - s.Contains(err.Error(), tt.errorMsg) - } - } else { - s.NoError(err) - } + )) }) } } func (s *HandlerPublicTestSuite) TestHandleJobMessage() { tests := []struct { - name string - setupMsg func(ctrl *gomock.Controller) jetstream.Msg - setupMocks func() - expectError bool - errorMsg string + name string + setupMsg func(ctrl *gomock.Controller) jetstream.Msg + setupMocks func() + validateFunc func(error) }{ { name: "when successful job processing", @@ -260,7 +261,9 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { WriteJobResponse(gomock.Any(), "test-job-123", gomock.Any(), gomock.Any(), "completed", "", gomock.Any()). Return(nil) }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when job processing fails", @@ -297,8 +300,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { WriteJobResponse(gomock.Any(), "test-job-456", gomock.Any(), gomock.Any(), "failed", gomock.Any(), gomock.Any()). Return(nil) }, - expectError: true, - errorMsg: "job processing failed", + validateFunc: func(err error) { + s.Error(err) + if "job processing failed" != "" { + s.Contains(err.Error(), "job processing failed") + } + }, }, { name: "when invalid subject format", @@ -308,8 +315,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { setupMocks: func() { // No mocks needed as it should fail early }, - expectError: true, - errorMsg: "failed to parse subject", + validateFunc: func(err error) { + s.Error(err) + if "failed to parse subject" != "" { + s.Contains(err.Error(), "failed to parse subject") + } + }, }, { name: "when job not found", @@ -321,8 +332,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { GetJobData(gomock.Any(), "jobs.nonexistent-job"). Return(nil, errors.New("job not found")) }, - expectError: true, - errorMsg: "job not found", + validateFunc: func(err error) { + s.Error(err) + if "job not found" != "" { + s.Contains(err.Error(), "job not found") + } + }, }, { name: "when invalid job data format", @@ -334,8 +349,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { GetJobData(gomock.Any(), "jobs.invalid-job"). Return([]byte(`invalid json`), nil) }, - expectError: true, - errorMsg: "failed to parse job data", + validateFunc: func(err error) { + s.Error(err) + if "failed to parse job data" != "" { + s.Contains(err.Error(), "failed to parse job data") + } + }, }, { name: "when missing job ID", @@ -352,8 +371,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { } }`), nil) }, - expectError: true, - errorMsg: "invalid job format: missing id", + validateFunc: func(err error) { + s.Error(err) + if "invalid job format: missing id" != "" { + s.Contains(err.Error(), "invalid job format: missing id") + } + }, }, { name: "when missing operation", @@ -367,8 +390,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { "id": "missing-op-job" }`), nil) }, - expectError: true, - errorMsg: "invalid job format: missing operation", + validateFunc: func(err error) { + s.Error(err) + if "invalid job format: missing operation" != "" { + s.Contains(err.Error(), "invalid job format: missing operation") + } + }, }, { name: "when missing operation type", @@ -385,8 +412,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { } }`), nil) }, - expectError: true, - errorMsg: "invalid operation format: missing type field", + validateFunc: func(err error) { + s.Error(err) + if "invalid operation format: missing type field" != "" { + s.Contains(err.Error(), "invalid operation format: missing type field") + } + }, }, { name: "when invalid operation type format", @@ -404,8 +435,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { } }`), nil) }, - expectError: true, - errorMsg: "invalid operation type format", + validateFunc: func(err error) { + s.Error(err) + if "invalid operation type format" != "" { + s.Contains(err.Error(), "invalid operation type format") + } + }, }, { name: "when acknowledged write error logged", @@ -439,7 +474,9 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { WriteJobResponse(gomock.Any(), "ack-err-job", gomock.Any(), gomock.Any(), "completed", "", gomock.Any()). Return(nil) }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when started write error logged", @@ -473,7 +510,9 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { WriteJobResponse(gomock.Any(), "start-err-job", gomock.Any(), gomock.Any(), "completed", "", gomock.Any()). Return(nil) }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when completed write error logged", @@ -507,7 +546,9 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { WriteJobResponse(gomock.Any(), "comp-err-job", gomock.Any(), gomock.Any(), "completed", "", gomock.Any()). Return(nil) }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when failed write error logged", @@ -541,8 +582,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { WriteJobResponse(gomock.Any(), "fail-err-job", gomock.Any(), gomock.Any(), "failed", gomock.Any(), gomock.Any()). Return(nil) }, - expectError: true, - errorMsg: "job processing failed", + validateFunc: func(err error) { + s.Error(err) + if "job processing failed" != "" { + s.Contains(err.Error(), "job processing failed") + } + }, }, { name: "when processor returns ErrUnsupported sets skipped status", @@ -588,7 +633,9 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { WriteJobResponse(gomock.Any(), "skip-job", gomock.Any(), gomock.Any(), "skipped", gomock.Any(), gomock.Any()). Return(nil) }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when skipped write error logged", @@ -632,7 +679,9 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { WriteJobResponse(gomock.Any(), "skip-err-job", gomock.Any(), gomock.Any(), "skipped", gomock.Any(), gomock.Any()). Return(nil) }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when fact reference resolved in job data", @@ -670,7 +719,9 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { WriteJobResponse(gomock.Any(), "fact-resolve-job", gomock.Any(), gomock.Any(), "completed", "", gomock.Any()). Return(nil) }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when fact reference with nil cached facts writes error to KV", @@ -706,8 +757,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { WriteJobResponse(gomock.Any(), "fact-nil-job", gomock.Any(), gomock.Any(), "failed", gomock.Any(), gomock.Any()). Return(nil) }, - expectError: true, - errorMsg: "facts not available", + validateFunc: func(err error) { + s.Error(err) + if "facts not available" != "" { + s.Contains(err.Error(), "facts not available") + } + }, }, { name: "when unresolvable fact reference writes error to KV", @@ -743,8 +798,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { WriteJobResponse(gomock.Any(), "fact-fail-job", gomock.Any(), gomock.Any(), "failed", gomock.Any(), gomock.Any()). Return(nil) }, - expectError: true, - errorMsg: "failed to resolve fact references", + validateFunc: func(err error) { + s.Error(err) + if "failed to resolve fact references" != "" { + s.Contains(err.Error(), "failed to resolve fact references") + } + }, }, { name: "when response storage failure", @@ -777,8 +836,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { WriteJobResponse(gomock.Any(), "storage-fail-job", gomock.Any(), gomock.Any(), "completed", "", gomock.Any()). Return(errors.New("storage failure")) }, - expectError: true, - errorMsg: "failed to store job response", + validateFunc: func(err error) { + s.Error(err) + if "failed to store job response" != "" { + s.Contains(err.Error(), "failed to store job response") + } + }, }, } @@ -787,27 +850,18 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessage() { tt.setupMocks() msg := tt.setupMsg(s.mockCtrl) - err := agent.ExportHandleJobMessage(s.testAgent, msg) - - if tt.expectError { - s.Error(err) - if tt.errorMsg != "" { - s.Contains(err.Error(), tt.errorMsg) - } - } else { - s.NoError(err) - } + tt.validateFunc(agent.ExportHandleJobMessage(s.testAgent, msg)) }) } } func (s *HandlerPublicTestSuite) TestHandleJobMessageModifyJobs() { tests := []struct { - name string - subject string - jobData string - setupMocks func() - expectError bool + name string + subject string + jobData string + setupMocks func() + validateFunc func(error) }{ { name: "when modify job type identification", @@ -857,7 +911,9 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessageModifyJobs() { ). Return(nil) }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, } @@ -866,52 +922,58 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessageModifyJobs() { tt.setupMocks() msg := newTestMsg(s.mockCtrl, tt.subject, []byte("modify-job-123")) - err := agent.ExportHandleJobMessage(s.testAgent, msg) - - if tt.expectError { - s.Error(err) - } else { - s.NoError(err) - } + tt.validateFunc(agent.ExportHandleJobMessage(s.testAgent, msg)) }) } } func (s *HandlerPublicTestSuite) TestExtractChanged() { tests := []struct { - name string - data json.RawMessage - want *bool + name string + data json.RawMessage + validateFunc func(*bool) }{ { name: "when empty data returns nil", data: nil, - want: nil, + validateFunc: func(got *bool) { + s.Equal((*bool)(nil), got) + }, }, { name: "when invalid JSON returns nil", data: json.RawMessage(`not json`), - want: nil, + validateFunc: func(got *bool) { + s.Equal((*bool)(nil), got) + }, }, { name: "when changed key missing returns nil", data: json.RawMessage(`{"success":true}`), - want: nil, + validateFunc: func(got *bool) { + s.Equal((*bool)(nil), got) + }, }, { name: "when changed is non-bool returns nil", data: json.RawMessage(`{"changed":"yes"}`), - want: nil, + validateFunc: func(got *bool) { + s.Equal((*bool)(nil), got) + }, }, { name: "when changed is true returns true", data: json.RawMessage(`{"changed":true}`), - want: boolPtr(true), + validateFunc: func(got *bool) { + s.Equal(ptr.To(true), got) + }, }, { name: "when changed is false returns false", data: json.RawMessage(`{"changed":false}`), - want: boolPtr(false), + validateFunc: func(got *bool) { + s.Equal(ptr.To(false), got) + }, }, } @@ -919,7 +981,7 @@ func (s *HandlerPublicTestSuite) TestExtractChanged() { s.Run(tt.name, func() { got := agent.ExportExtractChanged(tt.data) - s.Equal(tt.want, got) + tt.validateFunc(got) }) } } @@ -930,12 +992,12 @@ func (s *HandlerPublicTestSuite) TestUnwrapJobEnvelope() { s.Require().NoError(err) tests := []struct { - name string - setupPKI func() *pki.Manager - data func() []byte - wantPayload string - expectError bool - errorMsg string + name string + setupPKI func() *pki.Manager + data func() []byte + expectError bool + errorMsg string + validateFunc func(string) }{ { name: "when PKI disabled passes through raw data", @@ -945,8 +1007,10 @@ func (s *HandlerPublicTestSuite) TestUnwrapJobEnvelope() { data: func() []byte { return []byte(`{"id":"test","operation":{"type":"node.hostname.get"}}`) }, - wantPayload: `{"id":"test","operation":{"type":"node.hostname.get"}}`, expectError: false, + validateFunc: func(got string) { + s.Equal(`{"id":"test","operation":{"type":"node.hostname.get"}}`, got) + }, }, { name: "when valid signed envelope with correct controller key", @@ -967,8 +1031,10 @@ func (s *HandlerPublicTestSuite) TestUnwrapJobEnvelope() { data, _ := json.Marshal(envelope) return data }, - wantPayload: `{"id":"signed-test"}`, expectError: false, + validateFunc: func(got string) { + s.Equal(`{"id":"signed-test"}`, got) + }, }, { name: "when signed envelope with invalid signature", @@ -990,9 +1056,11 @@ func (s *HandlerPublicTestSuite) TestUnwrapJobEnvelope() { data, _ := json.Marshal(envelope) return data }, - wantPayload: "", expectError: true, errorMsg: "invalid controller signature", + validateFunc: func(got string) { + s.Equal("", got) + }, }, { name: "when signed envelope without controller key skips verification", @@ -1013,8 +1081,10 @@ func (s *HandlerPublicTestSuite) TestUnwrapJobEnvelope() { data, _ := json.Marshal(envelope) return data }, - wantPayload: `{"id":"no-ctrl-key"}`, expectError: false, + validateFunc: func(got string) { + s.Equal(`{"id":"no-ctrl-key"}`, got) + }, }, { name: "when raw JSON with PKI enabled passes through", @@ -1027,8 +1097,10 @@ func (s *HandlerPublicTestSuite) TestUnwrapJobEnvelope() { data: func() []byte { return []byte(`{"id":"raw-job","operation":{"type":"node.hostname.get"}}`) }, - wantPayload: `{"id":"raw-job","operation":{"type":"node.hostname.get"}}`, expectError: false, + validateFunc: func(got string) { + s.Equal(`{"id":"raw-job","operation":{"type":"node.hostname.get"}}`, got) + }, }, { name: "when invalid JSON with PKI enabled passes through", @@ -1040,8 +1112,10 @@ func (s *HandlerPublicTestSuite) TestUnwrapJobEnvelope() { data: func() []byte { return []byte(`not json at all`) }, - wantPayload: "not json at all", expectError: false, + validateFunc: func(got string) { + s.Equal("not json at all", got) + }, }, } @@ -1063,7 +1137,7 @@ func (s *HandlerPublicTestSuite) TestUnwrapJobEnvelope() { } s.NoError(err) - s.Equal(tt.wantPayload, string(result)) + tt.validateFunc(string(result)) }) } } @@ -1074,13 +1148,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessageWithSignedEnvelope() { s.Require().NoError(err) tests := []struct { - name string - setupPKI func() - cleanupPKI func() - setupMsg func(ctrl *gomock.Controller) jetstream.Msg - setupMocks func() - expectError bool - errorMsg string + name string + setupPKI func() + cleanupPKI func() + setupMsg func(ctrl *gomock.Controller) jetstream.Msg + setupMocks func() + validateFunc func(error) }{ { name: "when signed job data processed successfully", @@ -1126,7 +1199,9 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessageWithSignedEnvelope() { WriteJobResponse(gomock.Any(), "signed-job-ok", gomock.Any(), gomock.Any(), "completed", "", gomock.Any()). Return(nil) }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when signed job data with invalid signature fails", @@ -1158,8 +1233,12 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessageWithSignedEnvelope() { GetJobData(gomock.Any(), "jobs.bad-sig-job"). Return(envelopeJSON, nil) }, - expectError: true, - errorMsg: "job signature verification failed", + validateFunc: func(err error) { + s.Error(err) + if "job signature verification failed" != "" { + s.Contains(err.Error(), "job signature verification failed") + } + }, }, } @@ -1170,22 +1249,13 @@ func (s *HandlerPublicTestSuite) TestHandleJobMessageWithSignedEnvelope() { tt.setupMocks() msg := tt.setupMsg(s.mockCtrl) - err := agent.ExportHandleJobMessage(s.testAgent, msg) - - if tt.expectError { - s.Error(err) - if tt.errorMsg != "" { - s.Contains(err.Error(), tt.errorMsg) - } - } else { - s.NoError(err) - } + tt.validateFunc(agent.ExportHandleJobMessage(s.testAgent, msg)) }) } } -func boolPtr(b bool) *bool { return &b } - -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/agent/heartbeat_public_test.go b/internal/agent/heartbeat_public_test.go index 1d13ab825..dfaf1909d 100644 --- a/internal/agent/heartbeat_public_test.go +++ b/internal/agent/heartbeat_public_test.go @@ -30,6 +30,7 @@ import ( "github.com/avfs/avfs" "github.com/avfs/avfs/vfs/memfs" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -219,7 +220,9 @@ func (s *HeartbeatPublicTestSuite) TestStartWithHeartbeat() { } } -func TestHeartbeatPublicTestSuite(t *testing.T) { +func TestHeartbeatPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HeartbeatPublicTestSuite)) } @@ -376,10 +379,18 @@ func (s *HeartbeatLowLevelPublicTestSuite) TestWriteRegistration() { func (s *HeartbeatLowLevelPublicTestSuite) TestWriteRegistrationStoresHeartbeatTime() { tests := []struct { - name string + name string + validateFunc func(time.Time, time.Time, time.Time) }{ { name: "when Put succeeds stores last heartbeat time", + validateFunc: func(got, before, after time.Time) { + s.False(got.IsZero(), "expected non-zero heartbeat time after successful Put") + s.True( + !got.Before(before) && !got.After(after), + "heartbeat time should be between before and after write", + ) + }, }, } @@ -399,19 +410,16 @@ func (s *HeartbeatLowLevelPublicTestSuite) TestWriteRegistrationStoresHeartbeatT after := time.Now() got := s.testAgent.LastHeartbeatTime() - s.False(got.IsZero(), "expected non-zero heartbeat time after successful Put") - s.True( - !got.Before(before) && !got.After(after), - "heartbeat time should be between before and after write", - ) + tt.validateFunc(got, before, after) }) } } func (s *HeartbeatLowLevelPublicTestSuite) TestDeregister() { tests := []struct { - name string - setupMock func() + name string + setupMock func() + validateFunc func(assert.PanicTestFunc) }{ { name: "when Delete fails logs warning", @@ -420,6 +428,9 @@ func (s *HeartbeatLowLevelPublicTestSuite) TestDeregister() { Delete(gomock.Any(), "agents.test_machine_id"). Return(errors.New("delete failed")) }, + validateFunc: func(deregister assert.PanicTestFunc) { + s.NotPanics(deregister) + }, }, { name: "when Delete succeeds logs deregistration", @@ -428,18 +439,22 @@ func (s *HeartbeatLowLevelPublicTestSuite) TestDeregister() { Delete(gomock.Any(), "agents.test_machine_id"). Return(nil) }, + validateFunc: func(deregister assert.PanicTestFunc) { + s.NotPanics(deregister) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { tt.setupMock() + // Deregister is best-effort (fire-and-forget). It deletes a // KV key and logs the outcome but does not mutate agent state. // The gomock expectations above verify the correct KV call was // made; beyond that, we only verify the function completes // without panicking. - s.NotPanics(func() { + tt.validateFunc(func() { agent.ExportDeregister(s.testAgent, "test-machine-id") }) }) @@ -500,18 +515,25 @@ func (s *HeartbeatLowLevelPublicTestSuite) TestStartHeartbeatHostnameChange() { initialHostname string hostnameReply string expectChanged bool + validateFunc func(any) }{ { name: "when hostname changes updates cached hostname", initialHostname: "old-host", hostnameReply: "new-host", expectChanged: true, + validateFunc: func(got any) { + s.Equal("new-host", got) + }, }, { name: "when hostname unchanged does not resubscribe", initialHostname: "same-host", hostnameReply: "same-host", expectChanged: false, + validateFunc: func(got any) { + s.Equal("same-host", got) + }, }, } @@ -589,38 +611,43 @@ func (s *HeartbeatLowLevelPublicTestSuite) TestStartHeartbeatHostnameChange() { // Wait for goroutine to finish agent.WaitAgentWG(testAgent) - got := agent.GetAgentHostname(testAgent) - s.Equal(tt.hostnameReply, got) + tt.validateFunc(agent.GetAgentHostname(testAgent)) }) } } func (s *HeartbeatLowLevelPublicTestSuite) TestRegistryKey() { tests := []struct { - name string - machineID string - expected string + name string + machineID string + validateFunc func(string) }{ { name: "simple machine ID", machineID: "abc-123-def", - expected: "agents.abc_123_def", + validateFunc: func(got string) { + s.Equal("agents.abc_123_def", got) + }, }, { name: "machine ID with dots", machineID: "A1B2C3D4-E5F6.7890", - expected: "agents.A1B2C3D4_E5F6_7890", + validateFunc: func(got string) { + s.Equal("agents.A1B2C3D4_E5F6_7890", got) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { result := agent.ExportRegistryKey(tt.machineID) - s.Equal(tt.expected, result) + tt.validateFunc(result) }) } } -func TestHeartbeatLowLevelPublicTestSuite(t *testing.T) { +func TestHeartbeatLowLevelPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HeartbeatLowLevelPublicTestSuite)) } diff --git a/internal/agent/identity/export_test.go b/internal/agent/identity/export_test.go index bf7f8bab3..2e21bf56d 100644 --- a/internal/agent/identity/export_test.go +++ b/internal/agent/identity/export_test.go @@ -27,7 +27,9 @@ import ( ) // SetIoregFn overrides the ioregFn function for testing. -func SetIoregFn(fn func() (string, error)) { +func SetIoregFn( + fn func() (string, error), +) { ioregFn = fn } @@ -37,7 +39,9 @@ func ResetIoregFn() { } // SetExecCommandFn overrides the execCommandFn function for testing. -func SetExecCommandFn(fn func() ([]byte, error)) { +func SetExecCommandFn( + fn func() ([]byte, error), +) { execCommandFn = fn } @@ -47,7 +51,9 @@ func ResetExecCommandFn() { } // SetGetMachineIDFn overrides the getMachineIDFn function for testing. -func SetGetMachineIDFn(fn func(avfs.VFS) (string, error)) { +func SetGetMachineIDFn( + fn func(avfs.VFS) (string, error), +) { getMachineIDFn = fn } @@ -62,12 +68,16 @@ func ExportDefaultIoregFn() (string, error) { } // ExportDefaultGetMachineID exposes defaultGetMachineID for testing. -func ExportDefaultGetMachineID(fs avfs.VFS) (string, error) { +func ExportDefaultGetMachineID( + fs avfs.VFS, +) (string, error) { return defaultGetMachineID(fs) } // SetOSPlatform overrides the osPlatform variable for testing. -func SetOSPlatform(platform string) { +func SetOSPlatform( + platform string, +) { osPlatform = platform } diff --git a/internal/agent/identity/identity_public_test.go b/internal/agent/identity/identity_public_test.go index 57d28b192..d6eccdcb9 100644 --- a/internal/agent/identity/identity_public_test.go +++ b/internal/agent/identity/identity_public_test.go @@ -46,9 +46,7 @@ func (suite *GetMachineIDFromFSPublicTestSuite) TestGetMachineIDFromFS() { tests := []struct { name string setupFS func(fs avfs.VFS) - wantID string - wantErr bool - wantContains string + validateFunc func(string, error) }{ { name: "when valid machine-id file exists", @@ -56,7 +54,10 @@ func (suite *GetMachineIDFromFSPublicTestSuite) TestGetMachineIDFromFS() { _ = fs.MkdirAll("/etc", 0o755) _ = fs.WriteFile("/etc/machine-id", []byte("abc123def456\n"), 0o444) }, - wantID: "abc123def456", + validateFunc: func(got string, err error) { + require.NoError(suite.T(), err) + assert.Equal(suite.T(), "abc123def456", got) + }, }, { name: "when machine-id has leading and trailing whitespace", @@ -64,15 +65,21 @@ func (suite *GetMachineIDFromFSPublicTestSuite) TestGetMachineIDFromFS() { _ = fs.MkdirAll("/etc", 0o755) _ = fs.WriteFile("/etc/machine-id", []byte(" abc123def456 \n"), 0o444) }, - wantID: "abc123def456", + validateFunc: func(got string, err error) { + require.NoError(suite.T(), err) + assert.Equal(suite.T(), "abc123def456", got) + }, }, { name: "when machine-id file does not exist", setupFS: func(_ avfs.VFS) { // no file created }, - wantErr: true, - wantContains: "read machine-id", + validateFunc: func(got string, err error) { + require.Error(suite.T(), err) + assert.Contains(suite.T(), err.Error(), "read machine-id") + assert.Empty(suite.T(), got) + }, }, { name: "when machine-id file is empty", @@ -80,8 +87,11 @@ func (suite *GetMachineIDFromFSPublicTestSuite) TestGetMachineIDFromFS() { _ = fs.MkdirAll("/etc", 0o755) _ = fs.WriteFile("/etc/machine-id", []byte(""), 0o444) }, - wantErr: true, - wantContains: "empty machine-id", + validateFunc: func(got string, err error) { + require.Error(suite.T(), err) + assert.Contains(suite.T(), err.Error(), "empty machine-id") + assert.Empty(suite.T(), got) + }, }, { name: "when machine-id file contains only whitespace", @@ -89,8 +99,11 @@ func (suite *GetMachineIDFromFSPublicTestSuite) TestGetMachineIDFromFS() { _ = fs.MkdirAll("/etc", 0o755) _ = fs.WriteFile("/etc/machine-id", []byte(" \n\t\n"), 0o444) }, - wantErr: true, - wantContains: "empty machine-id", + validateFunc: func(got string, err error) { + require.Error(suite.T(), err) + assert.Contains(suite.T(), err.Error(), "empty machine-id") + assert.Empty(suite.T(), got) + }, }, } @@ -99,21 +112,14 @@ func (suite *GetMachineIDFromFSPublicTestSuite) TestGetMachineIDFromFS() { fs := memfs.New() tc.setupFS(fs) - got, err := identity.GetMachineIDFromFS(fs) - - if tc.wantErr { - require.Error(suite.T(), err) - assert.Contains(suite.T(), err.Error(), tc.wantContains) - assert.Empty(suite.T(), got) - } else { - require.NoError(suite.T(), err) - assert.Equal(suite.T(), tc.wantID, got) - } + tc.validateFunc(identity.GetMachineIDFromFS(fs)) }) } } -func TestGetMachineIDFromFSPublicTestSuite(t *testing.T) { +func TestGetMachineIDFromFSPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(GetMachineIDFromFSPublicTestSuite)) } @@ -131,9 +137,7 @@ func (suite *GetDarwinMachineIDPublicTestSuite) TestGetDarwinMachineID() { name string ioregOutput string ioregErr error - wantID string - wantErr bool - wantContains string + validateFunc func(string, error) }{ { name: "when ioreg returns valid UUID", @@ -142,13 +146,19 @@ func (suite *GetDarwinMachineIDPublicTestSuite) TestGetDarwinMachineID() { "IOPlatformUUID" = "12345678-ABCD-EFGH-IJKL-123456789ABC" } `, - wantID: "12345678-ABCD-EFGH-IJKL-123456789ABC", + validateFunc: func(got string, err error) { + require.NoError(suite.T(), err) + assert.Equal(suite.T(), "12345678-ABCD-EFGH-IJKL-123456789ABC", got) + }, }, { - name: "when ioreg command fails", - ioregErr: fmt.Errorf("command not found"), - wantErr: true, - wantContains: "run ioreg", + name: "when ioreg command fails", + ioregErr: fmt.Errorf("command not found"), + validateFunc: func(got string, err error) { + require.Error(suite.T(), err) + assert.Contains(suite.T(), err.Error(), "run ioreg") + assert.Empty(suite.T(), got) + }, }, { name: "when ioreg output has no UUID", @@ -157,8 +167,11 @@ func (suite *GetDarwinMachineIDPublicTestSuite) TestGetDarwinMachineID() { "SomeOtherKey" = "value" } `, - wantErr: true, - wantContains: "IOPlatformUUID not found", + validateFunc: func(got string, err error) { + require.Error(suite.T(), err) + assert.Contains(suite.T(), err.Error(), "IOPlatformUUID not found") + assert.Empty(suite.T(), got) + }, }, } @@ -168,21 +181,14 @@ func (suite *GetDarwinMachineIDPublicTestSuite) TestGetDarwinMachineID() { return tc.ioregOutput, tc.ioregErr }) - got, err := identity.GetDarwinMachineID() - - if tc.wantErr { - require.Error(suite.T(), err) - assert.Contains(suite.T(), err.Error(), tc.wantContains) - assert.Empty(suite.T(), got) - } else { - require.NoError(suite.T(), err) - assert.Equal(suite.T(), tc.wantID, got) - } + tc.validateFunc(identity.GetDarwinMachineID()) }) } } -func TestGetDarwinMachineIDPublicTestSuite(t *testing.T) { +func TestGetDarwinMachineIDPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(GetDarwinMachineIDPublicTestSuite)) } @@ -197,14 +203,10 @@ func (suite *GetIdentityPublicTestSuite) TearDownSubTest() { func (suite *GetIdentityPublicTestSuite) TestGetIdentity() { tests := []struct { - name string - configHostname string - machineIDFn func(avfs.VFS) (string, error) - wantMachineID string - wantHostname string - wantErr bool - wantContains string - hostnameNonZero bool + name string + configHostname string + machineIDFn func(avfs.VFS) (string, error) + validateFunc func(*identity.Identity, error) }{ { name: "when config hostname is provided and machine-id succeeds", @@ -212,8 +214,12 @@ func (suite *GetIdentityPublicTestSuite) TestGetIdentity() { machineIDFn: func(_ avfs.VFS) (string, error) { return "abc123", nil }, - wantMachineID: "abc123", - wantHostname: "my-host", + validateFunc: func(got *identity.Identity, err error) { + require.NoError(suite.T(), err) + require.NotNil(suite.T(), got) + assert.Equal(suite.T(), "abc123", got.MachineID) + assert.Equal(suite.T(), "my-host", got.Hostname) + }, }, { name: "when config hostname is empty falls back to system hostname", @@ -221,8 +227,12 @@ func (suite *GetIdentityPublicTestSuite) TestGetIdentity() { machineIDFn: func(_ avfs.VFS) (string, error) { return "abc123", nil }, - wantMachineID: "abc123", - hostnameNonZero: true, + validateFunc: func(got *identity.Identity, err error) { + require.NoError(suite.T(), err) + require.NotNil(suite.T(), got) + assert.Equal(suite.T(), "abc123", got.MachineID) + assert.NotEmpty(suite.T(), got.Hostname) + }, }, { name: "when machine-id resolution fails", @@ -230,8 +240,11 @@ func (suite *GetIdentityPublicTestSuite) TestGetIdentity() { machineIDFn: func(_ avfs.VFS) (string, error) { return "", fmt.Errorf("read machine-id: file not found") }, - wantErr: true, - wantContains: "machine-id", + validateFunc: func(got *identity.Identity, err error) { + require.Error(suite.T(), err) + assert.Contains(suite.T(), err.Error(), "machine-id") + assert.Nil(suite.T(), got) + }, }, } @@ -243,27 +256,14 @@ func (suite *GetIdentityPublicTestSuite) TestGetIdentity() { identity.SetGetMachineIDFn(tc.machineIDFn) } - got, err := identity.GetIdentity(fs, tc.configHostname) - - if tc.wantErr { - require.Error(suite.T(), err) - assert.Contains(suite.T(), err.Error(), tc.wantContains) - assert.Nil(suite.T(), got) - } else { - require.NoError(suite.T(), err) - require.NotNil(suite.T(), got) - assert.Equal(suite.T(), tc.wantMachineID, got.MachineID) - if tc.hostnameNonZero { - assert.NotEmpty(suite.T(), got.Hostname) - } else { - assert.Equal(suite.T(), tc.wantHostname, got.Hostname) - } - } + tc.validateFunc(identity.GetIdentity(fs, tc.configHostname)) }) } } -func TestGetIdentityPublicTestSuite(t *testing.T) { +func TestGetIdentityPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(GetIdentityPublicTestSuite)) } @@ -285,13 +285,15 @@ func (suite *PlatformPublicTestSuite) TestDefaultIoregFn() { name string setupFn func() skipUnless string - wantErr bool - wantContains string + validateFunc func(string, error) }{ { - name: "when ioreg command succeeds on macOS", - skipUnless: "darwin", - wantContains: "IOPlatformUUID", + name: "when ioreg command succeeds on macOS", + skipUnless: "darwin", + validateFunc: func(out string, err error) { + require.NoError(suite.T(), err) + assert.Contains(suite.T(), out, "IOPlatformUUID") + }, }, { name: "when exec command fails returns error", @@ -300,7 +302,10 @@ func (suite *PlatformPublicTestSuite) TestDefaultIoregFn() { return nil, fmt.Errorf("exec: command not found") }) }, - wantErr: true, + validateFunc: func(out string, err error) { + require.Error(suite.T(), err) + assert.Empty(suite.T(), out) + }, }, } @@ -314,15 +319,7 @@ func (suite *PlatformPublicTestSuite) TestDefaultIoregFn() { tc.setupFn() } - out, err := identity.ExportDefaultIoregFn() - - if tc.wantErr { - require.Error(suite.T(), err) - assert.Empty(suite.T(), out) - } else { - require.NoError(suite.T(), err) - assert.Contains(suite.T(), out, tc.wantContains) - } + tc.validateFunc(identity.ExportDefaultIoregFn()) }) } } @@ -333,9 +330,7 @@ func (suite *PlatformPublicTestSuite) TestDefaultGetMachineID() { platform string setupFS func(fs avfs.VFS) setupFn func() - wantErr bool - wantContains string - wantNonEmpty bool + validateFunc func(string, error) }{ { name: "when platform is darwin returns machine ID", @@ -346,7 +341,10 @@ func (suite *PlatformPublicTestSuite) TestDefaultGetMachineID() { return `"IOPlatformUUID" = "FAKE-UUID-1234"`, nil }) }, - wantNonEmpty: true, + validateFunc: func(got string, err error) { + require.NoError(suite.T(), err) + assert.NotEmpty(suite.T(), got) + }, }, { name: "when platform is linux reads /etc/machine-id", @@ -355,16 +353,21 @@ func (suite *PlatformPublicTestSuite) TestDefaultGetMachineID() { _ = fs.MkdirAll("/etc", 0o755) _ = fs.WriteFile("/etc/machine-id", []byte("abc123\n"), 0o444) }, - setupFn: func() {}, - wantNonEmpty: true, + setupFn: func() {}, + validateFunc: func(got string, err error) { + require.NoError(suite.T(), err) + assert.NotEmpty(suite.T(), got) + }, }, { - name: "when platform is unsupported returns error", - platform: "windows", - setupFS: func(_ avfs.VFS) {}, - setupFn: func() {}, - wantErr: true, - wantContains: "unsupported platform: windows", + name: "when platform is unsupported returns error", + platform: "windows", + setupFS: func(_ avfs.VFS) {}, + setupFn: func() {}, + validateFunc: func(_ string, err error) { + require.Error(suite.T(), err) + assert.Contains(suite.T(), err.Error(), "unsupported platform: windows") + }, }, } @@ -377,21 +380,13 @@ func (suite *PlatformPublicTestSuite) TestDefaultGetMachineID() { tc.setupFn() } - got, err := identity.ExportDefaultGetMachineID(fs) - - if tc.wantErr { - require.Error(suite.T(), err) - assert.Contains(suite.T(), err.Error(), tc.wantContains) - } else { - require.NoError(suite.T(), err) - if tc.wantNonEmpty { - assert.NotEmpty(suite.T(), got) - } - } + tc.validateFunc(identity.ExportDefaultGetMachineID(fs)) }) } } -func TestPlatformPublicTestSuite(t *testing.T) { +func TestPlatformPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PlatformPublicTestSuite)) } diff --git a/internal/agent/pki/keypair_public_test.go b/internal/agent/pki/keypair_public_test.go index 73838cc8b..cef548860 100644 --- a/internal/agent/pki/keypair_public_test.go +++ b/internal/agent/pki/keypair_public_test.go @@ -291,18 +291,22 @@ func (suite *KeypairPublicTestSuite) TestSignAndVerify() { name string data []byte tamper bool - wantVerified bool + validateFunc func(bool) }{ { - name: "when data is signed and verified", - data: []byte("hello world"), - wantVerified: true, + name: "when data is signed and verified", + data: []byte("hello world"), + validateFunc: func(got bool) { + assert.Equal(suite.T(), true, got) + }, }, { - name: "when data is tampered after signing", - data: []byte("hello world"), - tamper: true, - wantVerified: false, + name: "when data is tampered after signing", + data: []byte("hello world"), + tamper: true, + validateFunc: func(got bool) { + assert.Equal(suite.T(), false, got) + }, }, } @@ -321,7 +325,7 @@ func (suite *KeypairPublicTestSuite) TestSignAndVerify() { } got := pki.Verify(m.PublicKey(), verifyData, sig) - assert.Equal(suite.T(), tc.wantVerified, got) + tc.validateFunc(got) }) } } @@ -470,7 +474,9 @@ func (suite *KeypairPublicTestSuite) TestParsePublicKeyPEM() { } } -func TestKeypairPublicTestSuite(t *testing.T) { +func TestKeypairPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(KeypairPublicTestSuite)) } diff --git a/internal/agent/pki/rotation_public_test.go b/internal/agent/pki/rotation_public_test.go index 28ac40bae..f82e1c3c8 100644 --- a/internal/agent/pki/rotation_public_test.go +++ b/internal/agent/pki/rotation_public_test.go @@ -41,7 +41,7 @@ func (suite *RotationPublicTestSuite) TestVerifyWithGrace() { tests := []struct { name string setup func(m *pki.Manager) (data []byte, sig []byte) - wantVerified bool + validateFunc func(bool) }{ { name: "when signed with current controller key returns true", @@ -52,7 +52,9 @@ func (suite *RotationPublicTestSuite) TestVerifyWithGrace() { sig := ed25519.Sign(priv, data) return data, sig }, - wantVerified: true, + validateFunc: func(got bool) { + assert.Equal(suite.T(), true, got) + }, }, { name: "when signed with previous controller key returns true", @@ -65,7 +67,9 @@ func (suite *RotationPublicTestSuite) TestVerifyWithGrace() { sig := ed25519.Sign(oldPriv, data) return data, sig }, - wantVerified: true, + validateFunc: func(got bool) { + assert.Equal(suite.T(), true, got) + }, }, { name: "when signed with both keys set and current key matches returns true", @@ -78,7 +82,9 @@ func (suite *RotationPublicTestSuite) TestVerifyWithGrace() { sig := ed25519.Sign(newPriv, data) return data, sig }, - wantVerified: true, + validateFunc: func(got bool) { + assert.Equal(suite.T(), true, got) + }, }, { name: "when neither key is set returns false", @@ -88,7 +94,9 @@ func (suite *RotationPublicTestSuite) TestVerifyWithGrace() { sig := ed25519.Sign(priv, data) return data, sig }, - wantVerified: false, + validateFunc: func(got bool) { + assert.Equal(suite.T(), false, got) + }, }, { name: "when signature does not match any key returns false", @@ -102,7 +110,9 @@ func (suite *RotationPublicTestSuite) TestVerifyWithGrace() { sig := ed25519.Sign(unrelatedPriv, data) return data, sig }, - wantVerified: false, + validateFunc: func(got bool) { + assert.Equal(suite.T(), false, got) + }, }, { name: "when only current key is set and signature does not match returns false", @@ -114,7 +124,9 @@ func (suite *RotationPublicTestSuite) TestVerifyWithGrace() { sig := ed25519.Sign(wrongPriv, data) return data, sig }, - wantVerified: false, + validateFunc: func(got bool) { + assert.Equal(suite.T(), false, got) + }, }, } @@ -125,7 +137,7 @@ func (suite *RotationPublicTestSuite) TestVerifyWithGrace() { data, sig := tc.setup(m) got := m.VerifyWithGrace(data, sig) - assert.Equal(suite.T(), tc.wantVerified, got) + tc.validateFunc(got) }) } } @@ -251,7 +263,9 @@ func (suite *RotationPublicTestSuite) TestPreviousControllerPublicKey() { } } -func TestRotationPublicTestSuite(t *testing.T) { +func TestRotationPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(RotationPublicTestSuite)) } diff --git a/internal/agent/pki/types_public_test.go b/internal/agent/pki/types_public_test.go index 2f0be1cee..afc85748a 100644 --- a/internal/agent/pki/types_public_test.go +++ b/internal/agent/pki/types_public_test.go @@ -35,70 +35,86 @@ type TypesPublicTestSuite struct { func (suite *TypesPublicTestSuite) TestSubjectConstants() { tests := []struct { - name string - constant string - expected string + name string + constant string + validateFunc func(string) }{ { name: "EnrollRequestSuffix has correct value", constant: pki.EnrollRequestSuffix, - expected: "enroll.request", + validateFunc: func(got string) { + assert.Equal(suite.T(), "enroll.request", got) + }, }, { name: "EnrollResponsePrefix has correct value", constant: pki.EnrollResponsePrefix, - expected: "enroll.response", + validateFunc: func(got string) { + assert.Equal(suite.T(), "enroll.response", got) + }, }, { name: "PKIRotateSuffix has correct value", constant: pki.PKIRotateSuffix, - expected: "pki.rotate", + validateFunc: func(got string) { + assert.Equal(suite.T(), "pki.rotate", got) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - assert.Equal(suite.T(), tc.expected, tc.constant) + tc.validateFunc(tc.constant) }) } } func (suite *TypesPublicTestSuite) TestEnrollmentStateValues() { tests := []struct { - name string - state pki.EnrollmentState - expected string + name string + state pki.EnrollmentState + validateFunc func(string) }{ { - name: "StateUnregistered", - state: pki.StateUnregistered, - expected: "unregistered", + name: "StateUnregistered", + state: pki.StateUnregistered, + validateFunc: func(got string) { + assert.Equal(suite.T(), "unregistered", got) + }, }, { - name: "StatePending", - state: pki.StatePending, - expected: "pending", + name: "StatePending", + state: pki.StatePending, + validateFunc: func(got string) { + assert.Equal(suite.T(), "pending", got) + }, }, { - name: "StateAccepted", - state: pki.StateAccepted, - expected: "accepted", + name: "StateAccepted", + state: pki.StateAccepted, + validateFunc: func(got string) { + assert.Equal(suite.T(), "accepted", got) + }, }, { - name: "StateRejected", - state: pki.StateRejected, - expected: "rejected", + name: "StateRejected", + state: pki.StateRejected, + validateFunc: func(got string) { + assert.Equal(suite.T(), "rejected", got) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - assert.Equal(suite.T(), tc.expected, string(tc.state)) + tc.validateFunc(string(tc.state)) }) } } -func TestTypesPublicTestSuite(t *testing.T) { +func TestTypesPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(TypesPublicTestSuite)) } diff --git a/internal/agent/preflight_public_test.go b/internal/agent/preflight_public_test.go index a9e140b07..e7f725771 100644 --- a/internal/agent/preflight_public_test.go +++ b/internal/agent/preflight_public_test.go @@ -43,7 +43,9 @@ type PreflightPublicTestSuite struct { tmpDir string } -func TestPreflightPublicTestSuite(t *testing.T) { +func TestPreflightPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PreflightPublicTestSuite)) } diff --git a/internal/agent/processor_certificate_public_test.go b/internal/agent/processor_certificate_public_test.go index 7c67f72aa..73750ab84 100644 --- a/internal/agent/processor_certificate_public_test.go +++ b/internal/agent/processor_certificate_public_test.go @@ -51,12 +51,12 @@ func (s *ProcessorCertificatePublicTestSuite) TearDownTest() { func (s *ProcessorCertificatePublicTestSuite) TestProcessCertificateOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() certificate.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() certificate.Provider + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "nil provider returns error", @@ -83,7 +83,7 @@ func (s *ProcessorCertificatePublicTestSuite) TestProcessCertificateOperation() m.EXPECT().List(gomock.Any()).Return([]certificate.Entry{}, nil) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var entries []certificate.Entry err := json.Unmarshal(result, &entries) s.NoError(err) @@ -123,9 +123,7 @@ func (s *ProcessorCertificatePublicTestSuite) TestProcessCertificateOperation() } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } @@ -133,12 +131,12 @@ func (s *ProcessorCertificatePublicTestSuite) TestProcessCertificateOperation() func (s *ProcessorCertificatePublicTestSuite) TestProcessCertificateCAOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() certificate.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() certificate.Provider + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "invalid CA operation missing sub-operation", @@ -172,7 +170,7 @@ func (s *ProcessorCertificatePublicTestSuite) TestProcessCertificateCAOperation( }, nil) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var entries []certificate.Entry err := json.Unmarshal(result, &entries) s.NoError(err) @@ -218,7 +216,7 @@ func (s *ProcessorCertificatePublicTestSuite) TestProcessCertificateCAOperation( ) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r certificate.CreateResult err := json.Unmarshal(result, &r) s.NoError(err) @@ -279,7 +277,7 @@ func (s *ProcessorCertificatePublicTestSuite) TestProcessCertificateCAOperation( ) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r certificate.UpdateResult err := json.Unmarshal(result, &r) s.NoError(err) @@ -333,7 +331,7 @@ func (s *ProcessorCertificatePublicTestSuite) TestProcessCertificateCAOperation( }, nil) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r certificate.DeleteResult err := json.Unmarshal(result, &r) s.NoError(err) @@ -399,14 +397,14 @@ func (s *ProcessorCertificatePublicTestSuite) TestProcessCertificateCAOperation( } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } } -func TestProcessorCertificatePublicTestSuite(t *testing.T) { +func TestProcessorCertificatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorCertificatePublicTestSuite)) } diff --git a/internal/agent/processor_command_public_test.go b/internal/agent/processor_command_public_test.go index 7840d331c..c147e114b 100644 --- a/internal/agent/processor_command_public_test.go +++ b/internal/agent/processor_command_public_test.go @@ -51,12 +51,12 @@ func (s *ProcessorCommandPublicTestSuite) TearDownTest() { func (s *ProcessorCommandPublicTestSuite) TestProcessCommandOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func(*commandMocks.MockProvider) - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func(*commandMocks.MockProvider) + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "successful exec operation", @@ -83,7 +83,7 @@ func (s *ProcessorCommandPublicTestSuite) TestProcessCommandOperation() { DurationMs: 12, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r command.Result err := json.Unmarshal(result, &r) s.NoError(err) @@ -115,7 +115,7 @@ func (s *ProcessorCommandPublicTestSuite) TestProcessCommandOperation() { DurationMs: 5, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r command.Result err := json.Unmarshal(result, &r) s.NoError(err) @@ -207,14 +207,14 @@ func (s *ProcessorCommandPublicTestSuite) TestProcessCommandOperation() { } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } } -func TestProcessorCommandPublicTestSuite(t *testing.T) { +func TestProcessorCommandPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorCommandPublicTestSuite)) } diff --git a/internal/agent/processor_docker_public_test.go b/internal/agent/processor_docker_public_test.go index def33f3c7..a6f5c8a74 100644 --- a/internal/agent/processor_docker_public_test.go +++ b/internal/agent/processor_docker_public_test.go @@ -52,12 +52,12 @@ func (s *ProcessorDockerPublicTestSuite) TearDownTest() { func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func(*dockerMocks.MockProvider) - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func(*dockerMocks.MockProvider) + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "nil provider returns error", @@ -96,7 +96,7 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { Changed: true, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r map[string]interface{} err := json.Unmarshal(result, &r) s.NoError(err) @@ -135,7 +135,7 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { Changed: true, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r map[string]interface{} err := json.Unmarshal(result, &r) s.NoError(err) @@ -169,7 +169,7 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { Changed: true, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r map[string]interface{} err := json.Unmarshal(result, &r) s.NoError(err) @@ -234,7 +234,7 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { Changed: true, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r map[string]interface{} err := json.Unmarshal(result, &r) s.NoError(err) @@ -287,7 +287,7 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { Changed: true, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r map[string]interface{} err := json.Unmarshal(result, &r) s.NoError(err) @@ -311,7 +311,7 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { Changed: true, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r map[string]interface{} err := json.Unmarshal(result, &r) s.NoError(err) @@ -364,7 +364,7 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { Changed: true, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r map[string]interface{} err := json.Unmarshal(result, &r) s.NoError(err) @@ -419,7 +419,7 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { {ID: "abc123"}, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r []dockerProv.Container err := json.Unmarshal(result, &r) s.NoError(err) @@ -471,7 +471,7 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { Container: dockerProv.Container{ID: "abc123"}, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r dockerProv.ContainerDetail err := json.Unmarshal(result, &r) s.NoError(err) @@ -526,7 +526,7 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { Changed: true, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r map[string]interface{} err := json.Unmarshal(result, &r) s.NoError(err) @@ -580,7 +580,7 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { Changed: true, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r map[string]interface{} err := json.Unmarshal(result, &r) s.NoError(err) @@ -633,7 +633,7 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { Changed: true, }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r map[string]interface{} err := json.Unmarshal(result, &r) s.NoError(err) @@ -691,14 +691,14 @@ func (s *ProcessorDockerPublicTestSuite) TestProcessDockerOperation() { } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } } -func TestProcessorDockerPublicTestSuite(t *testing.T) { +func TestProcessorDockerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorDockerPublicTestSuite)) } diff --git a/internal/agent/processor_file_public_test.go b/internal/agent/processor_file_public_test.go index 2e88f2d86..28a156480 100644 --- a/internal/agent/processor_file_public_test.go +++ b/internal/agent/processor_file_public_test.go @@ -51,12 +51,12 @@ func (s *ProcessorFilePublicTestSuite) TearDownTest() { func (s *ProcessorFilePublicTestSuite) TestProcessFileOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func(*fileMocks.MockProvider) - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func(*fileMocks.MockProvider) + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "successful deploy operation", @@ -82,7 +82,7 @@ func (s *ProcessorFilePublicTestSuite) TestProcessFileOperation() { Path: "/etc/app/app.conf", }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r fileProv.DeployResult err := json.Unmarshal(result, &r) s.NoError(err) @@ -110,7 +110,7 @@ func (s *ProcessorFilePublicTestSuite) TestProcessFileOperation() { SHA256: "abc123def456", }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r fileProv.StatusResult err := json.Unmarshal(result, &r) s.NoError(err) @@ -207,7 +207,7 @@ func (s *ProcessorFilePublicTestSuite) TestProcessFileOperation() { Path: "/etc/cron.d/backup", }, nil) }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r fileProv.UndeployResult err := json.Unmarshal(result, &r) s.NoError(err) @@ -260,9 +260,7 @@ func (s *ProcessorFilePublicTestSuite) TestProcessFileOperation() { } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } @@ -270,32 +268,34 @@ func (s *ProcessorFilePublicTestSuite) TestProcessFileOperation() { func (s *ProcessorFilePublicTestSuite) TestProcessFileOperationNilProvider() { tests := []struct { - name string - errorMsg string + name string + validateFunc func(json.RawMessage, error) }{ { - name: "returns error when file provider is nil", - errorMsg: "file provider not configured", + name: "returns error when file provider is nil", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "file provider not configured") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := agent.NewFileProcessor(nil, slog.Default()) - result, err := processor(job.Request{ + tt.validateFunc(processor(job.Request{ Type: job.TypeModify, Category: "file", Operation: "deploy.execute", Data: json.RawMessage(`{}`), - }) - - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) + })) }) } } -func TestProcessorFilePublicTestSuite(t *testing.T) { +func TestProcessorFilePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorFilePublicTestSuite)) } diff --git a/internal/agent/processor_interface_public_test.go b/internal/agent/processor_interface_public_test.go index f7f9181e0..6cd528f70 100644 --- a/internal/agent/processor_interface_public_test.go +++ b/internal/agent/processor_interface_public_test.go @@ -51,11 +51,10 @@ func (s *ProcessorInterfacePublicTestSuite) TearDownTest() { func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() iface.Provider - expectError bool - errorMsg string + name string + jobRequest job.Request + setupMock func() iface.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -65,9 +64,12 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceOperation() { Operation: "interface.list", Data: json.RawMessage(`{}`), }, - setupMock: nil, - expectError: true, - errorMsg: "interface provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "interface provider not available") + s.Nil(result) + }, }, { name: "invalid interface operation missing sub-operation", @@ -80,8 +82,11 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceOperation() { setupMock: func() iface.Provider { return netifMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid interface operation: interface", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid interface operation: interface") + s.Nil(result) + }, }, { name: "unsupported interface sub-operation", @@ -94,8 +99,11 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceOperation() { setupMock: func() iface.Provider { return netifMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported interface operation: interface.unknown", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported interface operation: interface.unknown") + s.Nil(result) + }, }, } @@ -112,28 +120,19 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceOperation() { nil, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceList() { tests := []struct { - name string - jobRequest job.Request - setupMock func() iface.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() iface.Provider + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "successful interface list", @@ -151,7 +150,7 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceList() { }, nil) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var entries []iface.InterfaceEntry err := json.Unmarshal(result, &entries) s.NoError(err) @@ -194,9 +193,7 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceList() { } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } @@ -204,12 +201,12 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceList() { func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceGet() { tests := []struct { - name string - jobRequest job.Request - setupMock func() iface.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() iface.Provider + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "successful interface get", @@ -226,7 +223,7 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceGet() { }, nil) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var entry iface.InterfaceEntry err := json.Unmarshal(result, &entry) s.NoError(err) @@ -282,9 +279,7 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceGet() { } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } @@ -292,12 +287,12 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceGet() { func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceCreate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() iface.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() iface.Provider + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "successful interface create", @@ -318,7 +313,7 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceCreate() { }, nil) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r iface.InterfaceResult err := json.Unmarshal(result, &r) s.NoError(err) @@ -377,9 +372,7 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceCreate() { } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } @@ -387,12 +380,12 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceCreate() { func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceUpdate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() iface.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() iface.Provider + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "successful interface update", @@ -413,7 +406,7 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceUpdate() { }, nil) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r iface.InterfaceResult err := json.Unmarshal(result, &r) s.NoError(err) @@ -472,9 +465,7 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceUpdate() { } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } @@ -482,12 +473,12 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceUpdate() { func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceDelete() { tests := []struct { - name string - jobRequest job.Request - setupMock func() iface.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() iface.Provider + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "successful interface delete", @@ -505,7 +496,7 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceDelete() { }, nil) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var r iface.InterfaceResult err := json.Unmarshal(result, &r) s.NoError(err) @@ -562,14 +553,14 @@ func (s *ProcessorInterfacePublicTestSuite) TestProcessInterfaceDelete() { } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } } -func TestProcessorInterfacePublicTestSuite(t *testing.T) { +func TestProcessorInterfacePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorInterfacePublicTestSuite)) } diff --git a/internal/agent/processor_log_public_test.go b/internal/agent/processor_log_public_test.go index 08f18bd49..04c01092d 100644 --- a/internal/agent/processor_log_public_test.go +++ b/internal/agent/processor_log_public_test.go @@ -68,12 +68,12 @@ func (s *ProcessorLogPublicTestSuite) newProcessor( func (s *ProcessorLogPublicTestSuite) TestProcessLogOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() log.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() log.Provider + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "nil provider returns error", @@ -131,9 +131,7 @@ func (s *ProcessorLogPublicTestSuite) TestProcessLogOperation() { } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } @@ -141,12 +139,12 @@ func (s *ProcessorLogPublicTestSuite) TestProcessLogOperation() { func (s *ProcessorLogPublicTestSuite) TestProcessLogQuery() { tests := []struct { - name string - jobRequest job.Request - setupMock func() log.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() log.Provider + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "query with default opts (empty data)", @@ -168,7 +166,7 @@ func (s *ProcessorLogPublicTestSuite) TestProcessLogQuery() { }, nil) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var entries []log.Entry err := json.Unmarshal(result, &entries) s.NoError(err) @@ -199,7 +197,7 @@ func (s *ProcessorLogPublicTestSuite) TestProcessLogQuery() { }, nil) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var entries []log.Entry err := json.Unmarshal(result, &entries) s.NoError(err) @@ -253,9 +251,7 @@ func (s *ProcessorLogPublicTestSuite) TestProcessLogQuery() { } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } @@ -263,12 +259,12 @@ func (s *ProcessorLogPublicTestSuite) TestProcessLogQuery() { func (s *ProcessorLogPublicTestSuite) TestProcessLogQueryUnit() { tests := []struct { - name string - jobRequest job.Request - setupMock func() log.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() log.Provider + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "queryUnit with unit name", @@ -292,7 +288,7 @@ func (s *ProcessorLogPublicTestSuite) TestProcessLogQueryUnit() { }, nil) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var entries []log.Entry err := json.Unmarshal(result, &entries) s.NoError(err) @@ -347,9 +343,7 @@ func (s *ProcessorLogPublicTestSuite) TestProcessLogQueryUnit() { } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } @@ -357,12 +351,12 @@ func (s *ProcessorLogPublicTestSuite) TestProcessLogQueryUnit() { func (s *ProcessorLogPublicTestSuite) TestProcessLogSources() { tests := []struct { - name string - jobRequest job.Request - setupMock func() log.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() log.Provider + expectError bool + errorMsg string + validateFunc func(json.RawMessage) }{ { name: "sources success", @@ -378,7 +372,7 @@ func (s *ProcessorLogPublicTestSuite) TestProcessLogSources() { Return([]string{"nginx", "sshd", "systemd"}, nil) return m }, - validate: func(result json.RawMessage) { + validateFunc: func(result json.RawMessage) { var sources []string err := json.Unmarshal(result, &sources) s.NoError(err) @@ -416,14 +410,14 @@ func (s *ProcessorLogPublicTestSuite) TestProcessLogSources() { } else { s.NoError(err) s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } + tt.validateFunc(result) } }) } } -func TestProcessorLogPublicTestSuite(t *testing.T) { +func TestProcessorLogPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorLogPublicTestSuite)) } diff --git a/internal/agent/processor_network_public_test.go b/internal/agent/processor_network_public_test.go index c30bc111f..c47c0f282 100644 --- a/internal/agent/processor_network_public_test.go +++ b/internal/agent/processor_network_public_test.go @@ -54,12 +54,10 @@ func (s *ProcessorNetworkPublicTestSuite) TearDownTest() { func (s *ProcessorNetworkPublicTestSuite) TestProcessDNSDelete() { tests := []struct { - name string - jobRequest job.Request - setupMock func() *dnsMocks.MockProvider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() *dnsMocks.MockProvider + validateFunc func(json.RawMessage, error) }{ { name: "successful DNS delete", @@ -76,10 +74,12 @@ func (s *ProcessorNetworkPublicTestSuite) TestProcessDNSDelete() { Return(true, nil) return m }, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal(true, response["success"]) s.Equal(true, response["changed"]) s.Equal("DNS configuration deleted", response["message"]) @@ -100,10 +100,12 @@ func (s *ProcessorNetworkPublicTestSuite) TestProcessDNSDelete() { Return(false, nil) return m }, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal(true, response["success"]) s.Equal(false, response["changed"]) }, @@ -123,8 +125,11 @@ func (s *ProcessorNetworkPublicTestSuite) TestProcessDNSDelete() { Return(false, errors.New("netplan remove failed")) return m }, - expectError: true, - errorMsg: "netplan remove failed", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "netplan remove failed") + s.Nil(result) + }, }, } @@ -138,23 +143,13 @@ func (s *ProcessorNetworkPublicTestSuite) TestProcessDNSDelete() { nil, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } -func TestProcessorNetworkPublicTestSuite(t *testing.T) { +func TestProcessorNetworkPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorNetworkPublicTestSuite)) } diff --git a/internal/agent/processor_ntp_public_test.go b/internal/agent/processor_ntp_public_test.go index aa6984218..5c951a34c 100644 --- a/internal/agent/processor_ntp_public_test.go +++ b/internal/agent/processor_ntp_public_test.go @@ -52,12 +52,10 @@ func (s *ProcessorNtpPublicTestSuite) TearDownTest() { func (s *ProcessorNtpPublicTestSuite) TestProcessNtpOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() ntp.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() ntp.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -67,9 +65,12 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpOperation() { Operation: "ntp.get", Data: json.RawMessage(`{}`), }, - setupMock: nil, - expectError: true, - errorMsg: "ntp provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "ntp provider not available") + s.Nil(result) + }, }, { name: "invalid ntp operation missing sub-operation", @@ -82,8 +83,11 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpOperation() { setupMock: func() ntp.Provider { return ntpMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid ntp operation: ntp", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid ntp operation: ntp") + s.Nil(result) + }, }, { name: "unsupported ntp sub-operation", @@ -96,8 +100,11 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpOperation() { setupMock: func() ntp.Provider { return ntpMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported ntp operation: ntp.unknown", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported ntp operation: ntp.unknown") + s.Nil(result) + }, }, } @@ -119,31 +126,17 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpOperation() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorNtpPublicTestSuite) TestProcessNtpGet() { tests := []struct { - name string - jobRequest job.Request - setupMock func() ntp.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() ntp.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful ntp get", @@ -163,10 +156,12 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpGet() { }, nil) return m }, - validate: func(result json.RawMessage) { - var status ntp.Status - err := json.Unmarshal(result, &status) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var status ntp.Status + decodeErr := json.Unmarshal(result, &status) + s.NoError(decodeErr) s.True(status.Synchronized) s.Equal(2, status.Stratum) s.Equal("time.cloudflare.com", status.CurrentSource) @@ -186,8 +181,11 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpGet() { m.EXPECT().Get(gomock.Any()).Return(nil, errors.New("chronyc not found")) return m }, - expectError: true, - errorMsg: "chronyc not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "chronyc not found") + s.Nil(result) + }, }, } @@ -204,31 +202,17 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpGet() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorNtpPublicTestSuite) TestProcessNtpCreate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() ntp.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() ntp.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful ntp create", @@ -247,10 +231,12 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpCreate() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r ntp.CreateResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r ntp.CreateResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.True(r.Changed) }, }, @@ -265,8 +251,11 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpCreate() { setupMock: func() ntp.Provider { return ntpMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal ntp create data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal ntp create data") + s.Nil(result) + }, }, { name: "ntp create provider error", @@ -283,8 +272,11 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpCreate() { Return(nil, errors.New("deploy failed")) return m }, - expectError: true, - errorMsg: "deploy failed", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "deploy failed") + s.Nil(result) + }, }, } @@ -301,31 +293,17 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpCreate() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorNtpPublicTestSuite) TestProcessNtpUpdate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() ntp.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() ntp.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful ntp update", @@ -344,10 +322,12 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpUpdate() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r ntp.UpdateResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r ntp.UpdateResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.True(r.Changed) }, }, @@ -362,8 +342,11 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpUpdate() { setupMock: func() ntp.Provider { return ntpMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal ntp update data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal ntp update data") + s.Nil(result) + }, }, { name: "ntp update provider error", @@ -380,8 +363,11 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpUpdate() { Return(nil, errors.New("config not managed")) return m }, - expectError: true, - errorMsg: "config not managed", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "config not managed") + s.Nil(result) + }, }, } @@ -398,31 +384,17 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpUpdate() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorNtpPublicTestSuite) TestProcessNtpDelete() { tests := []struct { - name string - jobRequest job.Request - setupMock func() ntp.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() ntp.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful ntp delete", @@ -439,10 +411,12 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpDelete() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r ntp.DeleteResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r ntp.DeleteResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.True(r.Changed) }, }, @@ -459,8 +433,11 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpDelete() { m.EXPECT().Delete(gomock.Any()).Return(nil, errors.New("config not managed")) return m }, - expectError: true, - errorMsg: "config not managed", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "config not managed") + s.Nil(result) + }, }, } @@ -477,23 +454,13 @@ func (s *ProcessorNtpPublicTestSuite) TestProcessNtpDelete() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } -func TestProcessorNtpPublicTestSuite(t *testing.T) { +func TestProcessorNtpPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorNtpPublicTestSuite)) } diff --git a/internal/agent/processor_package_public_test.go b/internal/agent/processor_package_public_test.go index b0c6c0e2f..bebf9a3ce 100644 --- a/internal/agent/processor_package_public_test.go +++ b/internal/agent/processor_package_public_test.go @@ -68,12 +68,10 @@ func (s *ProcessorPackagePublicTestSuite) newProcessor( func (s *ProcessorPackagePublicTestSuite) TestProcessPackageOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() apt.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() apt.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -82,9 +80,12 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageOperation() { Category: "node", Operation: "package.list", }, - setupMock: nil, - expectError: true, - errorMsg: "package provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "package provider not available") + s.Nil(result) + }, }, { name: "invalid operation format (no sub-operation)", @@ -96,8 +97,11 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageOperation() { setupMock: func() apt.Provider { return aptMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid package operation: package", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid package operation: package") + s.Nil(result) + }, }, { name: "unsupported package sub-operation", @@ -109,8 +113,11 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageOperation() { setupMock: func() apt.Provider { return aptMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported package operation: package.unknown", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported package operation: package.unknown") + s.Nil(result) + }, }, } @@ -122,31 +129,17 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageOperation() { } processor := s.newProcessor(packageProvider) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorPackagePublicTestSuite) TestProcessPackageList() { tests := []struct { - name string - jobRequest job.Request - setupMock func() apt.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() apt.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful list", @@ -171,10 +164,12 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageList() { }, nil) return m }, - validate: func(result json.RawMessage) { - var pkgs []apt.Package - err := json.Unmarshal(result, &pkgs) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var pkgs []apt.Package + decodeErr := json.Unmarshal(result, &pkgs) + s.NoError(decodeErr) s.Len(pkgs, 2) s.Equal("curl", pkgs[0].Name) s.Equal("vim", pkgs[1].Name) @@ -192,39 +187,28 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageList() { m.EXPECT().List(gomock.Any()).Return(nil, errors.New("permission denied")) return m }, - expectError: true, - errorMsg: "permission denied", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "permission denied") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorPackagePublicTestSuite) TestProcessPackageGet() { tests := []struct { - name string - jobRequest job.Request - setupMock func() apt.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() apt.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful get", @@ -243,10 +227,12 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageGet() { }, nil) return m }, - validate: func(result json.RawMessage) { - var pkg apt.Package - err := json.Unmarshal(result, &pkg) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var pkg apt.Package + decodeErr := json.Unmarshal(result, &pkg) + s.NoError(decodeErr) s.Equal("curl", pkg.Name) s.Equal("installed", pkg.Status) }, @@ -262,8 +248,11 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageGet() { setupMock: func() apt.Provider { return aptMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal package get data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal package get data") + s.Nil(result) + }, }, { name: "get provider error", @@ -280,39 +269,28 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageGet() { Return(nil, errors.New("package not found")) return m }, - expectError: true, - errorMsg: "package not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "package not found") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorPackagePublicTestSuite) TestProcessPackageInstall() { tests := []struct { - name string - jobRequest job.Request - setupMock func() apt.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() apt.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful install", @@ -330,10 +308,12 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageInstall() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r apt.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r apt.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("nginx", r.Name) s.True(r.Changed) }, @@ -349,8 +329,11 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageInstall() { setupMock: func() apt.Provider { return aptMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal package install data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal package install data") + s.Nil(result) + }, }, { name: "install provider error", @@ -367,39 +350,28 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageInstall() { Return(nil, errors.New("package not found in repository")) return m }, - expectError: true, - errorMsg: "package not found in repository", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "package not found in repository") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorPackagePublicTestSuite) TestProcessPackageRemove() { tests := []struct { - name string - jobRequest job.Request - setupMock func() apt.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() apt.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful remove", @@ -417,10 +389,12 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageRemove() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r apt.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r apt.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("nginx", r.Name) s.True(r.Changed) }, @@ -436,8 +410,11 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageRemove() { setupMock: func() apt.Provider { return aptMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal package remove data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal package remove data") + s.Nil(result) + }, }, { name: "remove provider error", @@ -454,39 +431,28 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageRemove() { Return(nil, errors.New("cannot remove essential package")) return m }, - expectError: true, - errorMsg: "cannot remove essential package", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "cannot remove essential package") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorPackagePublicTestSuite) TestProcessPackageUpdate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() apt.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() apt.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful update", @@ -502,10 +468,12 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageUpdate() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r apt.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r apt.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.True(r.Changed) }, }, @@ -521,39 +489,28 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageUpdate() { m.EXPECT().Update(gomock.Any()).Return(nil, errors.New("network unreachable")) return m }, - expectError: true, - errorMsg: "network unreachable", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "network unreachable") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorPackagePublicTestSuite) TestProcessPackageListUpdates() { tests := []struct { - name string - jobRequest job.Request - setupMock func() apt.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() apt.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful list updates", @@ -573,10 +530,12 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageListUpdates() { }, nil) return m }, - validate: func(result json.RawMessage) { - var updates []apt.Update - err := json.Unmarshal(result, &updates) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var updates []apt.Update + decodeErr := json.Unmarshal(result, &updates) + s.NoError(decodeErr) s.Len(updates, 1) s.Equal("curl", updates[0].Name) s.Equal("7.88.1-10+deb12u5", updates[0].NewVersion) @@ -594,31 +553,24 @@ func (s *ProcessorPackagePublicTestSuite) TestProcessPackageListUpdates() { m.EXPECT().ListUpdates(gomock.Any()).Return(nil, errors.New("apt cache stale")) return m }, - expectError: true, - errorMsg: "apt cache stale", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "apt cache stale") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } -func TestProcessorPackagePublicTestSuite(t *testing.T) { +func TestProcessorPackagePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorPackagePublicTestSuite)) } diff --git a/internal/agent/processor_power_public_test.go b/internal/agent/processor_power_public_test.go index 8e61ec5d4..9d03ae226 100644 --- a/internal/agent/processor_power_public_test.go +++ b/internal/agent/processor_power_public_test.go @@ -52,12 +52,10 @@ func (s *ProcessorPowerPublicTestSuite) TearDownTest() { func (s *ProcessorPowerPublicTestSuite) TestProcessPowerOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() power.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() power.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -67,9 +65,12 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerOperation() { Operation: "power.reboot", Data: json.RawMessage(`{}`), }, - setupMock: nil, - expectError: true, - errorMsg: "power provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "power provider not available") + s.Nil(result) + }, }, { name: "invalid operation format (no sub-operation)", @@ -82,8 +83,11 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerOperation() { setupMock: func() power.Provider { return powerMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid power operation: power", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid power operation: power") + s.Nil(result) + }, }, { name: "unsupported power sub-operation", @@ -96,8 +100,11 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerOperation() { setupMock: func() power.Provider { return powerMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported power operation: power.unknown", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported power operation: power.unknown") + s.Nil(result) + }, }, } @@ -120,31 +127,17 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerOperation() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorPowerPublicTestSuite) TestProcessPowerReboot() { tests := []struct { - name string - jobRequest job.Request - setupMock func() power.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() power.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful reboot with opts", @@ -166,10 +159,12 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerReboot() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r power.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r power.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("reboot", r.Action) s.Equal(30, r.Delay) s.True(r.Changed) @@ -192,10 +187,12 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerReboot() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r power.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r power.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("reboot", r.Action) s.True(r.Changed) }, @@ -211,8 +208,11 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerReboot() { setupMock: func() power.Provider { return powerMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal power opts", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal power opts") + s.Nil(result) + }, }, { name: "reboot provider error", @@ -229,8 +229,11 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerReboot() { Return(nil, errors.New("permission denied")) return m }, - expectError: true, - errorMsg: "permission denied", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "permission denied") + s.Nil(result) + }, }, } @@ -248,31 +251,17 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerReboot() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorPowerPublicTestSuite) TestProcessPowerShutdown() { tests := []struct { - name string - jobRequest job.Request - setupMock func() power.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() power.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful shutdown with opts", @@ -294,10 +283,12 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerShutdown() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r power.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r power.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("shutdown", r.Action) s.Equal(60, r.Delay) s.True(r.Changed) @@ -320,10 +311,12 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerShutdown() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r power.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r power.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("shutdown", r.Action) s.True(r.Changed) }, @@ -339,8 +332,11 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerShutdown() { setupMock: func() power.Provider { return powerMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal power opts", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal power opts") + s.Nil(result) + }, }, { name: "shutdown provider error", @@ -357,8 +353,11 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerShutdown() { Return(nil, errors.New("operation not permitted")) return m }, - expectError: true, - errorMsg: "operation not permitted", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "operation not permitted") + s.Nil(result) + }, }, } @@ -376,23 +375,13 @@ func (s *ProcessorPowerPublicTestSuite) TestProcessPowerShutdown() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } -func TestProcessorPowerPublicTestSuite(t *testing.T) { +func TestProcessorPowerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorPowerPublicTestSuite)) } diff --git a/internal/agent/processor_process_public_test.go b/internal/agent/processor_process_public_test.go index 76551ddf8..a324106af 100644 --- a/internal/agent/processor_process_public_test.go +++ b/internal/agent/processor_process_public_test.go @@ -52,12 +52,10 @@ func (s *ProcessorProcessPublicTestSuite) TearDownTest() { func (s *ProcessorProcessPublicTestSuite) TestProcessProcessOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() process.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() process.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -66,9 +64,12 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessOperation() { Category: "node", Operation: "process.list", }, - setupMock: nil, - expectError: true, - errorMsg: "process provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "process provider not available") + s.Nil(result) + }, }, { name: "invalid operation format (no sub-operation)", @@ -80,8 +81,11 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessOperation() { setupMock: func() process.Provider { return processMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid process operation: process", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid process operation: process") + s.Nil(result) + }, }, { name: "unsupported process sub-operation", @@ -93,8 +97,11 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessOperation() { setupMock: func() process.Provider { return processMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported process operation: process.unknown", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported process operation: process.unknown") + s.Nil(result) + }, }, } @@ -116,31 +123,17 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessOperation() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorProcessPublicTestSuite) TestProcessProcessList() { tests := []struct { - name string - jobRequest job.Request - setupMock func() process.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() process.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful list", @@ -169,10 +162,12 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessList() { }, nil) return m }, - validate: func(result json.RawMessage) { - var infos []process.Info - err := json.Unmarshal(result, &infos) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var infos []process.Info + decodeErr := json.Unmarshal(result, &infos) + s.NoError(decodeErr) s.Len(infos, 2) s.Equal(1, infos[0].PID) s.Equal("systemd", infos[0].Name) @@ -191,8 +186,11 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessList() { m.EXPECT().List(gomock.Any()).Return(nil, errors.New("permission denied")) return m }, - expectError: true, - errorMsg: "permission denied", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "permission denied") + s.Nil(result) + }, }, } @@ -209,31 +207,17 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessList() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorProcessPublicTestSuite) TestProcessProcessGet() { tests := []struct { - name string - jobRequest job.Request - setupMock func() process.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() process.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful get", @@ -254,10 +238,12 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessGet() { }, nil) return m }, - validate: func(result json.RawMessage) { - var info process.Info - err := json.Unmarshal(result, &info) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var info process.Info + decodeErr := json.Unmarshal(result, &info) + s.NoError(decodeErr) s.Equal(1234, info.PID) s.Equal("nginx", info.Name) s.Equal("www-data", info.User) @@ -274,8 +260,11 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessGet() { setupMock: func() process.Provider { return processMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal process get data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal process get data") + s.Nil(result) + }, }, { name: "get provider error", @@ -290,8 +279,11 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessGet() { m.EXPECT().Get(gomock.Any(), 9999).Return(nil, errors.New("process not found")) return m }, - expectError: true, - errorMsg: "process not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "process not found") + s.Nil(result) + }, }, } @@ -308,31 +300,17 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessGet() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorProcessPublicTestSuite) TestProcessProcessSignal() { tests := []struct { - name string - jobRequest job.Request - setupMock func() process.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() process.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful signal", @@ -351,10 +329,12 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessSignal() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r process.SignalResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r process.SignalResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal(1234, r.PID) s.Equal("TERM", r.Signal) s.True(r.Changed) @@ -371,8 +351,11 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessSignal() { setupMock: func() process.Provider { return processMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal process signal data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal process signal data") + s.Nil(result) + }, }, { name: "signal provider error", @@ -389,8 +372,11 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessSignal() { Return(nil, errors.New("permission denied")) return m }, - expectError: true, - errorMsg: "permission denied", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "permission denied") + s.Nil(result) + }, }, } @@ -407,23 +393,13 @@ func (s *ProcessorProcessPublicTestSuite) TestProcessProcessSignal() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } -func TestProcessorProcessPublicTestSuite(t *testing.T) { +func TestProcessorProcessPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorProcessPublicTestSuite)) } diff --git a/internal/agent/processor_public_test.go b/internal/agent/processor_public_test.go index e458d1426..969032cda 100644 --- a/internal/agent/processor_public_test.go +++ b/internal/agent/processor_public_test.go @@ -145,11 +145,9 @@ func (s *ProcessorPublicTestSuite) TearDownTest() { func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { tests := []struct { - name string - jobRequest job.Request - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + validateFunc func(json.RawMessage, error) }{ { name: "successful node hostname operation", @@ -159,11 +157,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "hostname.get", Data: json.RawMessage(`{}`), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Contains(response, "hostname") s.IsType("", response["hostname"]) s.Equal(false, response["changed"]) @@ -177,11 +177,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "status.get", Data: json.RawMessage(`{}`), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Contains(response, "hostname") s.Equal(false, response["changed"]) }, @@ -194,11 +196,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "uptime.get", Data: json.RawMessage(`{}`), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Contains(response, "uptime_seconds") s.Contains(response, "uptime") s.Equal(false, response["changed"]) @@ -212,11 +216,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "osinfo.get", Data: json.RawMessage(`{}`), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal(false, response["changed"]) }, }, @@ -228,11 +234,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "disk.get", Data: json.RawMessage(`{}`), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Contains(response, "disks") s.Equal(false, response["changed"]) }, @@ -245,11 +253,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "memory.get", Data: json.RawMessage(`{}`), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal(false, response["changed"]) }, }, @@ -261,11 +271,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "load.get", Data: json.RawMessage(`{}`), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal(false, response["changed"]) }, }, @@ -277,11 +289,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "dns.get", Data: json.RawMessage(`{"interface": "eth0"}`), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal(false, response["changed"]) }, }, @@ -295,11 +309,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { `{"servers": ["8.8.8.8"], "search_domains": ["example.com"], "interface": "eth0"}`, ), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Contains(response, "success") s.Contains(response, "message") s.Equal(true, response["changed"]) @@ -313,11 +329,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "ping.do", Data: json.RawMessage(`{"address": "8.8.8.8"}`), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal(false, response["changed"]) }, }, @@ -329,11 +347,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "exec.execute", Data: json.RawMessage(`{"command":"ls","args":["-la"]}`), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Contains(response, "stdout") }, }, @@ -345,11 +365,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "shell.execute", Data: json.RawMessage(`{"command":"echo hello"}`), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Contains(response, "stdout") }, }, @@ -363,11 +385,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { `{"object_name":"app.conf","path":"/etc/mock/file.conf","content_type":"raw"}`, ), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal(true, response["changed"]) }, }, @@ -379,11 +403,13 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "status.get", Data: json.RawMessage(`{"path":"/etc/mock/file.conf"}`), }, - expectError: false, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal("in-sync", response["status"]) }, }, @@ -395,8 +421,11 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "create.execute", Data: json.RawMessage(`{"image":"nginx:latest"}`), }, - expectError: true, - errorMsg: "docker runtime not available", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "docker runtime not available") + s.Nil(result) + }, }, { name: "unsupported job category", @@ -406,8 +435,11 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "test.get", Data: json.RawMessage(`{}`), }, - expectError: true, - errorMsg: "unsupported job category: unsupported", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported job category: unsupported") + s.Nil(result) + }, }, { name: "unsupported node operation", @@ -417,8 +449,11 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "unsupported.get", Data: json.RawMessage(`{}`), }, - expectError: true, - errorMsg: "unsupported node operation: unsupported.get", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported node operation: unsupported.get") + s.Nil(result) + }, }, { name: "unsupported network operation", @@ -428,8 +463,11 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "unsupported.get", Data: json.RawMessage(`{}`), }, - expectError: true, - errorMsg: "unsupported network operation: unsupported.get", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported network operation: unsupported.get") + s.Nil(result) + }, }, { name: "network ping missing address", @@ -439,8 +477,11 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "ping.do", Data: json.RawMessage(`{}`), }, - expectError: true, - errorMsg: "missing ping address", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "missing ping address") + s.Nil(result) + }, }, { name: "network ping invalid data format", @@ -450,8 +491,11 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "ping.do", Data: json.RawMessage(`invalid json`), }, - expectError: true, - errorMsg: "failed to parse ping data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to parse ping data") + s.Nil(result) + }, }, { name: "network DNS invalid data format", @@ -461,45 +505,38 @@ func (s *ProcessorPublicTestSuite) TestProcessJobOperation() { Operation: "dns.get", Data: json.RawMessage(`invalid json`), }, - expectError: true, - errorMsg: "failed to parse DNS data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to parse DNS data") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - result, err := agent.ExportProcessJobOperation(s.testAgent, tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(agent.ExportProcessJobOperation(s.testAgent, tt.jobRequest)) }) } } func (s *ProcessorPublicTestSuite) TestSystemOperations() { tests := []struct { - name string - operation string - labels map[string]string - expectError bool - validate func(json.RawMessage) + name string + operation string + labels map[string]string + validateFunc func(json.RawMessage, error) }{ { name: "get hostname", operation: "hostname.get", - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Contains(response, "hostname") s.Equal(false, response["changed"]) }, @@ -508,10 +545,13 @@ func (s *ProcessorPublicTestSuite) TestSystemOperations() { name: "get hostname with labels", operation: "hostname.get", labels: map[string]string{"group": "web.dev.us-east"}, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Contains(response, "hostname") s.Contains(response, "labels") labels, ok := response["labels"].(map[string]interface{}) @@ -523,10 +563,13 @@ func (s *ProcessorPublicTestSuite) TestSystemOperations() { { name: "get node status", operation: "status.get", - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Contains(response, "hostname") s.Equal(false, response["changed"]) }, @@ -534,10 +577,13 @@ func (s *ProcessorPublicTestSuite) TestSystemOperations() { { name: "get uptime", operation: "uptime.get", - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Contains(response, "uptime_seconds") s.Equal(false, response["changed"]) }, @@ -546,38 +592,43 @@ func (s *ProcessorPublicTestSuite) TestSystemOperations() { // Hostname update tests (TypeModify). modifyTests := []struct { - name string - operation string - data string - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + operation string + data string + validateFunc func(json.RawMessage, error) }{ { - name: "update hostname returns unsupported", - operation: "hostname.update", - data: `{"hostname": "new-host"}`, - expectError: true, - errorMsg: "operation not supported", + name: "update hostname returns unsupported", + operation: "hostname.update", + data: `{"hostname": "new-host"}`, + validateFunc: func(_ json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "operation not supported") + }, }, { name: "update hostname succeeds", operation: "hostname.update", data: `{"hostname": "success-host"}`, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal("success-host", response["hostname"]) s.Equal(true, response["changed"]) }, }, { - name: "update hostname with invalid data", - operation: "hostname.update", - data: `invalid json`, - expectError: true, - errorMsg: "invalid hostname update data", + name: "update hostname with invalid data", + operation: "hostname.update", + data: `invalid json`, + validateFunc: func(_ json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid hostname update data") + }, }, } @@ -590,18 +641,7 @@ func (s *ProcessorPublicTestSuite) TestSystemOperations() { Data: json.RawMessage(tt.data), } - result, err := agent.ExportProcessNodeOperation(s.testAgent, request) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(agent.ExportProcessNodeOperation(s.testAgent, request)) }) } @@ -618,38 +658,29 @@ func (s *ProcessorPublicTestSuite) TestSystemOperations() { Data: json.RawMessage(`{}`), } - result, err := agent.ExportProcessNodeOperation(s.testAgent, request) - - if tt.expectError { - s.Error(err) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(agent.ExportProcessNodeOperation(s.testAgent, request)) }) } } func (s *ProcessorPublicTestSuite) TestNetworkOperations() { tests := []struct { - name string - operation string - data string - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + operation string + data string + validateFunc func(json.RawMessage, error) }{ { name: "DNS query with interface", operation: "dns.get", data: `{"interface": "eth0"}`, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal(false, response["changed"]) }, }, @@ -657,10 +688,13 @@ func (s *ProcessorPublicTestSuite) TestNetworkOperations() { name: "DNS query without interface", operation: "dns.get", data: `{}`, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal(false, response["changed"]) }, }, @@ -668,26 +702,33 @@ func (s *ProcessorPublicTestSuite) TestNetworkOperations() { name: "ping with valid address", operation: "ping.do", data: `{"address": "127.0.0.1"}`, - validate: func(result json.RawMessage) { - var response map[string]interface{} - err := json.Unmarshal(result, &response) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + + var response map[string]interface{} + decodeErr := json.Unmarshal(result, &response) + s.NoError(decodeErr) s.Equal(false, response["changed"]) }, }, { - name: "ping without address", - operation: "ping.execute", - data: `{}`, - expectError: true, - errorMsg: "missing ping address", + name: "ping without address", + operation: "ping.execute", + data: `{}`, + validateFunc: func(_ json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "missing ping address") + }, }, { - name: "unsupported network operation", - operation: "unknown.get", - data: `{}`, - expectError: true, - errorMsg: "unsupported network operation", + name: "unsupported network operation", + operation: "unknown.get", + data: `{}`, + validateFunc: func(_ json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported network operation") + }, }, } @@ -700,80 +741,92 @@ func (s *ProcessorPublicTestSuite) TestNetworkOperations() { Data: json.RawMessage(tt.data), } - result, err := agent.ExportProcessNetworkOperation(s.testAgent, request) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(agent.ExportProcessNetworkOperation(s.testAgent, request)) }) } } func (s *ProcessorPublicTestSuite) TestProviderFactoryMethods() { tests := []struct { - name string - getProvider func() interface{} + name string + getProvider func() interface{} + validateFunc func(interface{}) }{ { name: "getHostProvider", getProvider: func() interface{} { return agent.ExportGetHostProvider(s.testAgent) }, + validateFunc: func(provider interface{}) { + s.NotNil(provider) + }, }, { name: "getDiskProvider", getProvider: func() interface{} { return agent.ExportGetDiskProvider(s.testAgent) }, + validateFunc: func(provider interface{}) { + s.NotNil(provider) + }, }, { name: "getMemProvider", getProvider: func() interface{} { return agent.ExportGetMemProvider(s.testAgent) }, + validateFunc: func(provider interface{}) { + s.NotNil(provider) + }, }, { name: "getLoadProvider", getProvider: func() interface{} { return agent.ExportGetLoadProvider(s.testAgent) }, + validateFunc: func(provider interface{}) { + s.NotNil(provider) + }, }, { name: "getDNSProvider", getProvider: func() interface{} { return agent.ExportGetDNSProvider(s.testAgent) }, + validateFunc: func(provider interface{}) { + s.NotNil(provider) + }, }, { name: "getPingProvider", getProvider: func() interface{} { return agent.ExportGetPingProvider(s.testAgent) }, + validateFunc: func(provider interface{}) { + s.NotNil(provider) + }, }, { name: "getCommandProvider", getProvider: func() interface{} { return agent.ExportGetCommandProvider(s.testAgent) }, + validateFunc: func(provider interface{}) { + s.NotNil(provider) + }, }, { name: "getFileProvider", getProvider: func() interface{} { return agent.ExportGetFileProvider(s.testAgent) }, + validateFunc: func(provider interface{}) { + s.NotNil(provider) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - provider := tt.getProvider() - s.NotNil(provider) + tt.validateFunc(tt.getProvider()) }) } } func (s *ProcessorPublicTestSuite) TestSystemOperationErrors() { tests := []struct { - name string - operation string - errorMsg string - createAgent func() *agent.Agent + name string + operation string + createAgent func() *agent.Agent + validateFunc func(json.RawMessage, error) }{ { name: "hostname provider error", operation: "hostname.get", - errorMsg: "hostname unavailable", createAgent: func() *agent.Agent { hostMock := hostMocks.NewPlainMockProvider(s.mockCtrl) hostMock.EXPECT().GetHostname().Return("", errors.New("hostname unavailable")) @@ -791,11 +844,15 @@ func (s *ProcessorPublicTestSuite) TestSystemOperationErrors() { commandProvider: commandMocks.NewPlainMockProvider(s.mockCtrl), }) }, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "hostname unavailable") + s.Nil(result) + }, }, { name: "uptime provider error", operation: "uptime.get", - errorMsg: "uptime unavailable", createAgent: func() *agent.Agent { hostMock := hostMocks.NewPlainMockProvider(s.mockCtrl) hostMock.EXPECT(). @@ -815,11 +872,15 @@ func (s *ProcessorPublicTestSuite) TestSystemOperationErrors() { commandProvider: commandMocks.NewPlainMockProvider(s.mockCtrl), }) }, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "uptime unavailable") + s.Nil(result) + }, }, { name: "OS info provider error", operation: "os.get", - errorMsg: "os info unavailable", createAgent: func() *agent.Agent { hostMock := hostMocks.NewPlainMockProvider(s.mockCtrl) hostMock.EXPECT().GetOSInfo().Return(nil, errors.New("os info unavailable")) @@ -837,11 +898,15 @@ func (s *ProcessorPublicTestSuite) TestSystemOperationErrors() { commandProvider: commandMocks.NewPlainMockProvider(s.mockCtrl), }) }, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "os info unavailable") + s.Nil(result) + }, }, { name: "disk provider error", operation: "disk.get", - errorMsg: "disk unavailable", createAgent: func() *agent.Agent { diskMock := diskMocks.NewPlainMockProvider(s.mockCtrl) diskMock.EXPECT().GetLocalUsageStats().Return(nil, errors.New("disk unavailable")) @@ -859,11 +924,15 @@ func (s *ProcessorPublicTestSuite) TestSystemOperationErrors() { commandProvider: commandMocks.NewPlainMockProvider(s.mockCtrl), }) }, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "disk unavailable") + s.Nil(result) + }, }, { name: "memory provider error", operation: "memory.get", - errorMsg: "memory unavailable", createAgent: func() *agent.Agent { memMock := memMocks.NewPlainMockProvider(s.mockCtrl) memMock.EXPECT().GetStats().Return(nil, errors.New("memory unavailable")) @@ -881,11 +950,15 @@ func (s *ProcessorPublicTestSuite) TestSystemOperationErrors() { commandProvider: commandMocks.NewPlainMockProvider(s.mockCtrl), }) }, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "memory unavailable") + s.Nil(result) + }, }, { name: "load provider error", operation: "load.get", - errorMsg: "load unavailable", createAgent: func() *agent.Agent { loadMock := loadMocks.NewPlainMockProvider(s.mockCtrl) loadMock.EXPECT().GetAverageStats().Return(nil, errors.New("load unavailable")) @@ -903,6 +976,11 @@ func (s *ProcessorPublicTestSuite) TestSystemOperationErrors() { commandProvider: commandMocks.NewPlainMockProvider(s.mockCtrl), }) }, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "load unavailable") + s.Nil(result) + }, }, } @@ -916,30 +994,25 @@ func (s *ProcessorPublicTestSuite) TestSystemOperationErrors() { Data: json.RawMessage(`{}`), } - result, err := agent.ExportProcessNodeOperation(a, request) - - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) + tt.validateFunc(agent.ExportProcessNodeOperation(a, request)) }) } } func (s *ProcessorPublicTestSuite) TestNetworkOperationErrors() { tests := []struct { - name string - operation string - jobType job.Type - data string - errorMsg string - createAgent func() *agent.Agent + name string + operation string + jobType job.Type + data string + createAgent func() *agent.Agent + validateFunc func(json.RawMessage, error) }{ { name: "DNS get error", operation: "dns.get", jobType: job.TypeQuery, data: `{"interface": "eth0"}`, - errorMsg: "DNS lookup failed", createAgent: func() *agent.Agent { dnsMock := dnsMocks.NewPlainMockProvider(s.mockCtrl) dnsMock.EXPECT(). @@ -959,13 +1032,17 @@ func (s *ProcessorPublicTestSuite) TestNetworkOperationErrors() { commandProvider: commandMocks.NewPlainMockProvider(s.mockCtrl), }) }, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "DNS lookup failed") + s.Nil(result) + }, }, { name: "DNS update error", operation: "dns.update", jobType: job.TypeModify, data: `{"servers": ["8.8.8.8"], "search_domains": ["example.com"], "interface": "eth0"}`, - errorMsg: "DNS update failed", createAgent: func() *agent.Agent { dnsMock := dnsMocks.NewPlainMockProvider(s.mockCtrl) dnsMock.EXPECT(). @@ -985,13 +1062,17 @@ func (s *ProcessorPublicTestSuite) TestNetworkOperationErrors() { commandProvider: commandMocks.NewPlainMockProvider(s.mockCtrl), }) }, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "DNS update failed") + s.Nil(result) + }, }, { name: "ping provider error", operation: "ping.do", jobType: job.TypeQuery, data: `{"address": "8.8.8.8"}`, - errorMsg: "ping failed", createAgent: func() *agent.Agent { pingMock := pingMocks.NewPlainMockProvider(s.mockCtrl) pingMock.EXPECT().Do("8.8.8.8").Return(nil, errors.New("ping timeout")) @@ -1009,6 +1090,11 @@ func (s *ProcessorPublicTestSuite) TestNetworkOperationErrors() { commandProvider: commandMocks.NewPlainMockProvider(s.mockCtrl), }) }, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "ping failed") + s.Nil(result) + }, }, } @@ -1022,15 +1108,13 @@ func (s *ProcessorPublicTestSuite) TestNetworkOperationErrors() { Data: json.RawMessage(tt.data), } - result, err := agent.ExportProcessNetworkOperation(a, request) - - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) + tt.validateFunc(agent.ExportProcessNetworkOperation(a, request)) }) } } -func TestProcessorPublicTestSuite(t *testing.T) { +func TestProcessorPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorPublicTestSuite)) } diff --git a/internal/agent/processor_route_public_test.go b/internal/agent/processor_route_public_test.go index 6a03e4ba7..f1cfd6986 100644 --- a/internal/agent/processor_route_public_test.go +++ b/internal/agent/processor_route_public_test.go @@ -51,11 +51,10 @@ func (s *ProcessorRoutePublicTestSuite) TearDownTest() { func (s *ProcessorRoutePublicTestSuite) TestProcessRouteOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() route.Provider - expectError bool - errorMsg string + name string + jobRequest job.Request + setupMock func() route.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -65,9 +64,12 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteOperation() { Operation: "route.list", Data: json.RawMessage(`{}`), }, - setupMock: nil, - expectError: true, - errorMsg: "route provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "route provider not available") + s.Nil(result) + }, }, { name: "invalid route operation missing sub-operation", @@ -80,8 +82,11 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteOperation() { setupMock: func() route.Provider { return routeMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid route operation: route", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid route operation: route") + s.Nil(result) + }, }, { name: "unsupported route sub-operation", @@ -94,8 +99,11 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteOperation() { setupMock: func() route.Provider { return routeMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported route operation: route.unknown", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported route operation: route.unknown") + s.Nil(result) + }, }, } @@ -112,28 +120,17 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteOperation() { routeProvider, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorRoutePublicTestSuite) TestProcessRouteList() { tests := []struct { - name string - jobRequest job.Request - setupMock func() route.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() route.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful route list", @@ -151,10 +148,12 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteList() { }, nil) return m }, - validate: func(result json.RawMessage) { - var entries []route.ListEntry - err := json.Unmarshal(result, &entries) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var entries []route.ListEntry + decodeErr := json.Unmarshal(result, &entries) + s.NoError(decodeErr) s.Len(entries, 2) s.Equal("10.0.0.0/24", entries[0].Destination) }, @@ -172,8 +171,11 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteList() { m.EXPECT().List(gomock.Any()).Return(nil, errors.New("permission denied")) return m }, - expectError: true, - errorMsg: "permission denied", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "permission denied") + s.Nil(result) + }, }, } @@ -185,31 +187,17 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteList() { tt.setupMock(), slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorRoutePublicTestSuite) TestProcessRouteGet() { tests := []struct { - name string - jobRequest job.Request - setupMock func() route.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() route.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful route get", @@ -229,10 +217,12 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteGet() { }, nil) return m }, - validate: func(result json.RawMessage) { - var entry route.Entry - err := json.Unmarshal(result, &entry) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var entry route.Entry + decodeErr := json.Unmarshal(result, &entry) + s.NoError(decodeErr) s.Equal("eth0", entry.Interface) s.Len(entry.Routes, 1) }, @@ -248,8 +238,11 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteGet() { setupMock: func() route.Provider { return routeMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal route get data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal route get data") + s.Nil(result) + }, }, { name: "route get provider error", @@ -264,8 +257,11 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteGet() { m.EXPECT().Get(gomock.Any(), "missing").Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } @@ -277,31 +273,17 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteGet() { tt.setupMock(), slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorRoutePublicTestSuite) TestProcessRouteCreate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() route.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() route.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful route create", @@ -326,10 +308,12 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteCreate() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r route.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r route.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("eth0", r.Interface) s.True(r.Changed) }, @@ -345,8 +329,11 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteCreate() { setupMock: func() route.Provider { return routeMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal route create data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal route create data") + s.Nil(result) + }, }, { name: "route create provider error", @@ -365,8 +352,11 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteCreate() { Return(nil, errors.New("deploy failed")) return m }, - expectError: true, - errorMsg: "deploy failed", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "deploy failed") + s.Nil(result) + }, }, } @@ -378,31 +368,17 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteCreate() { tt.setupMock(), slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorRoutePublicTestSuite) TestProcessRouteUpdate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() route.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() route.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful route update", @@ -427,10 +403,12 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteUpdate() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r route.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r route.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("eth0", r.Interface) s.True(r.Changed) }, @@ -446,8 +424,11 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteUpdate() { setupMock: func() route.Provider { return routeMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal route update data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal route update data") + s.Nil(result) + }, }, { name: "route update provider error", @@ -466,8 +447,11 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteUpdate() { Return(nil, errors.New("not managed")) return m }, - expectError: true, - errorMsg: "not managed", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not managed") + s.Nil(result) + }, }, } @@ -479,31 +463,17 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteUpdate() { tt.setupMock(), slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorRoutePublicTestSuite) TestProcessRouteDelete() { tests := []struct { - name string - jobRequest job.Request - setupMock func() route.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() route.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful route delete", @@ -521,10 +491,12 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteDelete() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r route.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r route.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("eth0", r.Interface) s.True(r.Changed) }, @@ -540,8 +512,11 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteDelete() { setupMock: func() route.Provider { return routeMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal route delete data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal route delete data") + s.Nil(result) + }, }, { name: "route delete provider error", @@ -556,8 +531,11 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteDelete() { m.EXPECT().Delete(gomock.Any(), "missing").Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } @@ -569,23 +547,13 @@ func (s *ProcessorRoutePublicTestSuite) TestProcessRouteDelete() { tt.setupMock(), slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } -func TestProcessorRoutePublicTestSuite(t *testing.T) { +func TestProcessorRoutePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorRoutePublicTestSuite)) } diff --git a/internal/agent/processor_schedule_public_test.go b/internal/agent/processor_schedule_public_test.go index 6bc1d0511..0263cbcda 100644 --- a/internal/agent/processor_schedule_public_test.go +++ b/internal/agent/processor_schedule_public_test.go @@ -58,12 +58,10 @@ func (s *ProcessorSchedulePublicTestSuite) TearDownTest() { func (s *ProcessorSchedulePublicTestSuite) TestProcessScheduleOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() cron.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() cron.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -73,9 +71,12 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessScheduleOperation() { Operation: "cron.list", Data: json.RawMessage(`{}`), }, - setupMock: nil, - expectError: true, - errorMsg: "cron provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "cron provider not available") + s.Nil(result) + }, }, { name: "dispatches to cron operation", @@ -90,10 +91,12 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessScheduleOperation() { m.EXPECT().List(gomock.Any()).Return([]cron.Entry{}, nil) return m }, - validate: func(result json.RawMessage) { - var entries []cron.Entry - err := json.Unmarshal(result, &entries) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var entries []cron.Entry + decodeErr := json.Unmarshal(result, &entries) + s.NoError(decodeErr) s.Empty(entries) }, }, @@ -108,8 +111,11 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessScheduleOperation() { setupMock: func() cron.Provider { return cronMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported schedule operation: unknown.list", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported schedule operation: unknown.list") + s.Nil(result) + }, }, } @@ -121,31 +127,17 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessScheduleOperation() { } processor := agent.NewScheduleProcessor(cronProvider, slog.Default()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() cron.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() cron.Provider + validateFunc func(json.RawMessage, error) }{ { name: "invalid cron operation missing sub-operation", @@ -158,8 +150,11 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { setupMock: func() cron.Provider { return cronMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid cron operation: cron", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid cron operation: cron") + s.Nil(result) + }, }, { name: "successful cron list", @@ -181,10 +176,12 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { }, nil) return m }, - validate: func(result json.RawMessage) { - var entries []cron.Entry - err := json.Unmarshal(result, &entries) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var entries []cron.Entry + decodeErr := json.Unmarshal(result, &entries) + s.NoError(decodeErr) s.Len(entries, 1) s.Equal("backup", entries[0].Name) s.Equal("0 2 * * *", entries[0].Schedule) @@ -203,8 +200,11 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { m.EXPECT().List(gomock.Any()).Return(nil, errors.New("permission denied")) return m }, - expectError: true, - errorMsg: "permission denied", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "permission denied") + s.Nil(result) + }, }, { name: "successful cron get", @@ -224,10 +224,12 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { }, nil) return m }, - validate: func(result json.RawMessage) { - var entry cron.Entry - err := json.Unmarshal(result, &entry) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var entry cron.Entry + decodeErr := json.Unmarshal(result, &entry) + s.NoError(decodeErr) s.Equal("backup", entry.Name) }, }, @@ -242,8 +244,11 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { setupMock: func() cron.Provider { return cronMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal cron get data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal cron get data") + s.Nil(result) + }, }, { name: "cron get provider error", @@ -258,8 +263,11 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { m.EXPECT().Get(gomock.Any(), "missing").Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, { name: "successful cron create", @@ -284,10 +292,12 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { ) return m }, - validate: func(result json.RawMessage) { - var r cron.CreateResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r cron.CreateResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("logrotate", r.Name) s.True(r.Changed) }, @@ -303,8 +313,11 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { setupMock: func() cron.Provider { return cronMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal cron create data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal cron create data") + s.Nil(result) + }, }, { name: "cron create provider error", @@ -323,8 +336,11 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { Return(nil, errors.New("already exists")) return m }, - expectError: true, - errorMsg: "already exists", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "already exists") + s.Nil(result) + }, }, { name: "successful cron update", @@ -350,10 +366,12 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { ) return m }, - validate: func(result json.RawMessage) { - var r cron.UpdateResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r cron.UpdateResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("backup", r.Name) s.True(r.Changed) }, @@ -369,8 +387,11 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { setupMock: func() cron.Provider { return cronMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal cron update data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal cron update data") + s.Nil(result) + }, }, { name: "cron update provider error", @@ -387,8 +408,11 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { m.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, { name: "successful cron delete", @@ -406,10 +430,12 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r cron.DeleteResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r cron.DeleteResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("backup", r.Name) s.True(r.Changed) }, @@ -425,8 +451,11 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { setupMock: func() cron.Provider { return cronMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal cron delete data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal cron delete data") + s.Nil(result) + }, }, { name: "cron delete provider error", @@ -441,8 +470,11 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { m.EXPECT().Delete(gomock.Any(), "missing").Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, { name: "unsupported cron sub-operation", @@ -455,39 +487,28 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessCronOperation() { setupMock: func() cron.Provider { return cronMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported cron operation: cron.unknown", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported cron operation: cron.unknown") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := agent.NewScheduleProcessor(tt.setupMock(), slog.Default()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorSchedulePublicTestSuite) TestProcessJobOperationScheduleCategory() { tests := []struct { - name string - jobRequest job.Request - setupMock func() cron.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() cron.Provider + validateFunc func(json.RawMessage, error) }{ { name: "schedule category dispatches correctly", @@ -502,10 +523,12 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessJobOperationScheduleCatego m.EXPECT().List(gomock.Any()).Return([]cron.Entry{}, nil) return m }, - validate: func(result json.RawMessage) { - var entries []cron.Entry - err := json.Unmarshal(result, &entries) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var entries []cron.Entry + decodeErr := json.Unmarshal(result, &entries) + s.NoError(decodeErr) s.Empty(entries) }, }, @@ -520,8 +543,11 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessJobOperationScheduleCatego setupMock: func() cron.Provider { return nil }, - expectError: true, - errorMsg: "cron provider not available", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "cron provider not available") + s.Nil(result) + }, }, } @@ -536,23 +562,13 @@ func (s *ProcessorSchedulePublicTestSuite) TestProcessJobOperationScheduleCatego cronProvider: tt.setupMock(), }) - result, err := agent.ExportProcessJobOperation(a, tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(agent.ExportProcessJobOperation(a, tt.jobRequest)) }) } } -func TestProcessorSchedulePublicTestSuite(t *testing.T) { +func TestProcessorSchedulePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorSchedulePublicTestSuite)) } diff --git a/internal/agent/processor_service_public_test.go b/internal/agent/processor_service_public_test.go index e52392fa6..d9ef330e1 100644 --- a/internal/agent/processor_service_public_test.go +++ b/internal/agent/processor_service_public_test.go @@ -68,12 +68,10 @@ func (s *ProcessorServicePublicTestSuite) newNodeProcessor( func (s *ProcessorServicePublicTestSuite) TestProcessServiceOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() service.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() service.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -83,9 +81,12 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceOperation() { Operation: "service.list", Data: json.RawMessage(`{}`), }, - setupMock: nil, - expectError: true, - errorMsg: "service provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "service provider not available") + s.Nil(result) + }, }, { name: "invalid operation format missing sub-operation", @@ -98,8 +99,11 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceOperation() { setupMock: func() service.Provider { return serviceMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid service operation: service", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid service operation: service") + s.Nil(result) + }, }, { name: "unsupported sub-operation", @@ -112,8 +116,11 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceOperation() { setupMock: func() service.Provider { return serviceMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported service operation: service.unknown", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported service operation: service.unknown") + s.Nil(result) + }, }, } @@ -125,31 +132,17 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceOperation() { } processor := s.newNodeProcessor(serviceProvider) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorServicePublicTestSuite) TestProcessServiceList() { tests := []struct { - name string - jobRequest job.Request - setupMock func() service.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() service.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful list", @@ -170,10 +163,12 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceList() { }, nil) return m }, - validate: func(result json.RawMessage) { - var entries []service.Info - err := json.Unmarshal(result, &entries) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var entries []service.Info + decodeErr := json.Unmarshal(result, &entries) + s.NoError(decodeErr) s.Len(entries, 1) s.Equal("nginx", entries[0].Name) }, @@ -191,39 +186,28 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceList() { m.EXPECT().List(gomock.Any()).Return(nil, errors.New("permission denied")) return m }, - expectError: true, - errorMsg: "permission denied", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "permission denied") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newNodeProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorServicePublicTestSuite) TestProcessServiceGet() { tests := []struct { - name string - jobRequest job.Request - setupMock func() service.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() service.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful get", @@ -242,10 +226,12 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceGet() { }, nil) return m }, - validate: func(result json.RawMessage) { - var info service.Info - err := json.Unmarshal(result, &info) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var info service.Info + decodeErr := json.Unmarshal(result, &info) + s.NoError(decodeErr) s.Equal("nginx", info.Name) s.Equal("running", info.Status) }, @@ -261,8 +247,11 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceGet() { setupMock: func() service.Provider { return serviceMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal service get data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal service get data") + s.Nil(result) + }, }, { name: "provider error", @@ -277,39 +266,28 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceGet() { m.EXPECT().Get(gomock.Any(), "missing").Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newNodeProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorServicePublicTestSuite) TestProcessServiceCreate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() service.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() service.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful create", @@ -332,10 +310,12 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceCreate() { ) return m }, - validate: func(result json.RawMessage) { - var r service.CreateResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r service.CreateResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("my-svc", r.Name) s.True(r.Changed) }, @@ -351,8 +331,11 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceCreate() { setupMock: func() service.Provider { return serviceMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal service create data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal service create data") + s.Nil(result) + }, }, { name: "provider error", @@ -368,39 +351,28 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceCreate() { Return(nil, errors.New("already exists")) return m }, - expectError: true, - errorMsg: "already exists", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "already exists") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newNodeProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorServicePublicTestSuite) TestProcessServiceUpdate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() service.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() service.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful update", @@ -423,10 +395,12 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceUpdate() { ) return m }, - validate: func(result json.RawMessage) { - var r service.UpdateResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r service.UpdateResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("my-svc", r.Name) s.True(r.Changed) }, @@ -442,8 +416,11 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceUpdate() { setupMock: func() service.Provider { return serviceMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal service update data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal service update data") + s.Nil(result) + }, }, { name: "provider error", @@ -459,39 +436,28 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceUpdate() { Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newNodeProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorServicePublicTestSuite) TestProcessServiceDelete() { tests := []struct { - name string - jobRequest job.Request - setupMock func() service.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() service.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful delete", @@ -509,10 +475,12 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceDelete() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r service.DeleteResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r service.DeleteResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("my-svc", r.Name) s.True(r.Changed) }, @@ -528,8 +496,11 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceDelete() { setupMock: func() service.Provider { return serviceMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal service delete data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal service delete data") + s.Nil(result) + }, }, { name: "provider error", @@ -545,39 +516,28 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceDelete() { Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newNodeProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorServicePublicTestSuite) TestProcessServiceStart() { tests := []struct { - name string - jobRequest job.Request - setupMock func() service.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() service.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful start", @@ -595,10 +555,12 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceStart() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r service.ActionResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r service.ActionResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("nginx", r.Name) s.True(r.Changed) }, @@ -614,8 +576,11 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceStart() { setupMock: func() service.Provider { return serviceMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal service start data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal service start data") + s.Nil(result) + }, }, { name: "provider error", @@ -631,39 +596,28 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceStart() { Return(nil, errors.New("failed to start")) return m }, - expectError: true, - errorMsg: "failed to start", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to start") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newNodeProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorServicePublicTestSuite) TestProcessServiceStop() { tests := []struct { - name string - jobRequest job.Request - setupMock func() service.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() service.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful stop", @@ -681,10 +635,12 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceStop() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r service.ActionResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r service.ActionResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("nginx", r.Name) s.True(r.Changed) }, @@ -700,8 +656,11 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceStop() { setupMock: func() service.Provider { return serviceMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal service stop data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal service stop data") + s.Nil(result) + }, }, { name: "provider error", @@ -717,39 +676,28 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceStop() { Return(nil, errors.New("failed to stop")) return m }, - expectError: true, - errorMsg: "failed to stop", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to stop") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newNodeProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorServicePublicTestSuite) TestProcessServiceRestart() { tests := []struct { - name string - jobRequest job.Request - setupMock func() service.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() service.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful restart", @@ -767,10 +715,12 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceRestart() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r service.ActionResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r service.ActionResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("nginx", r.Name) s.True(r.Changed) }, @@ -786,8 +736,11 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceRestart() { setupMock: func() service.Provider { return serviceMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal service restart data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal service restart data") + s.Nil(result) + }, }, { name: "provider error", @@ -803,39 +756,28 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceRestart() { Return(nil, errors.New("failed to restart")) return m }, - expectError: true, - errorMsg: "failed to restart", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to restart") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newNodeProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorServicePublicTestSuite) TestProcessServiceEnable() { tests := []struct { - name string - jobRequest job.Request - setupMock func() service.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() service.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful enable", @@ -853,10 +795,12 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceEnable() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r service.ActionResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r service.ActionResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("nginx", r.Name) s.True(r.Changed) }, @@ -872,8 +816,11 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceEnable() { setupMock: func() service.Provider { return serviceMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal service enable data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal service enable data") + s.Nil(result) + }, }, { name: "provider error", @@ -889,39 +836,28 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceEnable() { Return(nil, errors.New("failed to enable")) return m }, - expectError: true, - errorMsg: "failed to enable", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to enable") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newNodeProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorServicePublicTestSuite) TestProcessServiceDisable() { tests := []struct { - name string - jobRequest job.Request - setupMock func() service.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() service.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful disable", @@ -939,10 +875,12 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceDisable() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r service.ActionResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r service.ActionResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("nginx", r.Name) s.True(r.Changed) }, @@ -958,8 +896,11 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceDisable() { setupMock: func() service.Provider { return serviceMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal service disable data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal service disable data") + s.Nil(result) + }, }, { name: "provider error", @@ -975,31 +916,24 @@ func (s *ProcessorServicePublicTestSuite) TestProcessServiceDisable() { Return(nil, errors.New("failed to disable")) return m }, - expectError: true, - errorMsg: "failed to disable", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to disable") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newNodeProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } -func TestProcessorServicePublicTestSuite(t *testing.T) { +func TestProcessorServicePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorServicePublicTestSuite)) } diff --git a/internal/agent/processor_ssh_key_public_test.go b/internal/agent/processor_ssh_key_public_test.go index e9dde9deb..5425dd15f 100644 --- a/internal/agent/processor_ssh_key_public_test.go +++ b/internal/agent/processor_ssh_key_public_test.go @@ -68,11 +68,10 @@ func (s *ProcessorSSHKeyPublicTestSuite) newProcessor( func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -82,9 +81,12 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyOperation() { Operation: "sshKey.list", Data: json.RawMessage(`{"username":"john"}`), }, - setupMock: nil, - expectError: true, - errorMsg: "user provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "user provider not available") + s.Nil(result) + }, }, { name: "invalid sshKey operation missing sub-operation", @@ -97,8 +99,11 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyOperation() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid sshKey operation: sshKey", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid sshKey operation: sshKey") + s.Nil(result) + }, }, { name: "unsupported sshKey sub-operation", @@ -111,8 +116,11 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyOperation() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported sshKey operation: sshKey.invalid", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported sshKey operation: sshKey.invalid") + s.Nil(result) + }, }, } @@ -124,28 +132,17 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyOperation() { } processor := s.newProcessor(userProvider) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyList() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful ssh key list", @@ -171,10 +168,12 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyList() { }, nil) return m }, - validate: func(result json.RawMessage) { - var keys []user.SSHKey - err := json.Unmarshal(result, &keys) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var keys []user.SSHKey + decodeErr := json.Unmarshal(result, &keys) + s.NoError(decodeErr) s.Len(keys, 2) s.Equal("ssh-ed25519", keys[0].Type) s.Equal("SHA256:abc123", keys[0].Fingerprint) @@ -192,8 +191,11 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyList() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal sshKey list data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal sshKey list data") + s.Nil(result) + }, }, { name: "ssh key list provider error", @@ -210,39 +212,28 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyList() { Return(nil, errors.New("user not found")) return m }, - expectError: true, - errorMsg: "user not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "user not found") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyAdd() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful ssh key add", @@ -266,10 +257,12 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyAdd() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r user.SSHKeyResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r user.SSHKeyResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.True(r.Changed) }, }, @@ -284,8 +277,11 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyAdd() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal sshKey add data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal sshKey add data") + s.Nil(result) + }, }, { name: "ssh key add provider error", @@ -304,39 +300,28 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyAdd() { Return(nil, errors.New("permission denied")) return m }, - expectError: true, - errorMsg: "permission denied", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "permission denied") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyRemove() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful ssh key remove", @@ -355,10 +340,12 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyRemove() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r user.SSHKeyResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r user.SSHKeyResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.True(r.Changed) }, }, @@ -373,8 +360,11 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyRemove() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal sshKey remove data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal sshKey remove data") + s.Nil(result) + }, }, { name: "ssh key remove provider error", @@ -391,31 +381,24 @@ func (s *ProcessorSSHKeyPublicTestSuite) TestProcessSSHKeyRemove() { Return(nil, errors.New("key not found")) return m }, - expectError: true, - errorMsg: "key not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "key not found") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } -func TestProcessorSSHKeyPublicTestSuite(t *testing.T) { +func TestProcessorSSHKeyPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorSSHKeyPublicTestSuite)) } diff --git a/internal/agent/processor_sysctl_public_test.go b/internal/agent/processor_sysctl_public_test.go index 247747bae..bf4abaa27 100644 --- a/internal/agent/processor_sysctl_public_test.go +++ b/internal/agent/processor_sysctl_public_test.go @@ -52,12 +52,10 @@ func (s *ProcessorSysctlPublicTestSuite) TearDownTest() { func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() sysctl.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() sysctl.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -67,9 +65,12 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlOperation() { Operation: "sysctl.list", Data: json.RawMessage(`{}`), }, - setupMock: nil, - expectError: true, - errorMsg: "sysctl provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "sysctl provider not available") + s.Nil(result) + }, }, { name: "invalid sysctl operation missing sub-operation", @@ -82,8 +83,11 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlOperation() { setupMock: func() sysctl.Provider { return sysctlMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid sysctl operation: sysctl", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid sysctl operation: sysctl") + s.Nil(result) + }, }, { name: "unsupported sysctl sub-operation", @@ -96,8 +100,11 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlOperation() { setupMock: func() sysctl.Provider { return sysctlMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported sysctl operation: sysctl.unknown", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported sysctl operation: sysctl.unknown") + s.Nil(result) + }, }, } @@ -120,31 +127,17 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlOperation() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlList() { tests := []struct { - name string - jobRequest job.Request - setupMock func() sysctl.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() sysctl.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful sysctl list", @@ -162,10 +155,12 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlList() { }, nil) return m }, - validate: func(result json.RawMessage) { - var entries []sysctl.Entry - err := json.Unmarshal(result, &entries) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var entries []sysctl.Entry + decodeErr := json.Unmarshal(result, &entries) + s.NoError(decodeErr) s.Len(entries, 2) s.Equal("net.ipv4.ip_forward", entries[0].Key) s.Equal("1", entries[0].Value) @@ -184,8 +179,11 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlList() { m.EXPECT().List(gomock.Any()).Return(nil, errors.New("permission denied")) return m }, - expectError: true, - errorMsg: "permission denied", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "permission denied") + s.Nil(result) + }, }, } @@ -203,31 +201,17 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlList() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlGet() { tests := []struct { - name string - jobRequest job.Request - setupMock func() sysctl.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() sysctl.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful sysctl get", @@ -245,10 +229,12 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlGet() { }, nil) return m }, - validate: func(result json.RawMessage) { - var entry sysctl.Entry - err := json.Unmarshal(result, &entry) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var entry sysctl.Entry + decodeErr := json.Unmarshal(result, &entry) + s.NoError(decodeErr) s.Equal("net.ipv4.ip_forward", entry.Key) s.Equal("1", entry.Value) }, @@ -264,8 +250,11 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlGet() { setupMock: func() sysctl.Provider { return sysctlMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal sysctl get data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal sysctl get data") + s.Nil(result) + }, }, { name: "sysctl get provider error", @@ -280,8 +269,11 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlGet() { m.EXPECT().Get(gomock.Any(), "missing.key").Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } @@ -299,31 +291,17 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlGet() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlCreate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() sysctl.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() sysctl.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful sysctl create", @@ -344,10 +322,12 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlCreate() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r sysctl.CreateResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r sysctl.CreateResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("net.ipv4.ip_forward", r.Key) s.True(r.Changed) }, @@ -363,8 +343,11 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlCreate() { setupMock: func() sysctl.Provider { return sysctlMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal sysctl create data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal sysctl create data") + s.Nil(result) + }, }, { name: "sysctl create provider error", @@ -381,8 +364,11 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlCreate() { Return(nil, errors.New("invalid parameter")) return m }, - expectError: true, - errorMsg: "invalid parameter", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid parameter") + s.Nil(result) + }, }, } @@ -400,31 +386,17 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlCreate() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlUpdate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() sysctl.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() sysctl.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful sysctl update", @@ -445,10 +417,12 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlUpdate() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r sysctl.UpdateResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r sysctl.UpdateResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("net.ipv4.ip_forward", r.Key) s.True(r.Changed) }, @@ -464,8 +438,11 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlUpdate() { setupMock: func() sysctl.Provider { return sysctlMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal sysctl update data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal sysctl update data") + s.Nil(result) + }, }, { name: "sysctl update provider error", @@ -482,8 +459,11 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlUpdate() { Return(nil, errors.New("not managed")) return m }, - expectError: true, - errorMsg: "not managed", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not managed") + s.Nil(result) + }, }, } @@ -501,31 +481,17 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlUpdate() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlDelete() { tests := []struct { - name string - jobRequest job.Request - setupMock func() sysctl.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() sysctl.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful sysctl delete", @@ -543,10 +509,12 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlDelete() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r sysctl.DeleteResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r sysctl.DeleteResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("net.ipv4.ip_forward", r.Key) s.True(r.Changed) }, @@ -562,8 +530,11 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlDelete() { setupMock: func() sysctl.Provider { return sysctlMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal sysctl delete data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal sysctl delete data") + s.Nil(result) + }, }, { name: "sysctl delete provider error", @@ -578,8 +549,11 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlDelete() { m.EXPECT().Delete(gomock.Any(), "missing.key").Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } @@ -597,23 +571,13 @@ func (s *ProcessorSysctlPublicTestSuite) TestProcessSysctlDelete() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } -func TestProcessorSysctlPublicTestSuite(t *testing.T) { +func TestProcessorSysctlPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorSysctlPublicTestSuite)) } diff --git a/internal/agent/processor_timezone_public_test.go b/internal/agent/processor_timezone_public_test.go index 800b74ad0..8cac7bc1a 100644 --- a/internal/agent/processor_timezone_public_test.go +++ b/internal/agent/processor_timezone_public_test.go @@ -52,12 +52,10 @@ func (s *ProcessorTimezonePublicTestSuite) TearDownTest() { func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() timezone.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() timezone.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -67,9 +65,12 @@ func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneOperation() { Operation: "timezone.get", Data: json.RawMessage(`{}`), }, - setupMock: nil, - expectError: true, - errorMsg: "timezone provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "timezone provider not available") + s.Nil(result) + }, }, { name: "invalid timezone operation missing sub-operation", @@ -82,8 +83,11 @@ func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneOperation() { setupMock: func() timezone.Provider { return timezoneMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid timezone operation: timezone", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid timezone operation: timezone") + s.Nil(result) + }, }, { name: "unsupported timezone sub-operation", @@ -96,8 +100,11 @@ func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneOperation() { setupMock: func() timezone.Provider { return timezoneMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported timezone operation: timezone.unknown", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported timezone operation: timezone.unknown") + s.Nil(result) + }, }, } @@ -119,31 +126,17 @@ func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneOperation() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneGet() { tests := []struct { - name string - jobRequest job.Request - setupMock func() timezone.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() timezone.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful timezone get", @@ -161,10 +154,12 @@ func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneGet() { }, nil) return m }, - validate: func(result json.RawMessage) { - var info timezone.Info - err := json.Unmarshal(result, &info) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var info timezone.Info + decodeErr := json.Unmarshal(result, &info) + s.NoError(decodeErr) s.Equal("America/New_York", info.Timezone) s.Equal("-05:00", info.UTCOffset) }, @@ -182,8 +177,11 @@ func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneGet() { m.EXPECT().Get(gomock.Any()).Return(nil, errors.New("timedatectl not found")) return m }, - expectError: true, - errorMsg: "timedatectl not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "timedatectl not found") + s.Nil(result) + }, }, } @@ -200,31 +198,17 @@ func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneGet() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneUpdate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() timezone.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() timezone.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful timezone update", @@ -242,10 +226,12 @@ func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneUpdate() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r timezone.UpdateResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r timezone.UpdateResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("America/New_York", r.Timezone) s.True(r.Changed) }, @@ -261,8 +247,11 @@ func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneUpdate() { setupMock: func() timezone.Provider { return timezoneMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal timezone update data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal timezone update data") + s.Nil(result) + }, }, { name: "timezone update provider error", @@ -279,8 +268,11 @@ func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneUpdate() { Return(nil, errors.New("invalid timezone")) return m }, - expectError: true, - errorMsg: "invalid timezone", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid timezone") + s.Nil(result) + }, }, } @@ -297,23 +289,13 @@ func (s *ProcessorTimezonePublicTestSuite) TestProcessTimezoneUpdate() { config.Config{}, slog.Default(), ) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } -func TestProcessorTimezonePublicTestSuite(t *testing.T) { +func TestProcessorTimezonePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorTimezonePublicTestSuite)) } diff --git a/internal/agent/processor_user_public_test.go b/internal/agent/processor_user_public_test.go index 2c9d73daa..2c119979a 100644 --- a/internal/agent/processor_user_public_test.go +++ b/internal/agent/processor_user_public_test.go @@ -68,11 +68,10 @@ func (s *ProcessorUserPublicTestSuite) newProcessor( func (s *ProcessorUserPublicTestSuite) TestProcessUserOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -82,9 +81,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserOperation() { Operation: "user.list", Data: json.RawMessage(`{}`), }, - setupMock: nil, - expectError: true, - errorMsg: "user provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "user provider not available") + s.Nil(result) + }, }, { name: "invalid user operation missing sub-operation", @@ -97,8 +99,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserOperation() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid user operation: user", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid user operation: user") + s.Nil(result) + }, }, { name: "unsupported user sub-operation", @@ -111,8 +116,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserOperation() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported user operation: user.unknown", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported user operation: user.unknown") + s.Nil(result) + }, }, } @@ -124,28 +132,17 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserOperation() { } processor := s.newProcessor(userProvider) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorUserPublicTestSuite) TestProcessUserList() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful user list", @@ -163,10 +160,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserList() { }, nil) return m }, - validate: func(result json.RawMessage) { - var users []user.User - err := json.Unmarshal(result, &users) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var users []user.User + decodeErr := json.Unmarshal(result, &users) + s.NoError(decodeErr) s.Len(users, 2) s.Equal("root", users[0].Name) s.Equal("john", users[1].Name) @@ -185,39 +184,28 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserList() { m.EXPECT().ListUsers(gomock.Any()).Return(nil, errors.New("permission denied")) return m }, - expectError: true, - errorMsg: "permission denied", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "permission denied") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorUserPublicTestSuite) TestProcessUserGet() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful user get", @@ -235,10 +223,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserGet() { }, nil) return m }, - validate: func(result json.RawMessage) { - var u user.User - err := json.Unmarshal(result, &u) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var u user.User + decodeErr := json.Unmarshal(result, &u) + s.NoError(decodeErr) s.Equal("john", u.Name) s.Equal(1000, u.UID) }, @@ -254,8 +244,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserGet() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal user get data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal user get data") + s.Nil(result) + }, }, { name: "user get provider error", @@ -270,39 +263,28 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserGet() { m.EXPECT().GetUser(gomock.Any(), "missing").Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorUserPublicTestSuite) TestProcessUserCreate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful user create", @@ -323,10 +305,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserCreate() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r user.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r user.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("newuser", r.Name) s.True(r.Changed) }, @@ -342,8 +326,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserCreate() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal user create data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal user create data") + s.Nil(result) + }, }, { name: "user create provider error", @@ -360,39 +347,28 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserCreate() { Return(nil, errors.New("user already exists")) return m }, - expectError: true, - errorMsg: "user already exists", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "user already exists") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorUserPublicTestSuite) TestProcessUserUpdate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful user update", @@ -412,10 +388,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserUpdate() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r user.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r user.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("john", r.Name) s.True(r.Changed) }, @@ -431,8 +409,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserUpdate() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal user update data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal user update data") + s.Nil(result) + }, }, { name: "user update provider error", @@ -449,39 +430,28 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserUpdate() { Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorUserPublicTestSuite) TestProcessUserDelete() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful user delete", @@ -499,10 +469,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserDelete() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r user.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r user.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("olduser", r.Name) s.True(r.Changed) }, @@ -518,8 +490,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserDelete() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal user delete data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal user delete data") + s.Nil(result) + }, }, { name: "user delete provider error", @@ -534,39 +509,28 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserDelete() { m.EXPECT().DeleteUser(gomock.Any(), "missing").Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorUserPublicTestSuite) TestProcessUserPassword() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful password change", @@ -586,10 +550,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserPassword() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r user.Result - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r user.Result + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("john", r.Name) s.True(r.Changed) }, @@ -605,8 +571,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserPassword() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal user password data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal user password data") + s.Nil(result) + }, }, { name: "password change provider error", @@ -623,38 +592,28 @@ func (s *ProcessorUserPublicTestSuite) TestProcessUserPassword() { Return(nil, errors.New("permission denied")) return m }, - expectError: true, - errorMsg: "permission denied", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "permission denied") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorUserPublicTestSuite) TestProcessGroupOperation() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "nil provider returns error", @@ -664,9 +623,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupOperation() { Operation: "group.list", Data: json.RawMessage(`{}`), }, - setupMock: nil, - expectError: true, - errorMsg: "user provider not available", + setupMock: nil, + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "user provider not available") + s.Nil(result) + }, }, { name: "invalid group operation missing sub-operation", @@ -679,8 +641,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupOperation() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "invalid group operation: group", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid group operation: group") + s.Nil(result) + }, }, { name: "unsupported group sub-operation", @@ -693,8 +658,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupOperation() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unsupported group operation: group.unknown", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unsupported group operation: group.unknown") + s.Nil(result) + }, }, } @@ -706,28 +674,17 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupOperation() { } processor := s.newProcessor(userProvider) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorUserPublicTestSuite) TestProcessGroupList() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful group list", @@ -745,10 +702,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupList() { }, nil) return m }, - validate: func(result json.RawMessage) { - var groups []user.Group - err := json.Unmarshal(result, &groups) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var groups []user.Group + decodeErr := json.Unmarshal(result, &groups) + s.NoError(decodeErr) s.Len(groups, 2) s.Equal("root", groups[0].Name) s.Equal("sudo", groups[1].Name) @@ -767,39 +726,28 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupList() { m.EXPECT().ListGroups(gomock.Any()).Return(nil, errors.New("permission denied")) return m }, - expectError: true, - errorMsg: "permission denied", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "permission denied") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorUserPublicTestSuite) TestProcessGroupGet() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful group get", @@ -816,10 +764,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupGet() { }, nil) return m }, - validate: func(result json.RawMessage) { - var g user.Group - err := json.Unmarshal(result, &g) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var g user.Group + decodeErr := json.Unmarshal(result, &g) + s.NoError(decodeErr) s.Equal("sudo", g.Name) s.Equal(27, g.GID) }, @@ -835,8 +785,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupGet() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal group get data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal group get data") + s.Nil(result) + }, }, { name: "group get provider error", @@ -851,39 +804,28 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupGet() { m.EXPECT().GetGroup(gomock.Any(), "missing").Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorUserPublicTestSuite) TestProcessGroupCreate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful group create", @@ -903,10 +845,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupCreate() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r user.GroupResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r user.GroupResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("developers", r.Name) s.True(r.Changed) }, @@ -922,8 +866,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupCreate() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal group create data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal group create data") + s.Nil(result) + }, }, { name: "group create provider error", @@ -940,39 +887,28 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupCreate() { Return(nil, errors.New("group already exists")) return m }, - expectError: true, - errorMsg: "group already exists", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "group already exists") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorUserPublicTestSuite) TestProcessGroupUpdate() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful group update", @@ -994,10 +930,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupUpdate() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r user.GroupResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r user.GroupResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("developers", r.Name) s.True(r.Changed) }, @@ -1013,8 +951,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupUpdate() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal group update data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal group update data") + s.Nil(result) + }, }, { name: "group update provider error", @@ -1031,39 +972,28 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupUpdate() { Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } func (s *ProcessorUserPublicTestSuite) TestProcessGroupDelete() { tests := []struct { - name string - jobRequest job.Request - setupMock func() user.Provider - expectError bool - errorMsg string - validate func(json.RawMessage) + name string + jobRequest job.Request + setupMock func() user.Provider + validateFunc func(json.RawMessage, error) }{ { name: "successful group delete", @@ -1081,10 +1011,12 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupDelete() { }, nil) return m }, - validate: func(result json.RawMessage) { - var r user.GroupResult - err := json.Unmarshal(result, &r) + validateFunc: func(result json.RawMessage, err error) { s.NoError(err) + s.NotNil(result) + var r user.GroupResult + decodeErr := json.Unmarshal(result, &r) + s.NoError(decodeErr) s.Equal("oldgroup", r.Name) s.True(r.Changed) }, @@ -1100,8 +1032,11 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupDelete() { setupMock: func() user.Provider { return userMocks.NewMockProvider(s.mockCtrl) }, - expectError: true, - errorMsg: "unmarshal group delete data", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "unmarshal group delete data") + s.Nil(result) + }, }, { name: "group delete provider error", @@ -1116,31 +1051,24 @@ func (s *ProcessorUserPublicTestSuite) TestProcessGroupDelete() { m.EXPECT().DeleteGroup(gomock.Any(), "missing").Return(nil, errors.New("not found")) return m }, - expectError: true, - errorMsg: "not found", + validateFunc: func(result json.RawMessage, err error) { + s.Error(err) + s.Contains(err.Error(), "not found") + s.Nil(result) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { processor := s.newProcessor(tt.setupMock()) - result, err := processor(tt.jobRequest) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(processor(tt.jobRequest)) }) } } -func TestProcessorUserPublicTestSuite(t *testing.T) { +func TestProcessorUserPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessorUserPublicTestSuite)) } diff --git a/internal/agent/seed_public_test.go b/internal/agent/seed_public_test.go index d44947712..9715f78e1 100644 --- a/internal/agent/seed_public_test.go +++ b/internal/agent/seed_public_test.go @@ -84,10 +84,7 @@ func (s *SeedPublicTestSuite) TestSeedSystemTemplates() { name string setupFunc func() setupMock func(ctrl *gomock.Controller, mockObj *filemocks.MockObjectStore, putNames *[]string) - wantErr bool - errContains string - wantPutCalls int - wantPutName string + validateFunc func(error, *[]string) }{ { name: "when WalkDir callback receives error", @@ -100,8 +97,12 @@ func (s *SeedPublicTestSuite) TestSeedSystemTemplates() { _ *[]string, ) { }, - wantErr: true, - errContains: "walk error", + validateFunc: func(err error, putNames *[]string) { + s.Error(err) + s.Contains(err.Error(), "walk error") + + s.Len(*putNames, 0) + }, }, { name: "when directory contains only .gitkeep skips it", @@ -117,8 +118,11 @@ func (s *SeedPublicTestSuite) TestSeedSystemTemplates() { ) { // No GetBytes or PutBytes calls expected — .gitkeep is skipped. }, - wantErr: false, - wantPutCalls: 0, + validateFunc: func(err error, putNames *[]string) { + s.NoError(err) + + s.Len(*putNames, 0) + }, }, { name: "when ReadFile fails returns error", @@ -134,8 +138,12 @@ func (s *SeedPublicTestSuite) TestSeedSystemTemplates() { _ *[]string, ) { }, - wantErr: true, - errContains: "read embedded template", + validateFunc: func(err error, putNames *[]string) { + s.Error(err) + s.Contains(err.Error(), "read embedded template") + + s.Len(*putNames, 0) + }, }, { name: "when template not found in store uploads it", @@ -163,9 +171,13 @@ func (s *SeedPublicTestSuite) TestSeedSystemTemplates() { return &jetstream.ObjectInfo{}, nil }) }, - wantErr: false, - wantPutCalls: 1, - wantPutName: "osapi/test.tmpl", + validateFunc: func(err error, putNames *[]string) { + s.NoError(err) + + s.Len(*putNames, 1) + + s.Equal("osapi/test.tmpl", (*putNames)[0]) + }, }, { name: "when template unchanged in store skips upload", @@ -182,8 +194,11 @@ func (s *SeedPublicTestSuite) TestSeedSystemTemplates() { GetBytes(gomock.Any(), gomock.Any()). Return(templateData, nil) }, - wantErr: false, - wantPutCalls: 0, + validateFunc: func(err error, putNames *[]string) { + s.NoError(err) + + s.Len(*putNames, 0) + }, }, { name: "when template changed in store overwrites it", @@ -212,9 +227,13 @@ func (s *SeedPublicTestSuite) TestSeedSystemTemplates() { return &jetstream.ObjectInfo{}, nil }) }, - wantErr: false, - wantPutCalls: 1, - wantPutName: "osapi/test.tmpl", + validateFunc: func(err error, putNames *[]string) { + s.NoError(err) + + s.Len(*putNames, 1) + + s.Equal("osapi/test.tmpl", (*putNames)[0]) + }, }, { name: "when PutBytes fails returns wrapped error", @@ -242,9 +261,12 @@ func (s *SeedPublicTestSuite) TestSeedSystemTemplates() { return nil, errors.New("object store unavailable") }) }, - wantErr: true, - errContains: "upload osapi template", - wantPutCalls: 1, + validateFunc: func(err error, putNames *[]string) { + s.Error(err) + s.Contains(err.Error(), "upload osapi template") + + s.Len(*putNames, 1) + }, }, } @@ -265,24 +287,14 @@ func (s *SeedPublicTestSuite) TestSeedSystemTemplates() { } err := agent.SeedSystemTemplates(s.ctx, s.logger, mockObj) - - if tt.wantErr { - s.Error(err) - s.Contains(err.Error(), tt.errContains) - } else { - s.NoError(err) - } - - s.Len(*putNames, tt.wantPutCalls) - - if tt.wantPutCalls > 0 && tt.wantPutName != "" { - s.Equal(tt.wantPutName, (*putNames)[0]) - } + tt.validateFunc(err, putNames) }) } } -func TestSeedPublicTestSuite(t *testing.T) { +func TestSeedPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SeedPublicTestSuite)) } @@ -306,13 +318,17 @@ func (d *errorDir) Stat() (fs.FileInfo, error) { return &dirInfo{}, nil } -func (d *errorDir) Read(_ []byte) (int, error) { +func (d *errorDir) Read( + _ []byte, +) (int, error) { return 0, fmt.Errorf("not a file") } func (d *errorDir) Close() error { return nil } -func (d *errorDir) ReadDir(_ int) ([]fs.DirEntry, error) { +func (d *errorDir) ReadDir( + _ int, +) ([]fs.DirEntry, error) { return nil, fmt.Errorf("walk error") } diff --git a/internal/agent/fixture_public_test.go b/internal/agent/test_agent_public_test.go similarity index 98% rename from internal/agent/fixture_public_test.go rename to internal/agent/test_agent_public_test.go index c52ecb199..98720c50b 100644 --- a/internal/agent/fixture_public_test.go +++ b/internal/agent/test_agent_public_test.go @@ -81,7 +81,9 @@ type newTestAgentParams struct { // newTestAgent builds a ProviderRegistry from the supplied providers and // constructs an Agent — replacing the old 19-argument agent.New() call used // across all test suites. -func newTestAgent(p newTestAgentParams) *agent.Agent { +func newTestAgent( + p newTestAgentParams, +) *agent.Agent { logger := p.logger if logger == nil { logger = slog.Default() diff --git a/internal/audit/export/export_public_test.go b/internal/audit/export/export_public_test.go index dc12b15eb..bd9095af6 100644 --- a/internal/audit/export/export_public_test.go +++ b/internal/audit/export/export_public_test.go @@ -392,7 +392,9 @@ func (suite *ExportPublicTestSuite) TestRunProgress() { } } -func TestExportPublicTestSuite(t *testing.T) { +func TestExportPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ExportPublicTestSuite)) } diff --git a/internal/audit/export/file_public_test.go b/internal/audit/export/file_public_test.go index be318ac7b..4e401a9e2 100644 --- a/internal/audit/export/file_public_test.go +++ b/internal/audit/export/file_public_test.go @@ -359,14 +359,18 @@ func (suite *FileExporterPublicTestSuite) readLines( return lines } -func TestFileExporterPublicTestSuite(t *testing.T) { +func TestFileExporterPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FileExporterPublicTestSuite)) } // failWriter is a writer that always returns an error on Write. type failWriter struct{} -func (w *failWriter) Write(_ []byte) (int, error) { +func (w *failWriter) Write( + _ []byte, +) (int, error) { return 0, fmt.Errorf("write failed") } @@ -377,7 +381,9 @@ func (w *failWriter) Close() error { // failCloseWriter succeeds on Write but fails on Close. type failCloseWriter struct{} -func (w *failCloseWriter) Write(p []byte) (int, error) { +func (w *failCloseWriter) Write( + p []byte, +) (int, error) { return len(p), nil } diff --git a/internal/audit/stream_store_public_test.go b/internal/audit/stream_store_public_test.go index d8408158e..9443ad875 100644 --- a/internal/audit/stream_store_public_test.go +++ b/internal/audit/stream_store_public_test.go @@ -668,6 +668,8 @@ func (s *StreamStorePublicTestSuite) TestListAll() { } } -func TestStreamStorePublicTestSuite(t *testing.T) { +func TestStreamStorePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(StreamStorePublicTestSuite)) } diff --git a/internal/authtoken/permissions_public_test.go b/internal/authtoken/permissions_public_test.go index 8e4474973..56369ef14 100644 --- a/internal/authtoken/permissions_public_test.go +++ b/internal/authtoken/permissions_public_test.go @@ -38,79 +38,108 @@ func (s *PermissionsPublicTestSuite) TestResolvePermissions() { roles []string directPermissions []string customRoles map[string][]string - expectPerms []string - expectMissing []string + validateFunc func(map[string]bool) }{ { - name: "admin role gets all permissions", - roles: []string{"admin"}, - expectPerms: authtoken.AllPermissions, - expectMissing: nil, + name: "admin role gets all permissions", + roles: []string{"admin"}, + validateFunc: func(resolved map[string]bool) { + for _, p := range authtoken.AllPermissions { + s.True(resolved[p], "expected permission %s to be present", p) + } + }, }, { name: "write role gets write permissions but not audit", roles: []string{"write"}, - expectPerms: []string{ - authtoken.PermNodeRead, - authtoken.PermNetworkRead, - authtoken.PermNetworkWrite, - authtoken.PermJobRead, - authtoken.PermJobWrite, - authtoken.PermHealthRead, - authtoken.PermFileRead, - authtoken.PermFileWrite, - }, - expectMissing: []string{ - authtoken.PermAuditRead, + validateFunc: func(resolved map[string]bool) { + for _, p := range []string{ + authtoken.PermNodeRead, + authtoken.PermNetworkRead, + authtoken.PermNetworkWrite, + authtoken.PermJobRead, + authtoken.PermJobWrite, + authtoken.PermHealthRead, + authtoken.PermFileRead, + authtoken.PermFileWrite, + } { + s.True(resolved[p], "expected permission %s to be present", p) + } + for _, p := range []string{ + authtoken.PermAuditRead, + } { + s.False(resolved[p], "expected permission %s to be absent", p) + } }, }, { name: "read role gets read-only permissions", roles: []string{"read"}, - expectPerms: []string{ - authtoken.PermNodeRead, - authtoken.PermNetworkRead, - authtoken.PermJobRead, - authtoken.PermHealthRead, - authtoken.PermFileRead, - }, - expectMissing: []string{ - authtoken.PermNetworkWrite, - authtoken.PermJobWrite, - authtoken.PermAuditRead, - authtoken.PermFileWrite, + validateFunc: func(resolved map[string]bool) { + for _, p := range []string{ + authtoken.PermNodeRead, + authtoken.PermNetworkRead, + authtoken.PermJobRead, + authtoken.PermHealthRead, + authtoken.PermFileRead, + } { + s.True(resolved[p], "expected permission %s to be present", p) + } + for _, p := range []string{ + authtoken.PermNetworkWrite, + authtoken.PermJobWrite, + authtoken.PermAuditRead, + authtoken.PermFileWrite, + } { + s.False(resolved[p], "expected permission %s to be absent", p) + } }, }, { - name: "unknown role gets no permissions", - roles: []string{"unknown"}, - expectPerms: nil, - expectMissing: authtoken.AllPermissions, + name: "unknown role gets no permissions", + roles: []string{"unknown"}, + validateFunc: func(resolved map[string]bool) { + for _, p := range authtoken.AllPermissions { + s.False(resolved[p], "expected permission %s to be absent", p) + } + }, }, { - name: "empty roles gets no permissions", - roles: []string{}, - expectPerms: nil, - expectMissing: authtoken.AllPermissions, + name: "empty roles gets no permissions", + roles: []string{}, + validateFunc: func(resolved map[string]bool) { + for _, p := range authtoken.AllPermissions { + s.False(resolved[p], "expected permission %s to be absent", p) + } + }, }, { - name: "nil roles gets no permissions", - roles: nil, - expectPerms: nil, - expectMissing: authtoken.AllPermissions, + name: "nil roles gets no permissions", + roles: nil, + validateFunc: func(resolved map[string]bool) { + for _, p := range authtoken.AllPermissions { + s.False(resolved[p], "expected permission %s to be absent", p) + } + }, }, { name: "direct permissions override roles", roles: []string{"admin"}, directPermissions: []string{authtoken.PermNodeRead}, - expectPerms: []string{authtoken.PermNodeRead}, - expectMissing: []string{ - authtoken.PermNetworkRead, - authtoken.PermNetworkWrite, - authtoken.PermJobRead, - authtoken.PermJobWrite, - authtoken.PermHealthRead, - authtoken.PermAuditRead, + validateFunc: func(resolved map[string]bool) { + for _, p := range []string{authtoken.PermNodeRead} { + s.True(resolved[p], "expected permission %s to be present", p) + } + for _, p := range []string{ + authtoken.PermNetworkRead, + authtoken.PermNetworkWrite, + authtoken.PermJobRead, + authtoken.PermJobWrite, + authtoken.PermHealthRead, + authtoken.PermAuditRead, + } { + s.False(resolved[p], "expected permission %s to be absent", p) + } }, }, { @@ -119,15 +148,21 @@ func (s *PermissionsPublicTestSuite) TestResolvePermissions() { customRoles: map[string][]string{ "ops": {authtoken.PermNodeRead, authtoken.PermHealthRead}, }, - expectPerms: []string{ - authtoken.PermNodeRead, - authtoken.PermHealthRead, - }, - expectMissing: []string{ - authtoken.PermNetworkRead, - authtoken.PermNetworkWrite, - authtoken.PermJobRead, - authtoken.PermJobWrite, + validateFunc: func(resolved map[string]bool) { + for _, p := range []string{ + authtoken.PermNodeRead, + authtoken.PermHealthRead, + } { + s.True(resolved[p], "expected permission %s to be present", p) + } + for _, p := range []string{ + authtoken.PermNetworkRead, + authtoken.PermNetworkWrite, + authtoken.PermJobRead, + authtoken.PermJobWrite, + } { + s.False(resolved[p], "expected permission %s to be absent", p) + } }, }, { @@ -136,85 +171,98 @@ func (s *PermissionsPublicTestSuite) TestResolvePermissions() { customRoles: map[string][]string{ "read": {authtoken.PermHealthRead}, }, - expectPerms: []string{authtoken.PermHealthRead}, - expectMissing: []string{ - authtoken.PermNodeRead, - authtoken.PermNetworkRead, + validateFunc: func(resolved map[string]bool) { + for _, p := range []string{authtoken.PermHealthRead} { + s.True(resolved[p], "expected permission %s to be present", p) + } + for _, p := range []string{ + authtoken.PermNodeRead, + authtoken.PermNetworkRead, + } { + s.False(resolved[p], "expected permission %s to be absent", p) + } }, }, { name: "multiple roles merge permissions", roles: []string{"read", "write"}, - expectPerms: []string{ - authtoken.PermNodeRead, - authtoken.PermNetworkRead, - authtoken.PermNetworkWrite, - authtoken.PermJobRead, - authtoken.PermJobWrite, - authtoken.PermHealthRead, + validateFunc: func(resolved map[string]bool) { + for _, p := range []string{ + authtoken.PermNodeRead, + authtoken.PermNetworkRead, + authtoken.PermNetworkWrite, + authtoken.PermJobRead, + authtoken.PermJobWrite, + authtoken.PermHealthRead, + } { + s.True(resolved[p], "expected permission %s to be present", p) + } }, }, } for _, tt := range tests { s.Run(tt.name, func() { - resolved := authtoken.ResolvePermissions( + tt.validateFunc(authtoken.ResolvePermissions( tt.roles, tt.directPermissions, tt.customRoles, - ) - - for _, p := range tt.expectPerms { - s.True(resolved[p], "expected permission %s to be present", p) - } - for _, p := range tt.expectMissing { - s.False(resolved[p], "expected permission %s to be absent", p) - } + )) }) } } func (s *PermissionsPublicTestSuite) TestHasPermission() { tests := []struct { - name string - resolved map[string]bool - required string - expected bool + name string + resolved map[string]bool + required string + validateFunc func(bool) }{ { name: "present permission returns true", resolved: map[string]bool{authtoken.PermNodeRead: true}, required: authtoken.PermNodeRead, - expected: true, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { name: "absent permission returns false", resolved: map[string]bool{authtoken.PermNodeRead: true}, required: authtoken.PermJobWrite, - expected: false, + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { name: "empty resolved set returns false", resolved: map[string]bool{}, required: authtoken.PermNodeRead, - expected: false, + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { name: "nil resolved set returns false", resolved: nil, required: authtoken.PermNodeRead, - expected: false, + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { result := authtoken.HasPermission(tt.resolved, tt.required) - s.Equal(tt.expected, result) + tt.validateFunc(result) }) } } -func TestPermissionsPublicTestSuite(t *testing.T) { +func TestPermissionsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PermissionsPublicTestSuite)) } diff --git a/internal/authtoken/token_public_test.go b/internal/authtoken/token_public_test.go index 2962f3535..b6bd3bc8f 100644 --- a/internal/authtoken/token_public_test.go +++ b/internal/authtoken/token_public_test.go @@ -65,12 +65,12 @@ func (s *AuthTokenPublicTestSuite) TestGenerate() { func (s *AuthTokenPublicTestSuite) TestValidate() { tests := []struct { - name string - tokenFunc func() string - signingKey string - expectError bool - errContains string - validate func(*authtoken.CustomClaims) + name string + tokenFunc func() string + signingKey string + expectError bool + errContains string + validateFunc func(*authtoken.CustomClaims) }{ { name: "valid token", @@ -80,7 +80,7 @@ func (s *AuthTokenPublicTestSuite) TestValidate() { }, signingKey: s.signingKey, expectError: false, - validate: func(claims *authtoken.CustomClaims) { + validateFunc: func(claims *authtoken.CustomClaims) { s.Equal([]string{"admin"}, claims.Roles) s.Equal("test-subject", claims.Subject) s.Equal("osapi", claims.Issuer) @@ -166,9 +166,7 @@ func (s *AuthTokenPublicTestSuite) TestValidate() { } else { s.NoError(err) s.NotNil(claims) - if tt.validate != nil { - tt.validate(claims) - } + tt.validateFunc(claims) } }) } @@ -176,24 +174,43 @@ func (s *AuthTokenPublicTestSuite) TestValidate() { func (s *AuthTokenPublicTestSuite) TestGenerateAndValidateRoundTrip() { tests := []struct { - name string - roles []string - subject string + name string + roles []string + subject string + validateFunc func(*authtoken.CustomClaims, error) }{ { name: "admin role round trip", roles: []string{"admin"}, subject: "admin-user", + validateFunc: func(claims *authtoken.CustomClaims, err error) { + s.NoError(err) + s.NotNil(claims) + s.Equal([]string{"admin"}, claims.Roles) + s.Equal("admin-user", claims.Subject) + }, }, { name: "multiple roles round trip", roles: []string{"read", "write"}, subject: "rw-user", + validateFunc: func(claims *authtoken.CustomClaims, err error) { + s.NoError(err) + s.NotNil(claims) + s.Equal([]string{"read", "write"}, claims.Roles) + s.Equal("rw-user", claims.Subject) + }, }, { name: "read only round trip", roles: []string{"read"}, subject: "reader", + validateFunc: func(claims *authtoken.CustomClaims, err error) { + s.NoError(err) + s.NotNil(claims) + s.Equal([]string{"read"}, claims.Roles) + s.Equal("reader", claims.Subject) + }, }, } @@ -203,15 +220,13 @@ func (s *AuthTokenPublicTestSuite) TestGenerateAndValidateRoundTrip() { s.NoError(err) s.NotEmpty(tokenString) - claims, err := s.token.Validate(tokenString, s.signingKey) - s.NoError(err) - s.NotNil(claims) - s.Equal(tt.roles, claims.Roles) - s.Equal(tt.subject, claims.Subject) + tt.validateFunc(s.token.Validate(tokenString, s.signingKey)) }) } } -func TestAuthTokenPublicTestSuite(t *testing.T) { +func TestAuthTokenPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AuthTokenPublicTestSuite)) } diff --git a/internal/cli/lifecycle_public_test.go b/internal/cli/lifecycle_public_test.go index 58e3f7a60..3df656490 100644 --- a/internal/cli/lifecycle_public_test.go +++ b/internal/cli/lifecycle_public_test.go @@ -36,7 +36,9 @@ type LifecyclePublicTestSuite struct { suite.Suite } -func TestLifecyclePublicTestSuite(t *testing.T) { +func TestLifecyclePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LifecyclePublicTestSuite)) } @@ -44,17 +46,21 @@ func (suite *LifecyclePublicTestSuite) TestRunServer() { tests := []struct { name string cleanupCount int - wantCleanups int + validateFunc func(int) }{ { name: "when context cancelled stops server", cleanupCount: 0, - wantCleanups: 0, + validateFunc: func(got int) { + assert.Equal(suite.T(), 0, got) + }, }, { name: "when cleanup functions provided runs all", cleanupCount: 3, - wantCleanups: 3, + validateFunc: func(got int) { + assert.Equal(suite.T(), 3, got) + }, }, } @@ -75,7 +81,7 @@ func (suite *LifecyclePublicTestSuite) TestRunServer() { cancel() cli.RunServer(ctx, mockServer, cleanupFns...) - assert.Equal(suite.T(), tc.wantCleanups, cleanupRan) + tc.validateFunc(cleanupRan) }) } } diff --git a/internal/cli/log_public_test.go b/internal/cli/log_public_test.go index e131112b9..b8b532a20 100644 --- a/internal/cli/log_public_test.go +++ b/internal/cli/log_public_test.go @@ -42,34 +42,46 @@ func (suite *LogPublicTestSuite) TearDownTest() { func (suite *LogPublicTestSuite) TestLogFatal() { tests := []struct { - name string - message string - err error - kvPairs []any - wantInLog []string - wantCode int + name string + message string + err error + kvPairs []any + wantCode int + validateFunc func(string) }{ { - name: "when error is provided logs error", - message: "something failed", - err: fmt.Errorf("connection refused"), - wantInLog: []string{"something failed", "connection refused"}, - wantCode: 1, + name: "when error is provided logs error", + message: "something failed", + err: fmt.Errorf("connection refused"), + wantCode: 1, + validateFunc: func(output string) { + for _, want := range []string{"something failed", "connection refused"} { + assert.Contains(suite.T(), output, want) + } + }, }, { - name: "when error is nil logs without error key", - message: "fatal event", - err: nil, - wantInLog: []string{"fatal event"}, - wantCode: 1, + name: "when error is nil logs without error key", + message: "fatal event", + err: nil, + wantCode: 1, + validateFunc: func(output string) { + for _, want := range []string{"fatal event"} { + assert.Contains(suite.T(), output, want) + } + }, }, { - name: "when extra kv pairs are provided logs them", - message: "startup failed", - err: fmt.Errorf("bad config"), - kvPairs: []any{"host", "localhost"}, - wantInLog: []string{"startup failed", "bad config", "host", "localhost"}, - wantCode: 1, + name: "when extra kv pairs are provided logs them", + message: "startup failed", + err: fmt.Errorf("bad config"), + kvPairs: []any{"host", "localhost"}, + wantCode: 1, + validateFunc: func(output string) { + for _, want := range []string{"startup failed", "bad config", "host", "localhost"} { + assert.Contains(suite.T(), output, want) + } + }, }, } @@ -84,14 +96,13 @@ func (suite *LogPublicTestSuite) TestLogFatal() { cli.LogFatal(logger, tc.message, tc.err, tc.kvPairs...) assert.Equal(suite.T(), tc.wantCode, exitCode) - output := buf.String() - for _, want := range tc.wantInLog { - assert.Contains(suite.T(), output, want) - } + tc.validateFunc(buf.String()) }) } } -func TestLogPublicTestSuite(t *testing.T) { +func TestLogPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LogPublicTestSuite)) } diff --git a/internal/cli/nats_public_test.go b/internal/cli/nats_public_test.go index 5c49c9241..142f46fd2 100644 --- a/internal/cli/nats_public_test.go +++ b/internal/cli/nats_public_test.go @@ -41,7 +41,9 @@ type NATSPublicTestSuite struct { ctrl *gomock.Controller } -func TestNATSPublicTestSuite(t *testing.T) { +func TestNATSPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NATSPublicTestSuite)) } @@ -55,8 +57,9 @@ func (suite *NATSPublicTestSuite) TearDownTest() { func (suite *NATSPublicTestSuite) TestCloseNATSClient() { tests := []struct { - name string - setupFn func() func() + name string + setupFn func() func() + validateFunc func(assert.PanicTestFunc) }{ { name: "when real client with nil NC does not panic", @@ -67,6 +70,9 @@ func (suite *NATSPublicTestSuite) TestCloseNATSClient() { cli.CloseNATSClient(client) } }, + validateFunc: func(closeFn assert.PanicTestFunc) { + assert.NotPanics(suite.T(), closeFn) + }, }, { name: "when real client with non-nil NC closes connection", @@ -79,23 +85,24 @@ func (suite *NATSPublicTestSuite) TestCloseNATSClient() { cli.CloseNATSClient(client) } }, + validateFunc: func(closeFn assert.PanicTestFunc) { + assert.NotPanics(suite.T(), closeFn) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - closeFn := tc.setupFn() - - assert.NotPanics(suite.T(), closeFn) + tc.validateFunc(tc.setupFn()) }) } } func (suite *NATSPublicTestSuite) TestBuildNATSAuthOptions() { tests := []struct { - name string - auth config.NATSAuth - want natsclient.AuthOptions + name string + auth config.NATSAuth + validateFunc func(natsclient.AuthOptions) }{ { name: "when user_pass returns user pass auth", @@ -104,10 +111,12 @@ func (suite *NATSPublicTestSuite) TestBuildNATSAuthOptions() { Username: "osapi", Password: "secret", }, - want: natsclient.AuthOptions{ - AuthType: natsclient.UserPassAuth, - Username: "osapi", - Password: "secret", + validateFunc: func(got natsclient.AuthOptions) { + assert.Equal(suite.T(), natsclient.AuthOptions{ + AuthType: natsclient.UserPassAuth, + Username: "osapi", + Password: "secret", + }, got) }, }, { @@ -116,9 +125,11 @@ func (suite *NATSPublicTestSuite) TestBuildNATSAuthOptions() { Type: "nkey", NKeyFile: "/path/to/nkey", }, - want: natsclient.AuthOptions{ - AuthType: natsclient.NKeyAuth, - NKeyFile: "/path/to/nkey", + validateFunc: func(got natsclient.AuthOptions) { + assert.Equal(suite.T(), natsclient.AuthOptions{ + AuthType: natsclient.NKeyAuth, + NKeyFile: "/path/to/nkey", + }, got) }, }, { @@ -126,15 +137,19 @@ func (suite *NATSPublicTestSuite) TestBuildNATSAuthOptions() { auth: config.NATSAuth{ Type: "none", }, - want: natsclient.AuthOptions{ - AuthType: natsclient.NoAuth, + validateFunc: func(got natsclient.AuthOptions) { + assert.Equal(suite.T(), natsclient.AuthOptions{ + AuthType: natsclient.NoAuth, + }, got) }, }, { name: "when empty type defaults to no auth", auth: config.NATSAuth{}, - want: natsclient.AuthOptions{ - AuthType: natsclient.NoAuth, + validateFunc: func(got natsclient.AuthOptions) { + assert.Equal(suite.T(), natsclient.AuthOptions{ + AuthType: natsclient.NoAuth, + }, got) }, }, } @@ -143,17 +158,17 @@ func (suite *NATSPublicTestSuite) TestBuildNATSAuthOptions() { suite.Run(tc.name, func() { got := cli.BuildNATSAuthOptions(tc.auth) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } func (suite *NATSPublicTestSuite) TestBuildJobKVConfig() { tests := []struct { - name string - namespace string - kvCfg config.NATSKV - validateFn func(jetstream.KeyValueConfig) + name string + namespace string + kvCfg config.NATSKV + validateFunc func(jetstream.KeyValueConfig) }{ { name: "when namespace is set", @@ -166,7 +181,7 @@ func (suite *NATSPublicTestSuite) TestBuildJobKVConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "osapi-job-queue", cfg.Bucket) assert.Equal(suite.T(), 1*time.Hour, cfg.TTL) assert.Equal(suite.T(), int64(104857600), cfg.MaxBytes) @@ -184,7 +199,7 @@ func (suite *NATSPublicTestSuite) TestBuildJobKVConfig() { Storage: "memory", Replicas: 3, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "job-queue", cfg.Bucket) assert.Equal(suite.T(), 30*time.Minute, cfg.TTL) assert.Equal(suite.T(), int64(52428800), cfg.MaxBytes) @@ -202,7 +217,7 @@ func (suite *NATSPublicTestSuite) TestBuildJobKVConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), time.Duration(0), cfg.TTL) }, }, @@ -212,17 +227,17 @@ func (suite *NATSPublicTestSuite) TestBuildJobKVConfig() { suite.Run(tc.name, func() { got := cli.BuildJobKVConfig(tc.namespace, tc.kvCfg) - tc.validateFn(got) + tc.validateFunc(got) }) } } func (suite *NATSPublicTestSuite) TestBuildResponseKVConfig() { tests := []struct { - name string - namespace string - kvCfg config.NATSKV - validateFn func(jetstream.KeyValueConfig) + name string + namespace string + kvCfg config.NATSKV + validateFunc func(jetstream.KeyValueConfig) }{ { name: "when namespace is set", @@ -235,7 +250,7 @@ func (suite *NATSPublicTestSuite) TestBuildResponseKVConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "osapi-job-responses", cfg.Bucket) assert.Equal(suite.T(), 1*time.Hour, cfg.TTL) assert.Equal(suite.T(), int64(104857600), cfg.MaxBytes) @@ -254,7 +269,7 @@ func (suite *NATSPublicTestSuite) TestBuildResponseKVConfig() { Storage: "memory", Replicas: 3, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "job-responses", cfg.Bucket) assert.Equal(suite.T(), 30*time.Minute, cfg.TTL) assert.Equal(suite.T(), int64(52428800), cfg.MaxBytes) @@ -268,17 +283,17 @@ func (suite *NATSPublicTestSuite) TestBuildResponseKVConfig() { suite.Run(tc.name, func() { got := cli.BuildResponseKVConfig(tc.namespace, tc.kvCfg) - tc.validateFn(got) + tc.validateFunc(got) }) } } func (suite *NATSPublicTestSuite) TestBuildRegistryKVConfig() { tests := []struct { - name string - namespace string - registryCfg config.NATSRegistry - validateFn func(jetstream.KeyValueConfig) + name string + namespace string + registryCfg config.NATSRegistry + validateFunc func(jetstream.KeyValueConfig) }{ { name: "when namespace is set", @@ -289,7 +304,7 @@ func (suite *NATSPublicTestSuite) TestBuildRegistryKVConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "osapi-agent-registry", cfg.Bucket) assert.Equal(suite.T(), 30*time.Second, cfg.TTL) assert.Equal(suite.T(), jetstream.FileStorage, cfg.Storage) @@ -305,7 +320,7 @@ func (suite *NATSPublicTestSuite) TestBuildRegistryKVConfig() { Storage: "memory", Replicas: 3, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "agent-registry", cfg.Bucket) assert.Equal(suite.T(), 1*time.Minute, cfg.TTL) assert.Equal(suite.T(), jetstream.MemoryStorage, cfg.Storage) @@ -321,7 +336,7 @@ func (suite *NATSPublicTestSuite) TestBuildRegistryKVConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), time.Duration(0), cfg.TTL) }, }, @@ -331,17 +346,17 @@ func (suite *NATSPublicTestSuite) TestBuildRegistryKVConfig() { suite.Run(tc.name, func() { got := cli.BuildRegistryKVConfig(tc.namespace, tc.registryCfg) - tc.validateFn(got) + tc.validateFunc(got) }) } } func (suite *NATSPublicTestSuite) TestBuildFactsKVConfig() { tests := []struct { - name string - namespace string - factsCfg config.NATSFacts - validateFn func(jetstream.KeyValueConfig) + name string + namespace string + factsCfg config.NATSFacts + validateFunc func(jetstream.KeyValueConfig) }{ { name: "when namespace is set", @@ -352,7 +367,7 @@ func (suite *NATSPublicTestSuite) TestBuildFactsKVConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "osapi-agent-facts", cfg.Bucket) assert.Equal(suite.T(), 1*time.Hour, cfg.TTL) assert.Equal(suite.T(), jetstream.FileStorage, cfg.Storage) @@ -368,7 +383,7 @@ func (suite *NATSPublicTestSuite) TestBuildFactsKVConfig() { Storage: "memory", Replicas: 3, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "agent-facts", cfg.Bucket) assert.Equal(suite.T(), 30*time.Minute, cfg.TTL) assert.Equal(suite.T(), jetstream.MemoryStorage, cfg.Storage) @@ -384,7 +399,7 @@ func (suite *NATSPublicTestSuite) TestBuildFactsKVConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), time.Duration(0), cfg.TTL) }, }, @@ -394,17 +409,17 @@ func (suite *NATSPublicTestSuite) TestBuildFactsKVConfig() { suite.Run(tc.name, func() { got := cli.BuildFactsKVConfig(tc.namespace, tc.factsCfg) - tc.validateFn(got) + tc.validateFunc(got) }) } } func (suite *NATSPublicTestSuite) TestBuildStateKVConfig() { tests := []struct { - name string - namespace string - stateCfg config.NATSState - validateFn func(jetstream.KeyValueConfig) + name string + namespace string + stateCfg config.NATSState + validateFunc func(jetstream.KeyValueConfig) }{ { name: "when namespace is set", @@ -414,7 +429,7 @@ func (suite *NATSPublicTestSuite) TestBuildStateKVConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "osapi-agent-state", cfg.Bucket) assert.Equal(suite.T(), time.Duration(0), cfg.TTL) assert.Equal(suite.T(), jetstream.FileStorage, cfg.Storage) @@ -429,7 +444,7 @@ func (suite *NATSPublicTestSuite) TestBuildStateKVConfig() { Storage: "memory", Replicas: 3, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "agent-state", cfg.Bucket) assert.Equal(suite.T(), jetstream.MemoryStorage, cfg.Storage) assert.Equal(suite.T(), 3, cfg.Replicas) @@ -441,17 +456,17 @@ func (suite *NATSPublicTestSuite) TestBuildStateKVConfig() { suite.Run(tc.name, func() { got := cli.BuildStateKVConfig(tc.namespace, tc.stateCfg) - tc.validateFn(got) + tc.validateFunc(got) }) } } func (suite *NATSPublicTestSuite) TestBuildAuditStreamConfig() { tests := []struct { - name string - namespace string - auditCfg config.NATSAudit - validateFn func(jetstream.StreamConfig) + name string + namespace string + auditCfg config.NATSAudit + validateFunc func(jetstream.StreamConfig) }{ { name: "when namespace is set", @@ -464,7 +479,7 @@ func (suite *NATSPublicTestSuite) TestBuildAuditStreamConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.StreamConfig) { + validateFunc: func(cfg jetstream.StreamConfig) { assert.Equal(suite.T(), "osapi-AUDIT", cfg.Name) assert.Equal(suite.T(), []string{"osapi.audit.>"}, cfg.Subjects) assert.Equal(suite.T(), 720*time.Hour, cfg.MaxAge) @@ -485,7 +500,7 @@ func (suite *NATSPublicTestSuite) TestBuildAuditStreamConfig() { Storage: "memory", Replicas: 3, }, - validateFn: func(cfg jetstream.StreamConfig) { + validateFunc: func(cfg jetstream.StreamConfig) { assert.Equal(suite.T(), "AUDIT", cfg.Name) assert.Equal(suite.T(), []string{"audit.>"}, cfg.Subjects) assert.Equal(suite.T(), 24*time.Hour, cfg.MaxAge) @@ -506,7 +521,7 @@ func (suite *NATSPublicTestSuite) TestBuildAuditStreamConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.StreamConfig) { + validateFunc: func(cfg jetstream.StreamConfig) { assert.Equal(suite.T(), time.Duration(0), cfg.MaxAge) }, }, @@ -516,17 +531,17 @@ func (suite *NATSPublicTestSuite) TestBuildAuditStreamConfig() { suite.Run(tc.name, func() { got := cli.BuildAuditStreamConfig(tc.namespace, tc.auditCfg) - tc.validateFn(got) + tc.validateFunc(got) }) } } func (suite *NATSPublicTestSuite) TestBuildObjectStoreConfig() { tests := []struct { - name string - namespace string - objectsCfg config.NATSObjects - validateFn func(jetstream.ObjectStoreConfig) + name string + namespace string + objectsCfg config.NATSObjects + validateFunc func(jetstream.ObjectStoreConfig) }{ { name: "when namespace is set", @@ -537,7 +552,7 @@ func (suite *NATSPublicTestSuite) TestBuildObjectStoreConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.ObjectStoreConfig) { + validateFunc: func(cfg jetstream.ObjectStoreConfig) { assert.Equal(suite.T(), "osapi-file-objects", cfg.Bucket) assert.Equal(suite.T(), int64(104857600), cfg.MaxBytes) assert.Equal(suite.T(), jetstream.FileStorage, cfg.Storage) @@ -553,7 +568,7 @@ func (suite *NATSPublicTestSuite) TestBuildObjectStoreConfig() { Storage: "memory", Replicas: 3, }, - validateFn: func(cfg jetstream.ObjectStoreConfig) { + validateFunc: func(cfg jetstream.ObjectStoreConfig) { assert.Equal(suite.T(), "file-objects", cfg.Bucket) assert.Equal(suite.T(), int64(52428800), cfg.MaxBytes) assert.Equal(suite.T(), jetstream.MemoryStorage, cfg.Storage) @@ -569,7 +584,7 @@ func (suite *NATSPublicTestSuite) TestBuildObjectStoreConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.ObjectStoreConfig) { + validateFunc: func(cfg jetstream.ObjectStoreConfig) { assert.Equal(suite.T(), "osapi-file-objects", cfg.Bucket) assert.Equal(suite.T(), int64(0), cfg.MaxBytes) }, @@ -580,7 +595,7 @@ func (suite *NATSPublicTestSuite) TestBuildObjectStoreConfig() { suite.Run(tc.name, func() { got := cli.BuildObjectStoreConfig(tc.namespace, tc.objectsCfg) - tc.validateFn(got) + tc.validateFunc(got) }) } } @@ -590,7 +605,7 @@ func (suite *NATSPublicTestSuite) TestBuildEnrollmentKVConfig() { name string namespace string enrollmentCfg config.NATSEnrollment - validateFn func(jetstream.KeyValueConfig) + validateFunc func(jetstream.KeyValueConfig) }{ { name: "when namespace is set", @@ -600,7 +615,7 @@ func (suite *NATSPublicTestSuite) TestBuildEnrollmentKVConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "osapi-agent-enrollment", cfg.Bucket) assert.Equal(suite.T(), time.Duration(0), cfg.TTL) assert.Equal(suite.T(), jetstream.FileStorage, cfg.Storage) @@ -615,7 +630,7 @@ func (suite *NATSPublicTestSuite) TestBuildEnrollmentKVConfig() { Storage: "memory", Replicas: 3, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "agent-enrollment", cfg.Bucket) assert.Equal(suite.T(), jetstream.MemoryStorage, cfg.Storage) assert.Equal(suite.T(), 3, cfg.Replicas) @@ -627,7 +642,7 @@ func (suite *NATSPublicTestSuite) TestBuildEnrollmentKVConfig() { suite.Run(tc.name, func() { got := cli.BuildEnrollmentKVConfig(tc.namespace, tc.enrollmentCfg) - tc.validateFn(got) + tc.validateFunc(got) }) } } @@ -637,7 +652,7 @@ func (suite *NATSPublicTestSuite) TestBuildFileStateKVConfig() { name string namespace string fileStateCfg config.NATSFileState - validateFn func(jetstream.KeyValueConfig) + validateFunc func(jetstream.KeyValueConfig) }{ { name: "when namespace is set", @@ -647,7 +662,7 @@ func (suite *NATSPublicTestSuite) TestBuildFileStateKVConfig() { Storage: "file", Replicas: 1, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "osapi-file-state", cfg.Bucket) assert.Equal(suite.T(), time.Duration(0), cfg.TTL) assert.Equal(suite.T(), jetstream.FileStorage, cfg.Storage) @@ -662,7 +677,7 @@ func (suite *NATSPublicTestSuite) TestBuildFileStateKVConfig() { Storage: "memory", Replicas: 3, }, - validateFn: func(cfg jetstream.KeyValueConfig) { + validateFunc: func(cfg jetstream.KeyValueConfig) { assert.Equal(suite.T(), "file-state", cfg.Bucket) assert.Equal(suite.T(), jetstream.MemoryStorage, cfg.Storage) assert.Equal(suite.T(), 3, cfg.Replicas) @@ -674,7 +689,7 @@ func (suite *NATSPublicTestSuite) TestBuildFileStateKVConfig() { suite.Run(tc.name, func() { got := cli.BuildFileStateKVConfig(tc.namespace, tc.fileStateCfg) - tc.validateFn(got) + tc.validateFunc(got) }) } } diff --git a/internal/cli/raw_output_public_test.go b/internal/cli/raw_output_public_test.go index 88159a081..22d1c7024 100644 --- a/internal/cli/raw_output_public_test.go +++ b/internal/cli/raw_output_public_test.go @@ -34,18 +34,20 @@ type RawOutputPublicTestSuite struct { suite.Suite } -func TestRawOutputPublicTestSuite(t *testing.T) { +func TestRawOutputPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(RawOutputPublicTestSuite)) } func (suite *RawOutputPublicTestSuite) TestPrintRawOutputPlain() { tests := []struct { - name string - results []cli.RawResult - showStdout bool - showStderr bool - wantOut string - wantErr string + name string + results []cli.RawResult + showStdout bool + showStderr bool + wantOut string + validateFunc func(string) }{ { name: "when single host stdout only prefixes with hostname", @@ -55,7 +57,9 @@ func (suite *RawOutputPublicTestSuite) TestPrintRawOutputPlain() { showStdout: true, showStderr: true, wantOut: "[server1] file1\n[server1] file2\n", - wantErr: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, { name: "when single host stderr only prints to stderr", @@ -65,7 +69,9 @@ func (suite *RawOutputPublicTestSuite) TestPrintRawOutputPlain() { showStdout: true, showStderr: true, wantOut: "", - wantErr: "[server1] permission denied\n", + validateFunc: func(got string) { + assert.Equal(suite.T(), "[server1] permission denied\n", got) + }, }, { name: "when single host both streams prints each", @@ -75,7 +81,9 @@ func (suite *RawOutputPublicTestSuite) TestPrintRawOutputPlain() { showStdout: true, showStderr: true, wantOut: "[server1] output\n", - wantErr: "[server1] warning\n", + validateFunc: func(got string) { + assert.Equal(suite.T(), "[server1] warning\n", got) + }, }, { name: "when content has embedded empty lines preserves them", @@ -85,7 +93,9 @@ func (suite *RawOutputPublicTestSuite) TestPrintRawOutputPlain() { showStdout: true, showStderr: true, wantOut: "[server1] line1\n[server1] \n[server1] line3\n", - wantErr: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, { name: "when single host empty output prints nothing", @@ -93,7 +103,9 @@ func (suite *RawOutputPublicTestSuite) TestPrintRawOutputPlain() { showStdout: true, showStderr: true, wantOut: "", - wantErr: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, { name: "when multi host stdout prefixed with hostname", @@ -104,7 +116,9 @@ func (suite *RawOutputPublicTestSuite) TestPrintRawOutputPlain() { showStdout: true, showStderr: false, wantOut: "[web-01] file1\n[web-01] file2\n[web-02] file3\n", - wantErr: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, { name: "when multi host stderr prefixed with hostname", @@ -115,7 +129,9 @@ func (suite *RawOutputPublicTestSuite) TestPrintRawOutputPlain() { showStdout: false, showStderr: true, wantOut: "", - wantErr: "[web-01] err1\n[web-02] err2\n", + validateFunc: func(got string) { + assert.Equal(suite.T(), "[web-01] err1\n[web-02] err2\n", got) + }, }, { name: "when showStdout false suppresses stdout", @@ -125,7 +141,9 @@ func (suite *RawOutputPublicTestSuite) TestPrintRawOutputPlain() { showStdout: false, showStderr: true, wantOut: "", - wantErr: "[server1] warning\n", + validateFunc: func(got string) { + assert.Equal(suite.T(), "[server1] warning\n", got) + }, }, { name: "when showStderr false suppresses stderr", @@ -135,7 +153,9 @@ func (suite *RawOutputPublicTestSuite) TestPrintRawOutputPlain() { showStdout: true, showStderr: false, wantOut: "[server1] output\n", - wantErr: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, { name: "when both false prints nothing", @@ -145,7 +165,9 @@ func (suite *RawOutputPublicTestSuite) TestPrintRawOutputPlain() { showStdout: false, showStderr: false, wantOut: "", - wantErr: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, } @@ -156,7 +178,7 @@ func (suite *RawOutputPublicTestSuite) TestPrintRawOutputPlain() { cli.PrintRawOutputPlain(&stdout, &stderr, tc.results, tc.showStdout, tc.showStderr) assert.Equal(suite.T(), tc.wantOut, stdout.String()) - assert.Equal(suite.T(), tc.wantErr, stderr.String()) + tc.validateFunc(stderr.String()) }) } } @@ -177,14 +199,16 @@ func (suite *RawOutputPublicTestSuite) TestPrintRawOutput() { func (suite *RawOutputPublicTestSuite) TestMaxExitCode() { tests := []struct { - name string - results []cli.RawResult - want int + name string + results []cli.RawResult + validateFunc func(int) }{ { name: "when empty results returns zero", results: []cli.RawResult{}, - want: 0, + validateFunc: func(got int) { + assert.Equal(suite.T(), 0, got) + }, }, { name: "when all zero returns zero", @@ -192,7 +216,9 @@ func (suite *RawOutputPublicTestSuite) TestMaxExitCode() { {Hostname: "s1", ExitCode: 0}, {Hostname: "s2", ExitCode: 0}, }, - want: 0, + validateFunc: func(got int) { + assert.Equal(suite.T(), 0, got) + }, }, { name: "when mixed returns highest", @@ -201,20 +227,24 @@ func (suite *RawOutputPublicTestSuite) TestMaxExitCode() { {Hostname: "s2", ExitCode: 2}, {Hostname: "s3", ExitCode: 1}, }, - want: 2, + validateFunc: func(got int) { + assert.Equal(suite.T(), 2, got) + }, }, { name: "when single non-zero returns it", results: []cli.RawResult{ {Hostname: "s1", ExitCode: 127}, }, - want: 127, + validateFunc: func(got int) { + assert.Equal(suite.T(), 127, got) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - assert.Equal(suite.T(), tc.want, cli.MaxExitCode(tc.results)) + tc.validateFunc(cli.MaxExitCode(tc.results)) }) } } diff --git a/internal/cli/ui_public_test.go b/internal/cli/ui_public_test.go index 695554c07..245222372 100644 --- a/internal/cli/ui_public_test.go +++ b/internal/cli/ui_public_test.go @@ -30,6 +30,8 @@ import ( "testing" "time" + "k8s.io/utils/ptr" + "github.com/google/uuid" "github.com/osapi-io/osapi/pkg/sdk/client" "github.com/stretchr/testify/assert" @@ -42,7 +44,9 @@ type UIPublicTestSuite struct { suite.Suite } -func TestUIPublicTestSuite(t *testing.T) { +func TestUIPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(UIPublicTestSuite)) } @@ -62,28 +66,32 @@ func captureStdout( return string(out) } -func boolPtr(b bool) *bool { return &b } - func (suite *UIPublicTestSuite) TestBoolToSafeString() { tests := []struct { - name string - b *bool - want string + name string + b *bool + validateFunc func(string) }{ { name: "when true returns true", - b: boolPtr(true), - want: "true", + b: ptr.To(true), + validateFunc: func(got string) { + assert.Equal(suite.T(), "true", got) + }, }, { name: "when false returns false", - b: boolPtr(false), - want: "false", + b: ptr.To(false), + validateFunc: func(got string) { + assert.Equal(suite.T(), "false", got) + }, }, { name: "when nil returns empty", b: nil, - want: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, } @@ -91,7 +99,7 @@ func (suite *UIPublicTestSuite) TestBoolToSafeString() { suite.Run(tc.name, func() { got := cli.BoolToSafeString(tc.b) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } @@ -104,14 +112,16 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTable() { results []cli.ResultRow fieldHeaders []string wantHeaders []string - wantRows [][]string + validateFunc func([][]string) }{ { name: "when no results returns hostname and status headers", results: []cli.ResultRow{}, fieldHeaders: nil, wantHeaders: []string{"HOSTNAME", "STATUS"}, - wantRows: [][]string{}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{}, got) + }, }, { name: "when all results succeed shows ok status", @@ -121,9 +131,11 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTable() { }, fieldHeaders: []string{"DATA"}, wantHeaders: []string{"HOSTNAME", "STATUS", "DATA"}, - wantRows: [][]string{ - {"web-01", "ok", "val1"}, - {"web-02", "ok", "val2"}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "ok", "val1"}, + {"web-02", "ok", "val2"}, + }, got) }, }, { @@ -134,9 +146,11 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTable() { }, fieldHeaders: []string{"DATA"}, wantHeaders: []string{"HOSTNAME", "STATUS", "DATA"}, - wantRows: [][]string{ - {"web-01", "ok", "val1"}, - {"web-02", "err", ""}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "ok", "val1"}, + {"web-02", "err", ""}, + }, got) }, }, { @@ -147,9 +161,11 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTable() { }, fieldHeaders: []string{"DATA"}, wantHeaders: []string{"HOSTNAME", "STATUS", "DATA"}, - wantRows: [][]string{ - {"web-01", "ok", "val1"}, - {"web-02", "skip"}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "ok", "val1"}, + {"web-02", "skip"}, + }, got) }, }, { @@ -160,9 +176,11 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTable() { }, fieldHeaders: []string{"DATA"}, wantHeaders: []string{"HOSTNAME", "STATUS", "DATA"}, - wantRows: [][]string{ - {"web-01", "ok", "val1"}, - {"web-02", "skip", "partial"}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "ok", "val1"}, + {"web-02", "skip", "partial"}, + }, got) }, }, { @@ -172,8 +190,10 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTable() { }, fieldHeaders: []string{"DATA"}, wantHeaders: []string{"HOSTNAME", "STATUS", "DATA"}, - wantRows: [][]string{ - {"web-01", "ok", "val1"}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "ok", "val1"}, + }, got) }, }, { @@ -184,22 +204,26 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTable() { }, fieldHeaders: []string{"DATA"}, wantHeaders: []string{"HOSTNAME", "STATUS", "DATA"}, - wantRows: [][]string{ - {"web-01", "err", ""}, - {"web-02", "err", ""}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "err", ""}, + {"web-02", "err", ""}, + }, got) }, }, { name: "when changed is true shows changed status", results: []cli.ResultRow{ - {Hostname: "web-01", Changed: boolPtr(true), Fields: []string{"val1"}}, - {Hostname: "web-02", Changed: boolPtr(false), Fields: []string{"val2"}}, + {Hostname: "web-01", Changed: ptr.To(true), Fields: []string{"val1"}}, + {Hostname: "web-02", Changed: ptr.To(false), Fields: []string{"val2"}}, }, fieldHeaders: []string{"DATA"}, wantHeaders: []string{"HOSTNAME", "STATUS", "DATA"}, - wantRows: [][]string{ - {"web-01", "changed", "val1"}, - {"web-02", "ok", "val2"}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "changed", "val1"}, + {"web-02", "ok", "val2"}, + }, got) }, }, { @@ -208,35 +232,39 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTable() { { Hostname: "web-01", Status: "ok", - Changed: boolPtr(true), + Changed: ptr.To(true), Fields: []string{"val1"}, }, { Hostname: "web-02", Status: "failed", - Changed: boolPtr(false), + Changed: ptr.To(false), Error: &errMsg, Fields: []string{""}, }, }, fieldHeaders: []string{"DATA"}, wantHeaders: []string{"HOSTNAME", "STATUS", "DATA"}, - wantRows: [][]string{ - {"web-01", "changed", "val1"}, - {"web-02", "err", ""}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "changed", "val1"}, + {"web-02", "err", ""}, + }, got) }, }, { name: "when no field headers shows only hostname and status", results: []cli.ResultRow{ - {Hostname: "web-01", Changed: boolPtr(true)}, + {Hostname: "web-01", Changed: ptr.To(true)}, {Hostname: "web-02"}, }, fieldHeaders: nil, wantHeaders: []string{"HOSTNAME", "STATUS"}, - wantRows: [][]string{ - {"web-01", "changed"}, - {"web-02", "ok"}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "changed"}, + {"web-02", "ok"}, + }, got) }, }, } @@ -246,43 +274,51 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTable() { tr := cli.BuildBroadcastTable(tc.results, tc.fieldHeaders) assert.Equal(suite.T(), tc.wantHeaders, tr.Headers) - assert.Equal(suite.T(), tc.wantRows, tr.Rows) + tc.validateFunc(tr.Rows) }) } } func (suite *UIPublicTestSuite) TestFormatLabels() { tests := []struct { - name string - labels map[string]string - want string + name string + labels map[string]string + validateFunc func(string) }{ { name: "when nil returns empty", labels: nil, - want: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, { name: "when empty map returns empty", labels: map[string]string{}, - want: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, { name: "when single label formats correctly", labels: map[string]string{"group": "web"}, - want: "group:web", + validateFunc: func(got string) { + assert.Equal(suite.T(), "group:web", got) + }, }, { name: "when multiple labels sorts by key", labels: map[string]string{"group": "web", "env": "prod", "az": "us-east"}, - want: "az:us-east, env:prod, group:web", + validateFunc: func(got string) { + assert.Equal(suite.T(), "az:us-east, env:prod, group:web", got) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { result := cli.FormatLabels(tc.labels) - assert.Equal(suite.T(), tc.want, result) + tc.validateFunc(result) }) } } @@ -295,14 +331,16 @@ func (suite *UIPublicTestSuite) TestBuildMutationTable() { results []cli.ResultRow fieldHeaders []string wantHeaders []string - wantRows [][]string + validateFunc func([][]string) }{ { name: "when no results returns hostname and status headers", results: []cli.ResultRow{}, fieldHeaders: nil, wantHeaders: []string{"HOSTNAME", "STATUS"}, - wantRows: [][]string{}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{}, got) + }, }, { name: "when all succeed shows ok status", @@ -312,9 +350,11 @@ func (suite *UIPublicTestSuite) TestBuildMutationTable() { }, fieldHeaders: nil, wantHeaders: []string{"HOSTNAME", "STATUS"}, - wantRows: [][]string{ - {"web-01", "ok"}, - {"web-02", "ok"}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "ok"}, + {"web-02", "ok"}, + }, got) }, }, { @@ -325,9 +365,11 @@ func (suite *UIPublicTestSuite) TestBuildMutationTable() { }, fieldHeaders: nil, wantHeaders: []string{"HOSTNAME", "STATUS"}, - wantRows: [][]string{ - {"web-01", "ok"}, - {"web-02", "err"}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "ok"}, + {"web-02", "err"}, + }, got) }, }, { @@ -337,47 +379,55 @@ func (suite *UIPublicTestSuite) TestBuildMutationTable() { }, fieldHeaders: []string{"DETAIL"}, wantHeaders: []string{"HOSTNAME", "STATUS", "DETAIL"}, - wantRows: [][]string{ - {"web-01", "ok", "extra"}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "ok", "extra"}, + }, got) }, }, { name: "when changed is true shows changed status", results: []cli.ResultRow{ - {Hostname: "web-01", Status: "ok", Changed: boolPtr(true)}, - {Hostname: "web-02", Status: "ok", Changed: boolPtr(true)}, + {Hostname: "web-01", Status: "ok", Changed: ptr.To(true)}, + {Hostname: "web-02", Status: "ok", Changed: ptr.To(true)}, }, fieldHeaders: nil, wantHeaders: []string{"HOSTNAME", "STATUS"}, - wantRows: [][]string{ - {"web-01", "changed"}, - {"web-02", "changed"}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "changed"}, + {"web-02", "changed"}, + }, got) }, }, { name: "when changed is false shows ok status", results: []cli.ResultRow{ - {Hostname: "web-01", Status: "ok", Changed: boolPtr(false)}, - {Hostname: "web-02", Status: "ok", Changed: boolPtr(false)}, + {Hostname: "web-01", Status: "ok", Changed: ptr.To(false)}, + {Hostname: "web-02", Status: "ok", Changed: ptr.To(false)}, }, fieldHeaders: nil, wantHeaders: []string{"HOSTNAME", "STATUS"}, - wantRows: [][]string{ - {"web-01", "ok"}, - {"web-02", "ok"}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "ok"}, + {"web-02", "ok"}, + }, got) }, }, { name: "when field headers provided includes them after status", results: []cli.ResultRow{ - {Hostname: "web-01", Changed: boolPtr(true), Fields: []string{"val1"}}, + {Hostname: "web-01", Changed: ptr.To(true), Fields: []string{"val1"}}, {Hostname: "web-02", Fields: []string{"val2"}}, }, fieldHeaders: []string{"DATA"}, wantHeaders: []string{"HOSTNAME", "STATUS", "DATA"}, - wantRows: [][]string{ - {"web-01", "changed", "val1"}, - {"web-02", "ok", "val2"}, + validateFunc: func(got [][]string) { + assert.Equal(suite.T(), [][]string{ + {"web-01", "changed", "val1"}, + {"web-02", "ok", "val2"}, + }, got) }, }, } @@ -387,7 +437,7 @@ func (suite *UIPublicTestSuite) TestBuildMutationTable() { tr := cli.BuildMutationTable(tc.results, tc.fieldHeaders) assert.Equal(suite.T(), tc.wantHeaders, tr.Headers) - assert.Equal(suite.T(), tc.wantRows, tr.Rows) + tc.validateFunc(tr.Rows) }) } } @@ -397,12 +447,12 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTableResult() { skipMsg := "unsupported" tests := []struct { - name string - results []cli.ResultRow - fieldHdrs []string - wantHeaders []string - wantRows [][]string - wantErrors []cli.ErrorEntry + name string + results []cli.ResultRow + fieldHdrs []string + wantHeaders []string + wantRows [][]string + validateFunc func([]cli.ErrorEntry) }{ { name: "when errors exist they appear in errors field", @@ -416,8 +466,10 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTableResult() { {"web-01", "ok", "val1"}, {"web-02", "err", ""}, }, - wantErrors: []cli.ErrorEntry{ - {Hostname: "web-02", Message: "connection refused", Status: "err"}, + validateFunc: func(got []cli.ErrorEntry) { + assert.Equal(suite.T(), []cli.ErrorEntry{ + {Hostname: "web-02", Message: "connection refused", Status: "err"}, + }, got) }, }, { @@ -432,7 +484,9 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTableResult() { {"web-01", "ok", "val1"}, {"web-02", "ok", "val2"}, }, - wantErrors: nil, + validateFunc: func(got []cli.ErrorEntry) { + assert.Equal(suite.T(), []cli.ErrorEntry(nil), got) + }, }, { name: "when skipped host without fields appears in errors", @@ -446,8 +500,10 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTableResult() { {"web-01", "ok", "val1"}, {"web-02", "skip"}, }, - wantErrors: []cli.ErrorEntry{ - {Hostname: "web-02", Message: "unsupported", Status: "skip"}, + validateFunc: func(got []cli.ErrorEntry) { + assert.Equal(suite.T(), []cli.ErrorEntry{ + {Hostname: "web-02", Message: "unsupported", Status: "skip"}, + }, got) }, }, { @@ -464,9 +520,11 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTableResult() { {"web-02", "err"}, {"web-03", "ok", "ok"}, }, - wantErrors: []cli.ErrorEntry{ - {Hostname: "web-01", Message: "connection refused", Status: "err"}, - {Hostname: "web-02", Message: "unsupported", Status: "err"}, + validateFunc: func(got []cli.ErrorEntry) { + assert.Equal(suite.T(), []cli.ErrorEntry{ + {Hostname: "web-01", Message: "connection refused", Status: "err"}, + {Hostname: "web-02", Message: "unsupported", Status: "err"}, + }, got) }, }, } @@ -477,7 +535,7 @@ func (suite *UIPublicTestSuite) TestBuildBroadcastTableResult() { assert.Equal(suite.T(), tc.wantHeaders, result.Headers) assert.Equal(suite.T(), tc.wantRows, result.Rows) - assert.Equal(suite.T(), tc.wantErrors, result.Errors) + tc.validateFunc(result.Errors) }) } } @@ -486,17 +544,17 @@ func (suite *UIPublicTestSuite) TestBuildMutationTableResult() { errMsg := "permission denied" tests := []struct { - name string - results []cli.ResultRow - fieldHdrs []string - wantHeaders []string - wantRows [][]string - wantErrors []cli.ErrorEntry + name string + results []cli.ResultRow + fieldHdrs []string + wantHeaders []string + wantRows [][]string + validateFunc func([]cli.ErrorEntry) }{ { name: "when mutation errors exist they appear in errors field", results: []cli.ResultRow{ - {Hostname: "web-01", Changed: boolPtr(true)}, + {Hostname: "web-01", Changed: ptr.To(true)}, {Hostname: "web-02", Error: &errMsg}, }, fieldHdrs: nil, @@ -505,15 +563,17 @@ func (suite *UIPublicTestSuite) TestBuildMutationTableResult() { {"web-01", "changed"}, {"web-02", "err"}, }, - wantErrors: []cli.ErrorEntry{ - {Hostname: "web-02", Message: "permission denied", Status: "err"}, + validateFunc: func(got []cli.ErrorEntry) { + assert.Equal(suite.T(), []cli.ErrorEntry{ + {Hostname: "web-02", Message: "permission denied", Status: "err"}, + }, got) }, }, { name: "when no mutation errors the errors field is nil", results: []cli.ResultRow{ - {Hostname: "web-01", Changed: boolPtr(true)}, - {Hostname: "web-02", Changed: boolPtr(false)}, + {Hostname: "web-01", Changed: ptr.To(true)}, + {Hostname: "web-02", Changed: ptr.To(false)}, }, fieldHdrs: nil, wantHeaders: []string{"HOSTNAME", "STATUS"}, @@ -521,7 +581,9 @@ func (suite *UIPublicTestSuite) TestBuildMutationTableResult() { {"web-01", "changed"}, {"web-02", "ok"}, }, - wantErrors: nil, + validateFunc: func(got []cli.ErrorEntry) { + assert.Equal(suite.T(), []cli.ErrorEntry(nil), got) + }, }, } @@ -531,31 +593,37 @@ func (suite *UIPublicTestSuite) TestBuildMutationTableResult() { assert.Equal(suite.T(), tc.wantHeaders, result.Headers) assert.Equal(suite.T(), tc.wantRows, result.Rows) - assert.Equal(suite.T(), tc.wantErrors, result.Errors) + tc.validateFunc(result.Errors) }) } } func (suite *UIPublicTestSuite) TestFormatList() { tests := []struct { - name string - list []string - want string + name string + list []string + validateFunc func(string) }{ { name: "when empty returns None", list: []string{}, - want: "None", + validateFunc: func(got string) { + assert.Equal(suite.T(), "None", got) + }, }, { name: "when single item returns it", list: []string{"alpha"}, - want: "alpha", + validateFunc: func(got string) { + assert.Equal(suite.T(), "alpha", got) + }, }, { name: "when multiple items joins with comma", list: []string{"alpha", "beta", "gamma"}, - want: "alpha, beta, gamma", + validateFunc: func(got string) { + assert.Equal(suite.T(), "alpha, beta, gamma", got) + }, }, } @@ -563,46 +631,54 @@ func (suite *UIPublicTestSuite) TestFormatList() { suite.Run(tc.name, func() { got := cli.FormatList(tc.list) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } func (suite *UIPublicTestSuite) TestCalculateColumnWidths() { tests := []struct { - name string - headers []string - rows [][]string - minPadding int - want []int + name string + headers []string + rows [][]string + minPadding int + validateFunc func([]int) }{ { name: "when empty headers returns empty", headers: []string{}, rows: nil, minPadding: 1, - want: []int{}, + validateFunc: func(got []int) { + assert.Equal(suite.T(), []int{}, got) + }, }, { name: "when headers wider than rows uses header width", headers: []string{"HOSTNAME", "STATUS"}, rows: [][]string{{"a", "b"}}, minPadding: 1, - want: []int{10, 8}, + validateFunc: func(got []int) { + assert.Equal(suite.T(), []int{10, 8}, got) + }, }, { name: "when rows wider than headers uses row width", headers: []string{"A", "B"}, rows: [][]string{{"longvalue", "anotherlongvalue"}}, minPadding: 1, - want: []int{11, 18}, + validateFunc: func(got []int) { + assert.Equal(suite.T(), []int{11, 18}, got) + }, }, { name: "when multi-line content uses longest line width", headers: []string{"DATA"}, rows: [][]string{{"short\nvery long line here"}}, minPadding: 0, - want: []int{19}, + validateFunc: func(got []int) { + assert.Equal(suite.T(), []int{19}, got) + }, }, } @@ -610,31 +686,37 @@ func (suite *UIPublicTestSuite) TestCalculateColumnWidths() { suite.Run(tc.name, func() { got := cli.CalculateColumnWidths(tc.headers, tc.rows, tc.minPadding) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } func (suite *UIPublicTestSuite) TestGetMaxLineWidth() { tests := []struct { - name string - text string - want int + name string + text string + validateFunc func(int) }{ { name: "when single line returns its length", text: "hello", - want: 5, + validateFunc: func(got int) { + assert.Equal(suite.T(), 5, got) + }, }, { name: "when multi-line returns longest", text: "short\na much longer line\nmed", - want: 18, + validateFunc: func(got int) { + assert.Equal(suite.T(), 18, got) + }, }, { name: "when empty returns zero", text: "", - want: 0, + validateFunc: func(got int) { + assert.Equal(suite.T(), 0, got) + }, }, } @@ -642,7 +724,7 @@ func (suite *UIPublicTestSuite) TestGetMaxLineWidth() { suite.Run(tc.name, func() { got := cli.GetMaxLineWidth(tc.text) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } @@ -651,19 +733,23 @@ func (suite *UIPublicTestSuite) TestSafeString() { str := "hello" tests := []struct { - name string - s *string - want string + name string + s *string + validateFunc func(string) }{ { name: "when non-nil returns value", s: &str, - want: "hello", + validateFunc: func(got string) { + assert.Equal(suite.T(), "hello", got) + }, }, { name: "when nil returns empty", s: nil, - want: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, } @@ -671,7 +757,7 @@ func (suite *UIPublicTestSuite) TestSafeString() { suite.Run(tc.name, func() { got := cli.SafeString(tc.s) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } @@ -680,19 +766,23 @@ func (suite *UIPublicTestSuite) TestSafeUUID() { id := uuid.MustParse("550e8400-e29b-41d4-a716-446655440000") tests := []struct { - name string - u *uuid.UUID - want string + name string + u *uuid.UUID + validateFunc func(string) }{ { name: "when non-nil returns string", u: &id, - want: "550e8400-e29b-41d4-a716-446655440000", + validateFunc: func(got string) { + assert.Equal(suite.T(), "550e8400-e29b-41d4-a716-446655440000", got) + }, }, { name: "when nil returns empty", u: nil, - want: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, } @@ -700,7 +790,7 @@ func (suite *UIPublicTestSuite) TestSafeUUID() { suite.Run(tc.name, func() { got := cli.SafeUUID(tc.u) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } @@ -709,19 +799,23 @@ func (suite *UIPublicTestSuite) TestFloat64ToSafeString() { val := 3.14 tests := []struct { - name string - f *float64 - want string + name string + f *float64 + validateFunc func(string) }{ { name: "when non-nil returns formatted float", f: &val, - want: "3.140000", + validateFunc: func(got string) { + assert.Equal(suite.T(), "3.140000", got) + }, }, { name: "when nil returns N/A", f: nil, - want: "N/A", + validateFunc: func(got string) { + assert.Equal(suite.T(), "N/A", got) + }, }, } @@ -729,7 +823,7 @@ func (suite *UIPublicTestSuite) TestFloat64ToSafeString() { suite.Run(tc.name, func() { got := cli.Float64ToSafeString(tc.f) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } @@ -738,19 +832,23 @@ func (suite *UIPublicTestSuite) TestIntToSafeString() { val := 42 tests := []struct { - name string - i *int - want string + name string + i *int + validateFunc func(string) }{ { name: "when non-nil returns formatted int", i: &val, - want: "42", + validateFunc: func(got string) { + assert.Equal(suite.T(), "42", got) + }, }, { name: "when nil returns N/A", i: nil, - want: "N/A", + validateFunc: func(got string) { + assert.Equal(suite.T(), "N/A", got) + }, }, } @@ -758,49 +856,64 @@ func (suite *UIPublicTestSuite) TestIntToSafeString() { suite.Run(tc.name, func() { got := cli.IntToSafeString(tc.i) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } func (suite *UIPublicTestSuite) TestHandleError() { tests := []struct { - name string - err error - wantInLog string + name string + err error + validateFunc func(string, int) }{ { name: "when auth error logs api error with status code", err: &client.AuthError{ APIError: client.APIError{StatusCode: 403, Message: "insufficient permissions"}, }, - wantInLog: "insufficient permissions", + validateFunc: func(log string, exitCode int) { + assert.Contains(suite.T(), log, "insufficient permissions") + assert.Equal(suite.T(), 1, exitCode) + }, }, { name: "when not found error logs api error with status code", err: &client.NotFoundError{ APIError: client.APIError{StatusCode: 404, Message: "job not found"}, }, - wantInLog: "job not found", + validateFunc: func(log string, exitCode int) { + assert.Contains(suite.T(), log, "job not found") + assert.Equal(suite.T(), 1, exitCode) + }, }, { name: "when validation error logs api error with status code", err: &client.ValidationError{ APIError: client.APIError{StatusCode: 400, Message: "invalid input"}, }, - wantInLog: "invalid input", + validateFunc: func(log string, exitCode int) { + assert.Contains(suite.T(), log, "invalid input") + assert.Equal(suite.T(), 1, exitCode) + }, }, { name: "when server error logs api error with status code", err: &client.ServerError{ APIError: client.APIError{StatusCode: 500, Message: "internal server error"}, }, - wantInLog: "internal server error", + validateFunc: func(log string, exitCode int) { + assert.Contains(suite.T(), log, "internal server error") + assert.Equal(suite.T(), 1, exitCode) + }, }, { - name: "when generic error logs error message", - err: fmt.Errorf("connection refused"), - wantInLog: "connection refused", + name: "when generic error logs error message", + err: fmt.Errorf("connection refused"), + validateFunc: func(log string, exitCode int) { + assert.Contains(suite.T(), log, "connection refused") + assert.Equal(suite.T(), 1, exitCode) + }, }, } @@ -816,60 +929,61 @@ func (suite *UIPublicTestSuite) TestHandleError() { cli.HandleError(tc.err, logger) - assert.Contains(suite.T(), buf.String(), tc.wantInLog) - assert.Equal(suite.T(), 1, exitCode) + tc.validateFunc(buf.String(), exitCode) }) } } func (suite *UIPublicTestSuite) TestPrintKV() { tests := []struct { - name string - pairs []string - wantOutput bool + name string + pairs []string + validateFunc func(string) }{ { - name: "when valid pairs prints output", - pairs: []string{"Key", "Value"}, - wantOutput: true, + name: "when valid pairs prints output", + pairs: []string{"Key", "Value"}, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + }, }, { - name: "when multiple pairs prints all", - pairs: []string{"Name", "test", "Status", "ok"}, - wantOutput: true, + name: "when multiple pairs prints all", + pairs: []string{"Name", "test", "Status", "ok"}, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + }, }, { - name: "when odd number of pairs prints nothing", - pairs: []string{"Key"}, - wantOutput: false, + name: "when odd number of pairs prints nothing", + pairs: []string{"Key"}, + validateFunc: func(output string) { + assert.Empty(suite.T(), output) + }, }, { - name: "when empty prints nothing", - pairs: []string{}, - wantOutput: false, + name: "when empty prints nothing", + pairs: []string{}, + validateFunc: func(output string) { + assert.Empty(suite.T(), output) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - output := captureStdout(func() { + tc.validateFunc(captureStdout(func() { cli.PrintKV(tc.pairs...) - }) - - if tc.wantOutput { - assert.NotEmpty(suite.T(), output) - } else { - assert.Empty(suite.T(), output) - } + })) }) } } func (suite *UIPublicTestSuite) TestPrintCompactTable() { tests := []struct { - name string - sections []cli.Section - wantHeaders []string + name string + sections []cli.Section + validateFunc func(string) }{ { name: "when section with title renders table", @@ -880,7 +994,12 @@ func (suite *UIPublicTestSuite) TestPrintCompactTable() { Rows: [][]string{{"a", "b"}}, }, }, - wantHeaders: []string{"COL1", "COL2"}, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + for _, h := range []string{"COL1", "COL2"} { + assert.Contains(suite.T(), output, h) + } + }, }, { name: "when section without title renders table", @@ -890,7 +1009,12 @@ func (suite *UIPublicTestSuite) TestPrintCompactTable() { Rows: [][]string{{"a"}}, }, }, - wantHeaders: []string{"COL1"}, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + for _, h := range []string{"COL1"} { + assert.Contains(suite.T(), output, h) + } + }, }, { name: "when wide data aligns columns", @@ -907,7 +1031,12 @@ func (suite *UIPublicTestSuite) TestPrintCompactTable() { }}, }, }, - wantHeaders: []string{"A", "B", "C", "D", "E"}, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + for _, h := range []string{"A", "B", "C", "D", "E"} { + assert.Contains(suite.T(), output, h) + } + }, }, { name: "when many columns renders all headers", @@ -923,7 +1052,12 @@ func (suite *UIPublicTestSuite) TestPrintCompactTable() { }}, }, }, - wantHeaders: []string{"X", "Y", "Z", "LONG-HEADER-1", "LONG-HEADER-2"}, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + for _, h := range []string{"X", "Y", "Z", "LONG-HEADER-1", "LONG-HEADER-2"} { + assert.Contains(suite.T(), output, h) + } + }, }, { name: "when multiple rows alternates colors", @@ -937,7 +1071,12 @@ func (suite *UIPublicTestSuite) TestPrintCompactTable() { }, }, }, - wantHeaders: []string{"NAME", "VALUE"}, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + for _, h := range []string{"NAME", "VALUE"} { + assert.Contains(suite.T(), output, h) + } + }, }, { name: "when column exceeds max width truncates to cap", @@ -950,7 +1089,12 @@ func (suite *UIPublicTestSuite) TestPrintCompactTable() { }}, }, }, - wantHeaders: []string{"A", "B"}, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + for _, h := range []string{"A", "B"} { + assert.Contains(suite.T(), output, h) + } + }, }, { name: "when cell exceeds column width shows ellipsis", @@ -962,59 +1106,71 @@ func (suite *UIPublicTestSuite) TestPrintCompactTable() { }, }, }, - wantHeaders: []string{"A"}, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + for _, h := range []string{"A"} { + assert.Contains(suite.T(), output, h) + } + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - output := captureStdout(func() { + tc.validateFunc(captureStdout(func() { cli.PrintCompactTable(tc.sections) - }) - - assert.NotEmpty(suite.T(), output) - for _, h := range tc.wantHeaders { - assert.Contains(suite.T(), output, h) - } + })) }) } } func (suite *UIPublicTestSuite) TestFormatAge() { tests := []struct { - name string - d time.Duration - want string + name string + d time.Duration + validateFunc func(string) }{ { name: "when zero returns empty", d: 0, - want: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, { name: "when negative returns empty", d: -1 * time.Hour, - want: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, { name: "when days and hours formats as days", d: 3*24*time.Hour + 4*time.Hour, - want: "3d 4h", + validateFunc: func(got string) { + assert.Equal(suite.T(), "3d 4h", got) + }, }, { name: "when hours and minutes formats as hours", d: 12*time.Hour + 30*time.Minute, - want: "12h 30m", + validateFunc: func(got string) { + assert.Equal(suite.T(), "12h 30m", got) + }, }, { name: "when only minutes formats as minutes", d: 45 * time.Minute, - want: "45m", + validateFunc: func(got string) { + assert.Equal(suite.T(), "45m", got) + }, }, { name: "when only seconds formats as seconds", d: 30 * time.Second, - want: "30s", + validateFunc: func(got string) { + assert.Equal(suite.T(), "30s", got) + }, }, } @@ -1022,36 +1178,44 @@ func (suite *UIPublicTestSuite) TestFormatAge() { suite.Run(tc.name, func() { got := cli.FormatAge(tc.d) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } func (suite *UIPublicTestSuite) TestFormatBytes() { tests := []struct { - name string - b int - want string + name string + b int + validateFunc func(string) }{ { name: "when bytes returns bytes", b: 512, - want: "512 B", + validateFunc: func(got string) { + assert.Equal(suite.T(), "512 B", got) + }, }, { name: "when kilobytes returns KB", b: 5 * 1024, - want: "5.0 KB", + validateFunc: func(got string) { + assert.Equal(suite.T(), "5.0 KB", got) + }, }, { name: "when megabytes returns MB", b: 3 * 1024 * 1024, - want: "3.0 MB", + validateFunc: func(got string) { + assert.Equal(suite.T(), "3.0 MB", got) + }, }, { name: "when gigabytes returns GB", b: 2 * 1024 * 1024 * 1024, - want: "2.0 GB", + validateFunc: func(got string) { + assert.Equal(suite.T(), "2.0 GB", got) + }, }, } @@ -1059,21 +1223,25 @@ func (suite *UIPublicTestSuite) TestFormatBytes() { suite.Run(tc.name, func() { got := cli.FormatBytes(tc.b) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } func (suite *UIPublicTestSuite) TestDisplayJobDetail() { tests := []struct { - name string - resp *client.JobDetail + name string + resp *client.JobDetail + validateFunc func(string) }{ { name: "when minimal response displays job info", resp: &client.JobDetail{ Status: "completed", }, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + }, }, { name: "when full response displays all sections", @@ -1107,6 +1275,9 @@ func (suite *UIPublicTestSuite) TestDisplayJobDetail() { }, }, }, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + }, }, { name: "when agent states with multiple agents shows summary", @@ -1118,6 +1289,9 @@ func (suite *UIPublicTestSuite) TestDisplayJobDetail() { "web-03": {Status: "started", Duration: "1s"}, }, }, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + }, }, { name: "when response has nil data shows no data placeholder", @@ -1130,6 +1304,9 @@ func (suite *UIPublicTestSuite) TestDisplayJobDetail() { }, }, }, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + }, }, { name: "when response has error shows error message", @@ -1142,6 +1319,9 @@ func (suite *UIPublicTestSuite) TestDisplayJobDetail() { }, }, }, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + }, }, { name: "when timeline has error shows error message", @@ -1155,6 +1335,9 @@ func (suite *UIPublicTestSuite) TestDisplayJobDetail() { }, }, }, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + }, }, { name: "when agent states contain skipped status", @@ -1166,6 +1349,9 @@ func (suite *UIPublicTestSuite) TestDisplayJobDetail() { "web-03": {Status: "completed", Duration: "2s"}, }, }, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + }, }, { name: "when multiple agents skipped shows skipped in summary", @@ -1177,38 +1363,75 @@ func (suite *UIPublicTestSuite) TestDisplayJobDetail() { "web-03": {Status: "completed", Duration: "1s"}, }, }, + validateFunc: func(output string) { + assert.NotEmpty(suite.T(), output) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - output := captureStdout(func() { + tc.validateFunc(captureStdout(func() { cli.DisplayJobDetail(tc.resp) - }) - - assert.NotEmpty(suite.T(), output) + })) }) } } func (suite *UIPublicTestSuite) TestStatusWeight() { tests := []struct { - name string - status string - want int + name string + status string + validateFunc func(int) }{ - {name: "when ok returns 0", status: "ok", want: 0}, - {name: "when changed returns 1", status: "changed", want: 1}, - {name: "when skip returns 2", status: "skip", want: 2}, - {name: "when err returns 3", status: "err", want: 3}, - {name: "when unknown returns 0", status: "unknown", want: 0}, - {name: "when empty returns 0", status: "", want: 0}, + { + name: "when ok returns 0", + status: "ok", + validateFunc: func(got int) { + assert.Equal(suite.T(), 0, got) + }, + }, + { + name: "when changed returns 1", + status: "changed", + validateFunc: func(got int) { + assert.Equal(suite.T(), 1, got) + }, + }, + { + name: "when skip returns 2", + status: "skip", + validateFunc: func(got int) { + assert.Equal(suite.T(), 2, got) + }, + }, + { + name: "when err returns 3", + status: "err", + validateFunc: func(got int) { + assert.Equal(suite.T(), 3, got) + }, + }, + { + name: "when unknown returns 0", + status: "unknown", + validateFunc: func(got int) { + assert.Equal(suite.T(), 0, got) + }, + }, + { + name: "when empty returns 0", + status: "", + validateFunc: func(got int) { + assert.Equal(suite.T(), 0, got) + }, + }, } for _, tc := range tests { suite.Run(tc.name, func() { got := cli.ExportStatusWeight(tc.status) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } @@ -1217,46 +1440,58 @@ func (suite *UIPublicTestSuite) TestResolveStatus() { errMsg := "failed" tests := []struct { - name string - row cli.ResultRow - want string + name string + row cli.ResultRow + validateFunc func(string) }{ { name: "when no error and no change returns ok", row: cli.ResultRow{Hostname: "h1"}, - want: "ok", + validateFunc: func(got string) { + assert.Equal(suite.T(), "ok", got) + }, }, { name: "when changed true returns changed", - row: cli.ResultRow{Hostname: "h1", Changed: boolPtr(true)}, - want: "changed", + row: cli.ResultRow{Hostname: "h1", Changed: ptr.To(true)}, + validateFunc: func(got string) { + assert.Equal(suite.T(), "changed", got) + }, }, { name: "when changed false returns ok", - row: cli.ResultRow{Hostname: "h1", Changed: boolPtr(false)}, - want: "ok", + row: cli.ResultRow{Hostname: "h1", Changed: ptr.To(false)}, + validateFunc: func(got string) { + assert.Equal(suite.T(), "ok", got) + }, }, { name: "when error returns err", row: cli.ResultRow{Hostname: "h1", Error: &errMsg}, - want: "err", + validateFunc: func(got string) { + assert.Equal(suite.T(), "err", got) + }, }, { name: "when status skipped returns skip even with error", row: cli.ResultRow{Hostname: "h1", Status: "skipped", Error: &errMsg}, - want: "skip", + validateFunc: func(got string) { + assert.Equal(suite.T(), "skip", got) + }, }, { name: "when status skip returns skip", row: cli.ResultRow{Hostname: "h1", Status: "skip"}, - want: "skip", + validateFunc: func(got string) { + assert.Equal(suite.T(), "skip", got) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { got := cli.ExportResolveStatus(tc.row) - assert.Equal(suite.T(), tc.want, got) + tc.validateFunc(got) }) } } diff --git a/internal/cli/validate_public_test.go b/internal/cli/validate_public_test.go index 929514c53..7f2084483 100644 --- a/internal/cli/validate_public_test.go +++ b/internal/cli/validate_public_test.go @@ -38,7 +38,9 @@ type ValidatePublicTestSuite struct { suite.Suite } -func TestValidatePublicTestSuite(t *testing.T) { +func TestValidatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ValidatePublicTestSuite)) } @@ -58,17 +60,19 @@ func (suite *ValidateDistributionPublicTestSuite) TearDownTest() { func (suite *ValidateDistributionPublicTestSuite) TestValidateDistribution() { tests := []struct { - name string - ignoreLinux bool - hostInfoFn func() (*host.InfoStat, error) - wantExited bool + name string + ignoreLinux bool + hostInfoFn func() (*host.InfoStat, error) + validateFunc func(bool) }{ { name: "when host info fails calls LogFatal", hostInfoFn: func() (*host.InfoStat, error) { return nil, fmt.Errorf("host info failed") }, - wantExited: true, + validateFunc: func(got bool) { + assert.Equal(suite.T(), true, got) + }, }, { name: "when IGNORE_LINUX is set returns early", @@ -79,7 +83,9 @@ func (suite *ValidateDistributionPublicTestSuite) TestValidateDistribution() { PlatformVersion: "14.0", }, nil }, - wantExited: false, + validateFunc: func(got bool) { + assert.Equal(suite.T(), false, got) + }, }, { name: "when supported version does not exit", @@ -89,7 +95,9 @@ func (suite *ValidateDistributionPublicTestSuite) TestValidateDistribution() { PlatformVersion: "24.04", }, nil }, - wantExited: false, + validateFunc: func(got bool) { + assert.Equal(suite.T(), false, got) + }, }, { name: "when unsupported version calls LogFatal", @@ -99,7 +107,9 @@ func (suite *ValidateDistributionPublicTestSuite) TestValidateDistribution() { PlatformVersion: "8", }, nil }, - wantExited: true, + validateFunc: func(got bool) { + assert.Equal(suite.T(), true, got) + }, }, } @@ -132,106 +142,132 @@ func (suite *ValidateDistributionPublicTestSuite) TestValidateDistribution() { cli.ValidateDistribution(logger) }() - assert.Equal(suite.T(), tc.wantExited, exited) + tc.validateFunc(exited) }) } } -func TestValidateDistributionPublicTestSuite(t *testing.T) { +func TestValidateDistributionPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ValidateDistributionPublicTestSuite)) } func (suite *ValidatePublicTestSuite) TestIsOSFamilySupported() { tests := []struct { - name string - distro string - version string - wantFamily string - wantOK bool + name string + distro string + version string + wantFamily string + validateFunc func(bool) }{ { name: "when darwin is supported with any version", distro: "darwin", version: "14.0", wantFamily: "Darwin", - wantOK: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when debian 12 is supported", distro: "debian", version: "12", wantFamily: "Debian", - wantOK: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when debian 12 point release is supported", distro: "debian", version: "12.13", wantFamily: "Debian", - wantOK: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when debian 13 is supported", distro: "debian", version: "13", wantFamily: "Debian", - wantOK: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when ubuntu 20.04 is supported", distro: "ubuntu", version: "20.04", wantFamily: "Debian", - wantOK: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when ubuntu 22.04 is supported", distro: "ubuntu", version: "22.04", wantFamily: "Debian", - wantOK: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when ubuntu 24.04 is supported", distro: "ubuntu", version: "24.04", wantFamily: "Debian", - wantOK: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when Ubuntu with uppercase is supported", distro: "Ubuntu", version: "24.04", wantFamily: "Debian", - wantOK: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when unsupported distro returns false", distro: "centos", version: "8", wantFamily: "", - wantOK: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, { name: "when unsupported version returns false", distro: "ubuntu", version: "18.04", wantFamily: "", - wantOK: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, { name: "when empty distro returns false", distro: "", version: "24.04", wantFamily: "", - wantOK: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, { name: "when empty version returns false", distro: "ubuntu", version: "", wantFamily: "", - wantOK: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, } @@ -240,7 +276,7 @@ func (suite *ValidatePublicTestSuite) TestIsOSFamilySupported() { family, ok := cli.IsOSFamilySupported(tc.distro, tc.version) suite.Equal(tc.wantFamily, family) - suite.Equal(tc.wantOK, ok) + tc.validateFunc(ok) }) } } diff --git a/internal/config/nats_public_test.go b/internal/config/nats_public_test.go index cca2c77e1..f2cd40644 100644 --- a/internal/config/nats_public_test.go +++ b/internal/config/nats_public_test.go @@ -34,10 +34,9 @@ type NATSPublicTestSuite struct { func (s *NATSPublicTestSuite) TestAllKVBuckets() { tests := []struct { - name string - nats config.NATS - expectedNames []string - expectedBuckets []string + name string + nats config.NATS + validateFunc func([]config.KVBucketInfo) }{ { name: "all buckets populated", @@ -52,38 +51,64 @@ func (s *NATSPublicTestSuite) TestAllKVBuckets() { FileState: config.NATSFileState{Bucket: "file-state"}, Enrollment: config.NATSEnrollment{Bucket: "agent-enrollment"}, }, - expectedNames: []string{ - "job-queue", - "job-responses", - "registry", - "facts", - "state", - "file-state", - "enrollment", - }, - expectedBuckets: []string{ - "job-queue", - "job-responses", - "agent-registry", - "agent-facts", - "agent-state", - "file-state", - "agent-enrollment", + validateFunc: func(got []config.KVBucketInfo) { + s.Len(got, len([]string{ + "job-queue", + "job-responses", + "registry", + "facts", + "state", + "file-state", + "enrollment", + })) + for i, info := range got { + s.Equal([]string{ + "job-queue", + "job-responses", + "registry", + "facts", + "state", + "file-state", + "enrollment", + }[i], info.Name) + s.Equal([]string{ + "job-queue", + "job-responses", + "agent-registry", + "agent-facts", + "agent-state", + "file-state", + "agent-enrollment", + }[i], info.Bucket) + } }, }, { name: "empty config returns slice with empty bucket fields", nats: config.NATS{}, - expectedNames: []string{ - "job-queue", - "job-responses", - "registry", - "facts", - "state", - "file-state", - "enrollment", + validateFunc: func(got []config.KVBucketInfo) { + s.Len(got, len([]string{ + "job-queue", + "job-responses", + "registry", + "facts", + "state", + "file-state", + "enrollment", + })) + for i, info := range got { + s.Equal([]string{ + "job-queue", + "job-responses", + "registry", + "facts", + "state", + "file-state", + "enrollment", + }[i], info.Name) + s.Equal([]string{"", "", "", "", "", "", ""}[i], info.Bucket) + } }, - expectedBuckets: []string{"", "", "", "", "", "", ""}, }, { name: "partial config — only KV buckets set", @@ -93,76 +118,88 @@ func (s *NATSPublicTestSuite) TestAllKVBuckets() { ResponseBucket: "job-responses", }, }, - expectedNames: []string{ - "job-queue", - "job-responses", - "registry", - "facts", - "state", - "file-state", - "enrollment", - }, - expectedBuckets: []string{ - "job-queue", - "job-responses", - "", - "", - "", - "", - "", + validateFunc: func(got []config.KVBucketInfo) { + s.Len(got, len([]string{ + "job-queue", + "job-responses", + "registry", + "facts", + "state", + "file-state", + "enrollment", + })) + for i, info := range got { + s.Equal([]string{ + "job-queue", + "job-responses", + "registry", + "facts", + "state", + "file-state", + "enrollment", + }[i], info.Name) + s.Equal([]string{ + "job-queue", + "job-responses", + "", + "", + "", + "", + "", + }[i], info.Bucket) + } }, }, } for _, tt := range tests { s.Run(tt.name, func() { - got := tt.nats.AllKVBuckets() - - s.Len(got, len(tt.expectedNames)) - for i, info := range got { - s.Equal(tt.expectedNames[i], info.Name) - s.Equal(tt.expectedBuckets[i], info.Bucket) - } + tt.validateFunc(tt.nats.AllKVBuckets()) }) } } func (s *NATSPublicTestSuite) TestAllObjectStoreBuckets() { tests := []struct { - name string - nats config.NATS - expectedNames []string - expectedBuckets []string + name string + nats config.NATS + validateFunc func([]config.ObjectStoreBucketInfo) }{ { name: "objects bucket populated", nats: config.NATS{ Objects: config.NATSObjects{Bucket: "file-objects"}, }, - expectedNames: []string{"file-objects"}, - expectedBuckets: []string{"file-objects"}, + validateFunc: func(got []config.ObjectStoreBucketInfo) { + s.Len(got, len([]string{"file-objects"})) + for i, info := range got { + s.Equal([]string{"file-objects"}[i], info.Name) + s.Equal([]string{"file-objects"}[i], info.Bucket) + } + }, }, { - name: "empty config returns slice with empty bucket field", - nats: config.NATS{}, - expectedNames: []string{"file-objects"}, - expectedBuckets: []string{""}, + name: "empty config returns slice with empty bucket field", + nats: config.NATS{}, + validateFunc: func(got []config.ObjectStoreBucketInfo) { + s.Len(got, len([]string{"file-objects"})) + for i, info := range got { + s.Equal([]string{"file-objects"}[i], info.Name) + s.Equal([]string{""}[i], info.Bucket) + } + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - got := tt.nats.AllObjectStoreBuckets() - - s.Len(got, len(tt.expectedNames)) - for i, info := range got { - s.Equal(tt.expectedNames[i], info.Name) - s.Equal(tt.expectedBuckets[i], info.Bucket) - } + tt.validateFunc(tt.nats.AllObjectStoreBuckets()) }) } } -func TestNATSPublicTestSuite(t *testing.T) { +func TestNATSPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NATSPublicTestSuite)) } diff --git a/internal/config/schema_public_test.go b/internal/config/schema_public_test.go index 9ebdc3131..be660bc83 100644 --- a/internal/config/schema_public_test.go +++ b/internal/config/schema_public_test.go @@ -36,10 +36,9 @@ type ConfigPublicTestSuite struct { func (s *ConfigPublicTestSuite) TestValidate() { tests := []struct { - name string - config config.Config - expectError bool - errContains string + name string + config config.Config + validateFunc func(error) }{ { name: "valid config", @@ -73,7 +72,9 @@ func (s *ConfigPublicTestSuite) TestValidate() { }, }, }, - expectError: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "missing signing key", @@ -91,8 +92,10 @@ func (s *ConfigPublicTestSuite) TestValidate() { }, }, }, - expectError: true, - errContains: "SigningKey", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "SigningKey") + }, }, { name: "missing bearer token", @@ -110,28 +113,23 @@ func (s *ConfigPublicTestSuite) TestValidate() { }, }, }, - expectError: true, - errContains: "BearerToken", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "BearerToken") + }, }, { - name: "missing both required fields", - config: config.Config{}, - expectError: true, + name: "missing both required fields", + config: config.Config{}, + validateFunc: func(err error) { + s.Error(err) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - err := config.Validate(&tt.config) - - if tt.expectError { - s.Error(err) - if tt.errContains != "" { - s.Contains(err.Error(), tt.errContains) - } - } else { - s.NoError(err) - } + tt.validateFunc(config.Validate(&tt.config)) }) } } @@ -181,6 +179,8 @@ func (s *ConfigPublicTestSuite) TestValidateRegisterValidatorsError() { } } -func TestConfigPublicTestSuite(t *testing.T) { +func TestConfigPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ConfigPublicTestSuite)) } diff --git a/internal/config/ui_public_test.go b/internal/config/ui_public_test.go index 018bbd1f1..fa8d2d7bf 100644 --- a/internal/config/ui_public_test.go +++ b/internal/config/ui_public_test.go @@ -37,34 +37,42 @@ func (s *UIPublicTestSuite) TestUIEnabled() { falseVal := false tests := []struct { - name string - cfg config.UIConfig - expected bool + name string + cfg config.UIConfig + validateFunc func(bool) }{ { - name: "defaults to true when Enabled is nil", - cfg: config.UIConfig{}, - expected: true, + name: "defaults to true when Enabled is nil", + cfg: config.UIConfig{}, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "returns true when Enabled is explicitly true", - cfg: config.UIConfig{Enabled: &trueVal}, - expected: true, + name: "returns true when Enabled is explicitly true", + cfg: config.UIConfig{Enabled: &trueVal}, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "returns false when Enabled is explicitly false", - cfg: config.UIConfig{Enabled: &falseVal}, - expected: false, + name: "returns false when Enabled is explicitly false", + cfg: config.UIConfig{Enabled: &falseVal}, + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, } for _, tc := range tests { s.Run(tc.name, func() { - s.Equal(tc.expected, tc.cfg.UIEnabled()) + tc.validateFunc(tc.cfg.UIEnabled()) }) } } -func TestUIPublicTestSuite(t *testing.T) { +func TestUIPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(UIPublicTestSuite)) } diff --git a/internal/controller/api/agent/agent_drain_public_test.go b/internal/controller/api/agent/agent_drain_public_test.go index 53f9af159..fe7cece7d 100644 --- a/internal/controller/api/agent/agent_drain_public_test.go +++ b/internal/controller/api/agent/agent_drain_public_test.go @@ -236,8 +236,7 @@ func (s *AgentDrainPublicTestSuite) TestDrainAgentHTTP() { name string hostname string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when hostname exceeds max length returns 400", @@ -245,8 +244,10 @@ func (s *AgentDrainPublicTestSuite) TestDrainAgentHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when agent exists returns 200", @@ -268,8 +269,11 @@ func (s *AgentDrainPublicTestSuite) TestDrainAgentHTTP() { Return(nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"message"`, `drain initiated`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"message"`) + s.Contains(rec.Body.String(), `drain initiated`) + }, }, { name: "when agent not found returns 404", @@ -281,8 +285,10 @@ func (s *AgentDrainPublicTestSuite) TestDrainAgentHTTP() { Return(nil, fmt.Errorf("agent not found: unknown")) return mock }, - wantCode: http.StatusNotFound, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusNotFound, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when agent already draining returns 409", @@ -298,8 +304,11 @@ func (s *AgentDrainPublicTestSuite) TestDrainAgentHTTP() { }, nil) return mock }, - wantCode: http.StatusConflict, - wantContains: []string{`"error"`, `already in Draining`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusConflict, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), `already in Draining`) + }, }, } @@ -322,10 +331,7 @@ func (s *AgentDrainPublicTestSuite) TestDrainAgentHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -339,8 +345,7 @@ func (s *AgentDrainPublicTestSuite) TestDrainAgentRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -350,8 +355,10 @@ func (s *AgentDrainPublicTestSuite) TestDrainAgentRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -368,8 +375,10 @@ func (s *AgentDrainPublicTestSuite) TestDrainAgentRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with agent:write returns 200", @@ -400,8 +409,11 @@ func (s *AgentDrainPublicTestSuite) TestDrainAgentRBACHTTP() { Return(nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"message"`, `drain initiated`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"message"`) + s.Contains(rec.Body.String(), `drain initiated`) + }, }, } @@ -439,14 +451,13 @@ func (s *AgentDrainPublicTestSuite) TestDrainAgentRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestAgentDrainPublicTestSuite(t *testing.T) { +func TestAgentDrainPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentDrainPublicTestSuite)) } diff --git a/internal/controller/api/agent/agent_enroll_accept_public_test.go b/internal/controller/api/agent/agent_enroll_accept_public_test.go index b376edf92..e88831807 100644 --- a/internal/controller/api/agent/agent_enroll_accept_public_test.go +++ b/internal/controller/api/agent/agent_enroll_accept_public_test.go @@ -209,8 +209,7 @@ func (s *AgentEnrollAcceptPublicTestSuite) TestAcceptAgentHTTP() { name string hostname string setupMocks func() (*jobmocks.MockJobClient, *agentmocks.MockEnrollmentManager) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when hostname exceeds max length returns 400", @@ -222,8 +221,10 @@ func (s *AgentEnrollAcceptPublicTestSuite) TestAcceptAgentHTTP() { s.mockCtrl, ) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when agent accepted returns 200", @@ -234,8 +235,11 @@ func (s *AgentEnrollAcceptPublicTestSuite) TestAcceptAgentHTTP() { em.EXPECT().AcceptByHostname(gomock.Any(), "web-01").Return(nil) return jm, em }, - wantCode: http.StatusOK, - wantContains: []string{`"message"`, `accepted`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"message"`) + s.Contains(rec.Body.String(), `accepted`) + }, }, { name: "when not found returns 404", @@ -247,8 +251,10 @@ func (s *AgentEnrollAcceptPublicTestSuite) TestAcceptAgentHTTP() { Return(fmt.Errorf("no pending agent with hostname")) return jm, em }, - wantCode: http.StatusNotFound, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusNotFound, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, } @@ -271,10 +277,7 @@ func (s *AgentEnrollAcceptPublicTestSuite) TestAcceptAgentHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -288,8 +291,7 @@ func (s *AgentEnrollAcceptPublicTestSuite) TestAcceptAgentRBACHTTP() { name string setupAuth func(req *http.Request) setupMocks func() (*jobmocks.MockJobClient, *agentmocks.MockEnrollmentManager) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -301,8 +303,10 @@ func (s *AgentEnrollAcceptPublicTestSuite) TestAcceptAgentRBACHTTP() { s.mockCtrl, ) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -323,8 +327,10 @@ func (s *AgentEnrollAcceptPublicTestSuite) TestAcceptAgentRBACHTTP() { s.mockCtrl, ) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with agent:write returns 200", @@ -344,8 +350,11 @@ func (s *AgentEnrollAcceptPublicTestSuite) TestAcceptAgentRBACHTTP() { em.EXPECT().AcceptByHostname(gomock.Any(), "web-01").Return(nil) return jm, em }, - wantCode: http.StatusOK, - wantContains: []string{`"message"`, `accepted`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"message"`) + s.Contains(rec.Body.String(), `accepted`) + }, }, } @@ -383,14 +392,13 @@ func (s *AgentEnrollAcceptPublicTestSuite) TestAcceptAgentRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestAgentEnrollAcceptPublicTestSuite(t *testing.T) { +func TestAgentEnrollAcceptPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentEnrollAcceptPublicTestSuite)) } diff --git a/internal/controller/api/agent/agent_enroll_reject_public_test.go b/internal/controller/api/agent/agent_enroll_reject_public_test.go index 9e4b97ae0..5900af3cb 100644 --- a/internal/controller/api/agent/agent_enroll_reject_public_test.go +++ b/internal/controller/api/agent/agent_enroll_reject_public_test.go @@ -165,8 +165,7 @@ func (s *AgentEnrollRejectPublicTestSuite) TestRejectAgentHTTP() { name string hostname string setupMocks func() (*jobmocks.MockJobClient, *agentmocks.MockEnrollmentManager) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when hostname exceeds max length returns 400", @@ -178,8 +177,10 @@ func (s *AgentEnrollRejectPublicTestSuite) TestRejectAgentHTTP() { s.mockCtrl, ) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when agent rejected returns 200", @@ -190,8 +191,11 @@ func (s *AgentEnrollRejectPublicTestSuite) TestRejectAgentHTTP() { em.EXPECT().RejectByHostname(gomock.Any(), "web-01", "rejected via API").Return(nil) return jm, em }, - wantCode: http.StatusOK, - wantContains: []string{`"message"`, `rejected`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"message"`) + s.Contains(rec.Body.String(), `rejected`) + }, }, { name: "when not found returns 404", @@ -203,8 +207,10 @@ func (s *AgentEnrollRejectPublicTestSuite) TestRejectAgentHTTP() { Return(fmt.Errorf("no pending agent with hostname")) return jm, em }, - wantCode: http.StatusNotFound, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusNotFound, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, } @@ -227,10 +233,7 @@ func (s *AgentEnrollRejectPublicTestSuite) TestRejectAgentHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -244,8 +247,7 @@ func (s *AgentEnrollRejectPublicTestSuite) TestRejectAgentRBACHTTP() { name string setupAuth func(req *http.Request) setupMocks func() (*jobmocks.MockJobClient, *agentmocks.MockEnrollmentManager) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -257,8 +259,10 @@ func (s *AgentEnrollRejectPublicTestSuite) TestRejectAgentRBACHTTP() { s.mockCtrl, ) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -279,8 +283,10 @@ func (s *AgentEnrollRejectPublicTestSuite) TestRejectAgentRBACHTTP() { s.mockCtrl, ) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with agent:write returns 200", @@ -300,8 +306,11 @@ func (s *AgentEnrollRejectPublicTestSuite) TestRejectAgentRBACHTTP() { em.EXPECT().RejectByHostname(gomock.Any(), "web-01", "rejected via API").Return(nil) return jm, em }, - wantCode: http.StatusOK, - wantContains: []string{`"message"`, `rejected`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"message"`) + s.Contains(rec.Body.String(), `rejected`) + }, }, } @@ -339,14 +348,13 @@ func (s *AgentEnrollRejectPublicTestSuite) TestRejectAgentRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestAgentEnrollRejectPublicTestSuite(t *testing.T) { +func TestAgentEnrollRejectPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentEnrollRejectPublicTestSuite)) } diff --git a/internal/controller/api/agent/agent_get_public_test.go b/internal/controller/api/agent/agent_get_public_test.go index cdc29e05e..a91d837ff 100644 --- a/internal/controller/api/agent/agent_get_public_test.go +++ b/internal/controller/api/agent/agent_get_public_test.go @@ -165,8 +165,7 @@ func (s *AgentGetPublicTestSuite) TestGetAgentDetailsHTTP() { name string hostname string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when hostname exceeds max length returns 400", @@ -174,8 +173,10 @@ func (s *AgentGetPublicTestSuite) TestGetAgentDetailsHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when agent exists returns details", @@ -196,8 +197,12 @@ func (s *AgentGetPublicTestSuite) TestGetAgentDetailsHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"server1"`, `"Ready"`, `"Ubuntu"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"server1"`) + s.Contains(rec.Body.String(), `"Ready"`) + s.Contains(rec.Body.String(), `"Ubuntu"`) + }, }, { name: "when agent not found returns 404", @@ -209,8 +214,10 @@ func (s *AgentGetPublicTestSuite) TestGetAgentDetailsHTTP() { Return(nil, fmt.Errorf("agent not found: unknown")) return mock }, - wantCode: http.StatusNotFound, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusNotFound, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when client error returns 500", @@ -222,8 +229,10 @@ func (s *AgentGetPublicTestSuite) TestGetAgentDetailsHTTP() { Return(nil, fmt.Errorf("connection failed")) return mock }, - wantCode: http.StatusInternalServerError, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, } @@ -246,10 +255,7 @@ func (s *AgentGetPublicTestSuite) TestGetAgentDetailsHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -263,8 +269,7 @@ func (s *AgentGetPublicTestSuite) TestGetAgentDetailsRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -274,8 +279,10 @@ func (s *AgentGetPublicTestSuite) TestGetAgentDetailsRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -292,8 +299,10 @@ func (s *AgentGetPublicTestSuite) TestGetAgentDetailsRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with agent:read returns 200", @@ -316,8 +325,11 @@ func (s *AgentGetPublicTestSuite) TestGetAgentDetailsRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"server1"`, `"Ready"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"server1"`) + s.Contains(rec.Body.String(), `"Ready"`) + }, }, } @@ -355,14 +367,13 @@ func (s *AgentGetPublicTestSuite) TestGetAgentDetailsRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestAgentGetPublicTestSuite(t *testing.T) { +func TestAgentGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentGetPublicTestSuite)) } diff --git a/internal/controller/api/agent/agent_list_public_test.go b/internal/controller/api/agent/agent_list_public_test.go index 98611a6ad..841e6d3cc 100644 --- a/internal/controller/api/agent/agent_list_public_test.go +++ b/internal/controller/api/agent/agent_list_public_test.go @@ -338,8 +338,7 @@ func (s *AgentListPublicTestSuite) TestListAgentsHTTP() { tests := []struct { name string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when agents exist returns agent list", @@ -353,8 +352,13 @@ func (s *AgentListPublicTestSuite) TestListAgentsHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"total":2`, `"server1"`, `"server2"`, `"status":"Ready"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"total":2`) + s.Contains(rec.Body.String(), `"server1"`) + s.Contains(rec.Body.String(), `"server2"`) + s.Contains(rec.Body.String(), `"status":"Ready"`) + }, }, { name: "when no agents returns empty list", @@ -365,8 +369,10 @@ func (s *AgentListPublicTestSuite) TestListAgentsHTTP() { Return([]jobtypes.AgentInfo{}, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"total":0`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"total":0`) + }, }, { name: "when job client errors returns 500", @@ -377,8 +383,10 @@ func (s *AgentListPublicTestSuite) TestListAgentsHTTP() { Return(nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, } @@ -397,10 +405,7 @@ func (s *AgentListPublicTestSuite) TestListAgentsHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -414,8 +419,7 @@ func (s *AgentListPublicTestSuite) TestListAgentsRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -425,8 +429,10 @@ func (s *AgentListPublicTestSuite) TestListAgentsRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -443,8 +449,10 @@ func (s *AgentListPublicTestSuite) TestListAgentsRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with agent:read returns 200", @@ -468,8 +476,11 @@ func (s *AgentListPublicTestSuite) TestListAgentsRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"total":2`, `"server1"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"total":2`) + s.Contains(rec.Body.String(), `"server1"`) + }, }, } @@ -507,10 +518,7 @@ func (s *AgentListPublicTestSuite) TestListAgentsRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -519,40 +527,50 @@ func (s *AgentListPublicTestSuite) TestUint64ToInt() { maxInt := int(^uint(0) >> 1) tests := []struct { - name string - val uint64 - want int + name string + val uint64 + validateFunc func(int) }{ { name: "when zero", val: 0, - want: 0, + validateFunc: func(got int) { + s.Equal(0, got) + }, }, { name: "when normal value", val: 42, - want: 42, + validateFunc: func(got int) { + s.Equal(42, got) + }, }, { name: "when max int value", val: uint64(maxInt), - want: maxInt, + validateFunc: func(got int) { + s.Equal(maxInt, got) + }, }, { name: "when overflow", val: math.MaxUint64, - want: maxInt, + validateFunc: func(got int) { + s.Equal(maxInt, got) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { got := apiagent.ExportUint64ToInt(tt.val) - s.Equal(tt.want, got) + tt.validateFunc(got) }) } } -func TestAgentListPublicTestSuite(t *testing.T) { +func TestAgentListPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentListPublicTestSuite)) } diff --git a/internal/controller/api/agent/agent_pending_public_test.go b/internal/controller/api/agent/agent_pending_public_test.go index dcf152505..f624dfb93 100644 --- a/internal/controller/api/agent/agent_pending_public_test.go +++ b/internal/controller/api/agent/agent_pending_public_test.go @@ -153,8 +153,7 @@ func (s *AgentPendingPublicTestSuite) TestGetAgentsPendingHTTP() { tests := []struct { name string setupMocks func() (*jobmocks.MockJobClient, *agentmocks.MockEnrollmentManager) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when pending agents exist returns 200", @@ -173,8 +172,12 @@ func (s *AgentPendingPublicTestSuite) TestGetAgentsPendingHTTP() { }, nil) return jm, em }, - wantCode: http.StatusOK, - wantContains: []string{`"agents"`, `"web-01"`, `"total"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"agents"`) + s.Contains(rec.Body.String(), `"web-01"`) + s.Contains(rec.Body.String(), `"total"`) + }, }, { name: "when list fails returns 500", @@ -186,8 +189,10 @@ func (s *AgentPendingPublicTestSuite) TestGetAgentsPendingHTTP() { Return(nil, fmt.Errorf("kv error")) return jm, em }, - wantCode: http.StatusInternalServerError, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, } @@ -206,10 +211,7 @@ func (s *AgentPendingPublicTestSuite) TestGetAgentsPendingHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -223,8 +225,7 @@ func (s *AgentPendingPublicTestSuite) TestGetAgentsPendingRBACHTTP() { name string setupAuth func(req *http.Request) setupMocks func() (*jobmocks.MockJobClient, *agentmocks.MockEnrollmentManager) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -236,8 +237,10 @@ func (s *AgentPendingPublicTestSuite) TestGetAgentsPendingRBACHTTP() { s.mockCtrl, ) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -258,8 +261,10 @@ func (s *AgentPendingPublicTestSuite) TestGetAgentsPendingRBACHTTP() { s.mockCtrl, ) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with agent:read returns 200", @@ -279,8 +284,11 @@ func (s *AgentPendingPublicTestSuite) TestGetAgentsPendingRBACHTTP() { em.EXPECT().ListPending(gomock.Any()).Return(nil, nil) return jm, em }, - wantCode: http.StatusOK, - wantContains: []string{`"agents"`, `"total"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"agents"`) + s.Contains(rec.Body.String(), `"total"`) + }, }, } @@ -314,14 +322,13 @@ func (s *AgentPendingPublicTestSuite) TestGetAgentsPendingRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestAgentPendingPublicTestSuite(t *testing.T) { +func TestAgentPendingPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentPendingPublicTestSuite)) } diff --git a/internal/controller/api/agent/agent_undrain_public_test.go b/internal/controller/api/agent/agent_undrain_public_test.go index 73f2ca5c5..144c295b3 100644 --- a/internal/controller/api/agent/agent_undrain_public_test.go +++ b/internal/controller/api/agent/agent_undrain_public_test.go @@ -251,8 +251,7 @@ func (s *AgentUndrainPublicTestSuite) TestUndrainAgentHTTP() { name string hostname string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when hostname exceeds max length returns 400", @@ -260,8 +259,10 @@ func (s *AgentUndrainPublicTestSuite) TestUndrainAgentHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when draining agent exists returns 200", @@ -283,8 +284,11 @@ func (s *AgentUndrainPublicTestSuite) TestUndrainAgentHTTP() { Return(nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"message"`, `undrain initiated`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"message"`) + s.Contains(rec.Body.String(), `undrain initiated`) + }, }, { name: "when agent not found returns 404", @@ -296,8 +300,10 @@ func (s *AgentUndrainPublicTestSuite) TestUndrainAgentHTTP() { Return(nil, fmt.Errorf("agent not found: unknown")) return mock }, - wantCode: http.StatusNotFound, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusNotFound, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when agent in ready state returns 409", @@ -313,8 +319,11 @@ func (s *AgentUndrainPublicTestSuite) TestUndrainAgentHTTP() { }, nil) return mock }, - wantCode: http.StatusConflict, - wantContains: []string{`"error"`, `not in draining or cordoned`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusConflict, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), `not in draining or cordoned`) + }, }, } @@ -337,10 +346,7 @@ func (s *AgentUndrainPublicTestSuite) TestUndrainAgentHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -354,8 +360,7 @@ func (s *AgentUndrainPublicTestSuite) TestUndrainAgentRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -365,8 +370,10 @@ func (s *AgentUndrainPublicTestSuite) TestUndrainAgentRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -383,8 +390,10 @@ func (s *AgentUndrainPublicTestSuite) TestUndrainAgentRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with agent:write returns 200", @@ -415,8 +424,11 @@ func (s *AgentUndrainPublicTestSuite) TestUndrainAgentRBACHTTP() { Return(nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"message"`, `undrain initiated`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"message"`) + s.Contains(rec.Body.String(), `undrain initiated`) + }, }, } @@ -454,14 +466,13 @@ func (s *AgentUndrainPublicTestSuite) TestUndrainAgentRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestAgentUndrainPublicTestSuite(t *testing.T) { +func TestAgentUndrainPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentUndrainPublicTestSuite)) } diff --git a/internal/controller/api/agent/handler_public_test.go b/internal/controller/api/agent/handler_public_test.go index 578846765..1b609d0a9 100644 --- a/internal/controller/api/agent/handler_public_test.go +++ b/internal/controller/api/agent/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -87,11 +87,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/audit/audit_export_public_test.go b/internal/controller/api/audit/audit_export_public_test.go index 5a5292c9d..fcfde28f1 100644 --- a/internal/controller/api/audit/audit_export_public_test.go +++ b/internal/controller/api/audit/audit_export_public_test.go @@ -169,8 +169,7 @@ func (s *AuditExportPublicTestSuite) TestGetAuditExportHTTP() { tests := []struct { name string setupStore func(mock *auditmocks.MockStore) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request returns entries", @@ -191,8 +190,10 @@ func (s *AuditExportPublicTestSuite) TestGetAuditExportHTTP() { }, }, nil) }, - wantCode: http.StatusOK, - wantContains: []string{`"total_items":1`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"total_items":1`) + }, }, } @@ -219,10 +220,7 @@ func (s *AuditExportPublicTestSuite) TestGetAuditExportHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -236,17 +234,18 @@ func (s *AuditExportPublicTestSuite) TestGetAuditExportRBACHTTP() { name string setupAuth func(req *http.Request) setupStore func(mock *auditmocks.MockStore) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", setupAuth: func(_ *http.Request) { // No auth header set }, - setupStore: func(_ *auditmocks.MockStore) {}, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + setupStore: func(_ *auditmocks.MockStore) {}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -260,9 +259,11 @@ func (s *AuditExportPublicTestSuite) TestGetAuditExportRBACHTTP() { s.Require().NoError(err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, - setupStore: func(_ *auditmocks.MockStore) {}, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + setupStore: func(_ *auditmocks.MockStore) {}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with audit:read returns 200", @@ -281,8 +282,10 @@ func (s *AuditExportPublicTestSuite) TestGetAuditExportRBACHTTP() { ListAll(gomock.Any()). Return([]auditstore.Entry{}, nil) }, - wantCode: http.StatusOK, - wantContains: []string{`"total_items":0`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"total_items":0`) + }, }, } @@ -323,14 +326,13 @@ func (s *AuditExportPublicTestSuite) TestGetAuditExportRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestAuditExportPublicTestSuite(t *testing.T) { +func TestAuditExportPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AuditExportPublicTestSuite)) } diff --git a/internal/controller/api/audit/audit_get_public_test.go b/internal/controller/api/audit/audit_get_public_test.go index a0c15b614..5b261c72e 100644 --- a/internal/controller/api/audit/audit_get_public_test.go +++ b/internal/controller/api/audit/audit_get_public_test.go @@ -146,8 +146,7 @@ func (s *AuditGetPublicTestSuite) TestGetAuditLogByIDHTTP() { name string path string setupStore func(mock *auditmocks.MockStore) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid UUID returns entry", @@ -167,15 +166,18 @@ func (s *AuditGetPublicTestSuite) TestGetAuditLogByIDHTTP() { DurationMs: 42, }, nil) }, - wantCode: http.StatusOK, - wantContains: []string{`"user":"user@example.com"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"user":"user@example.com"`) + }, }, { - name: "when invalid UUID returns 400", - path: "/api/audit/not-a-uuid", - setupStore: func(_ *auditmocks.MockStore) {}, - wantCode: http.StatusBadRequest, - wantContains: []string{}, + name: "when invalid UUID returns 400", + path: "/api/audit/not-a-uuid", + setupStore: func(_ *auditmocks.MockStore) {}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + }, }, } @@ -202,10 +204,7 @@ func (s *AuditGetPublicTestSuite) TestGetAuditLogByIDHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -219,17 +218,18 @@ func (s *AuditGetPublicTestSuite) TestGetAuditLogByIDRBACHTTP() { name string setupAuth func(req *http.Request) setupStore func(mock *auditmocks.MockStore) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", setupAuth: func(_ *http.Request) { // No auth header set }, - setupStore: func(_ *auditmocks.MockStore) {}, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + setupStore: func(_ *auditmocks.MockStore) {}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -243,9 +243,11 @@ func (s *AuditGetPublicTestSuite) TestGetAuditLogByIDRBACHTTP() { s.Require().NoError(err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, - setupStore: func(_ *auditmocks.MockStore) {}, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + setupStore: func(_ *auditmocks.MockStore) {}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with audit:read returns 200", @@ -274,8 +276,10 @@ func (s *AuditGetPublicTestSuite) TestGetAuditLogByIDRBACHTTP() { DurationMs: 42, }, nil) }, - wantCode: http.StatusOK, - wantContains: []string{`"user":"user@example.com"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"user":"user@example.com"`) + }, }, } @@ -316,14 +320,13 @@ func (s *AuditGetPublicTestSuite) TestGetAuditLogByIDRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestAuditGetPublicTestSuite(t *testing.T) { +func TestAuditGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AuditGetPublicTestSuite)) } diff --git a/internal/controller/api/audit/audit_list_public_test.go b/internal/controller/api/audit/audit_list_public_test.go index d93ea9522..42bf85e49 100644 --- a/internal/controller/api/audit/audit_list_public_test.go +++ b/internal/controller/api/audit/audit_list_public_test.go @@ -478,6 +478,8 @@ func (s *AuditListPublicTestSuite) TestGetAuditLogsRBACHTTP() { } } -func TestAuditListPublicTestSuite(t *testing.T) { +func TestAuditListPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AuditListPublicTestSuite)) } diff --git a/internal/controller/api/audit/handler_public_test.go b/internal/controller/api/audit/handler_public_test.go index 2bab4734b..3bbbb16d0 100644 --- a/internal/controller/api/audit/handler_public_test.go +++ b/internal/controller/api/audit/handler_public_test.go @@ -40,18 +40,18 @@ type HandlerPublicTestSuite struct { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -65,7 +65,7 @@ func (s *HandlerPublicTestSuite) TestHandler() { }, { name: "closure registers export route and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -92,11 +92,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/audit/fixture_public_test.go b/internal/controller/api/audit/test_audit_handler_public_test.go similarity index 100% rename from internal/controller/api/audit/fixture_public_test.go rename to internal/controller/api/audit/test_audit_handler_public_test.go diff --git a/internal/controller/api/facts/facts_keys_get_public_test.go b/internal/controller/api/facts/facts_keys_get_public_test.go index 7a1896631..993ab03eb 100644 --- a/internal/controller/api/facts/facts_keys_get_public_test.go +++ b/internal/controller/api/facts/facts_keys_get_public_test.go @@ -136,16 +136,18 @@ func (s *FactsKeysGetPublicTestSuite) TestGetFactKeysRBACHTTP() { tokenManager := authtoken.New(s.logger) tests := []struct { - name string - setupAuth func(req *http.Request) - wantCode int + name string + setupAuth func(req *http.Request) + validateFunc func(int) }{ { name: "when no token returns 401", setupAuth: func(_ *http.Request) { // No auth header set }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when insufficient permissions returns 403", @@ -159,7 +161,9 @@ func (s *FactsKeysGetPublicTestSuite) TestGetFactKeysRBACHTTP() { s.Require().NoError(err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, - wantCode: http.StatusForbidden, + validateFunc: func(got int) { + s.Equal(http.StatusForbidden, got) + }, }, { name: "when valid token with agent:read returns 200", @@ -173,7 +177,9 @@ func (s *FactsKeysGetPublicTestSuite) TestGetFactKeysRBACHTTP() { s.Require().NoError(err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, { name: "when admin role returns 200", @@ -187,7 +193,9 @@ func (s *FactsKeysGetPublicTestSuite) TestGetFactKeysRBACHTTP() { s.Require().NoError(err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -212,11 +220,13 @@ func (s *FactsKeysGetPublicTestSuite) TestGetFactKeysRBACHTTP() { rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tt.wantCode, rec.Code) + tt.validateFunc(rec.Code) }) } } -func TestFactsKeysGetPublicTestSuite(t *testing.T) { +func TestFactsKeysGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FactsKeysGetPublicTestSuite)) } diff --git a/internal/controller/api/facts/handler_public_test.go b/internal/controller/api/facts/handler_public_test.go index 600db1560..6c8080bd8 100644 --- a/internal/controller/api/facts/handler_public_test.go +++ b/internal/controller/api/facts/handler_public_test.go @@ -38,18 +38,18 @@ type HandlerPublicTestSuite struct { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -71,11 +71,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/file/file_delete_public_test.go b/internal/controller/api/file/file_delete_public_test.go index cc994daf3..b287a70bd 100644 --- a/internal/controller/api/file/file_delete_public_test.go +++ b/internal/controller/api/file/file_delete_public_test.go @@ -183,8 +183,7 @@ func (s *FileDeletePublicTestSuite) TestDeleteFileByNameValidationHTTP() { name string path string setupMock func() *mocks.MockObjectStoreManager - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when name too long returns 400", @@ -192,8 +191,10 @@ func (s *FileDeletePublicTestSuite) TestDeleteFileByNameValidationHTTP() { setupMock: func() *mocks.MockObjectStoreManager { return mocks.NewMockObjectStoreManager(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when delete Ok", @@ -211,8 +212,11 @@ func (s *FileDeletePublicTestSuite) TestDeleteFileByNameValidationHTTP() { Return(nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"name":"nginx.conf"`, `"deleted":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"name":"nginx.conf"`) + s.Contains(rec.Body.String(), `"deleted":true`) + }, }, { name: "when not found", @@ -224,8 +228,10 @@ func (s *FileDeletePublicTestSuite) TestDeleteFileByNameValidationHTTP() { Return(nil, jetstream.ErrObjectNotFound) return mock }, - wantCode: http.StatusNotFound, - wantContains: []string{"file not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusNotFound, rec.Code) + s.Contains(rec.Body.String(), "file not found") + }, }, { name: "when delete error", @@ -243,8 +249,10 @@ func (s *FileDeletePublicTestSuite) TestDeleteFileByNameValidationHTTP() { Return(assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, - wantContains: []string{"failed to delete file"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + s.Contains(rec.Body.String(), "failed to delete file") + }, }, } @@ -263,10 +271,7 @@ func (s *FileDeletePublicTestSuite) TestDeleteFileByNameValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -280,8 +285,7 @@ func (s *FileDeletePublicTestSuite) TestDeleteFileByNameRBACHTTP() { name string setupAuth func(req *http.Request) setupMock func() *mocks.MockObjectStoreManager - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -291,8 +295,10 @@ func (s *FileDeletePublicTestSuite) TestDeleteFileByNameRBACHTTP() { setupMock: func() *mocks.MockObjectStoreManager { return mocks.NewMockObjectStoreManager(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -309,8 +315,10 @@ func (s *FileDeletePublicTestSuite) TestDeleteFileByNameRBACHTTP() { setupMock: func() *mocks.MockObjectStoreManager { return mocks.NewMockObjectStoreManager(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with file:write returns 200", @@ -337,8 +345,11 @@ func (s *FileDeletePublicTestSuite) TestDeleteFileByNameRBACHTTP() { Return(nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"name":"nginx.conf"`, `"deleted":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"name":"nginx.conf"`) + s.Contains(rec.Body.String(), `"deleted":true`) + }, }, } @@ -372,14 +383,13 @@ func (s *FileDeletePublicTestSuite) TestDeleteFileByNameRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestFileDeletePublicTestSuite(t *testing.T) { +func TestFileDeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FileDeletePublicTestSuite)) } diff --git a/internal/controller/api/file/file_get_public_test.go b/internal/controller/api/file/file_get_public_test.go index 24e474e39..81f3f59e3 100644 --- a/internal/controller/api/file/file_get_public_test.go +++ b/internal/controller/api/file/file_get_public_test.go @@ -161,8 +161,7 @@ func (s *FileGetPublicTestSuite) TestGetFileByNameValidationHTTP() { name string path string setupMock func() *mocks.MockObjectStoreManager - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when name too long returns 400", @@ -170,8 +169,10 @@ func (s *FileGetPublicTestSuite) TestGetFileByNameValidationHTTP() { setupMock: func() *mocks.MockObjectStoreManager { return mocks.NewMockObjectStoreManager(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when get Ok", @@ -192,12 +193,15 @@ func (s *FileGetPublicTestSuite) TestGetFileByNameValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{ - `"name":"nginx.conf"`, - `"sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"`, - `"size":1024`, - `"content_type":"raw"`, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"name":"nginx.conf"`) + s.Contains( + rec.Body.String(), + `"sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"`, + ) + s.Contains(rec.Body.String(), `"size":1024`) + s.Contains(rec.Body.String(), `"content_type":"raw"`) }, }, { @@ -210,8 +214,10 @@ func (s *FileGetPublicTestSuite) TestGetFileByNameValidationHTTP() { Return(nil, jetstream.ErrObjectNotFound) return mock }, - wantCode: http.StatusNotFound, - wantContains: []string{"file not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusNotFound, rec.Code) + s.Contains(rec.Body.String(), "file not found") + }, }, { name: "when object store error", @@ -223,8 +229,10 @@ func (s *FileGetPublicTestSuite) TestGetFileByNameValidationHTTP() { Return(nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, - wantContains: []string{"failed to get file info"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + s.Contains(rec.Body.String(), "failed to get file info") + }, }, } @@ -243,10 +251,7 @@ func (s *FileGetPublicTestSuite) TestGetFileByNameValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -260,8 +265,7 @@ func (s *FileGetPublicTestSuite) TestGetFileByNameRBACHTTP() { name string setupAuth func(req *http.Request) setupMock func() *mocks.MockObjectStoreManager - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -271,8 +275,10 @@ func (s *FileGetPublicTestSuite) TestGetFileByNameRBACHTTP() { setupMock: func() *mocks.MockObjectStoreManager { return mocks.NewMockObjectStoreManager(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -289,8 +295,10 @@ func (s *FileGetPublicTestSuite) TestGetFileByNameRBACHTTP() { setupMock: func() *mocks.MockObjectStoreManager { return mocks.NewMockObjectStoreManager(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with file:read returns 200", @@ -320,8 +328,11 @@ func (s *FileGetPublicTestSuite) TestGetFileByNameRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"name":"nginx.conf"`, `"sha256"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"name":"nginx.conf"`) + s.Contains(rec.Body.String(), `"sha256"`) + }, }, } @@ -355,14 +366,13 @@ func (s *FileGetPublicTestSuite) TestGetFileByNameRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestFileGetPublicTestSuite(t *testing.T) { +func TestFileGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FileGetPublicTestSuite)) } diff --git a/internal/controller/api/file/file_list_public_test.go b/internal/controller/api/file/file_list_public_test.go index c4b51183b..511225968 100644 --- a/internal/controller/api/file/file_list_public_test.go +++ b/internal/controller/api/file/file_list_public_test.go @@ -208,8 +208,7 @@ func (s *FileListPublicTestSuite) TestGetFilesHTTP() { tests := []struct { name string setupMock func() *mocks.MockObjectStoreManager - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when list Ok", @@ -231,8 +230,13 @@ func (s *FileListPublicTestSuite) TestGetFilesHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"files"`, `"nginx.conf"`, `"total":1`, `"content_type":"raw"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"files"`) + s.Contains(rec.Body.String(), `"nginx.conf"`) + s.Contains(rec.Body.String(), `"total":1`) + s.Contains(rec.Body.String(), `"content_type":"raw"`) + }, }, { name: "when object store error", @@ -243,8 +247,10 @@ func (s *FileListPublicTestSuite) TestGetFilesHTTP() { Return(nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, - wantContains: []string{"failed to list files"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + s.Contains(rec.Body.String(), "failed to list files") + }, }, } @@ -263,10 +269,7 @@ func (s *FileListPublicTestSuite) TestGetFilesHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -280,8 +283,7 @@ func (s *FileListPublicTestSuite) TestGetFilesRBACHTTP() { name string setupAuth func(req *http.Request) setupMock func() *mocks.MockObjectStoreManager - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -291,8 +293,10 @@ func (s *FileListPublicTestSuite) TestGetFilesRBACHTTP() { setupMock: func() *mocks.MockObjectStoreManager { return mocks.NewMockObjectStoreManager(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -309,8 +313,10 @@ func (s *FileListPublicTestSuite) TestGetFilesRBACHTTP() { setupMock: func() *mocks.MockObjectStoreManager { return mocks.NewMockObjectStoreManager(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with file:read returns 200", @@ -331,8 +337,11 @@ func (s *FileListPublicTestSuite) TestGetFilesRBACHTTP() { Return([]*jetstream.ObjectInfo{}, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"files"`, `"total":0`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"files"`) + s.Contains(rec.Body.String(), `"total":0`) + }, }, } @@ -366,14 +375,13 @@ func (s *FileListPublicTestSuite) TestGetFilesRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestFileListPublicTestSuite(t *testing.T) { +func TestFileListPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FileListPublicTestSuite)) } diff --git a/internal/controller/api/file/file_stale.go b/internal/controller/api/file/file_stale.go index 38278ca28..414c27cbb 100644 --- a/internal/controller/api/file/file_stale.go +++ b/internal/controller/api/file/file_stale.go @@ -143,7 +143,9 @@ func (f *File) GetFileStale( // extractHostname extracts the hostname from a state KV key. // The key format is "." where the SHA is // 64 hex characters. We remove the trailing dot + 64 chars. -func extractHostname(key string) string { +func extractHostname( + key string, +) string { // dot (1) + sha256 hex (64) = 65 chars from the end if len(key) > 65 { return key[:len(key)-65] @@ -153,7 +155,9 @@ func extractHostname(key string) string { } // computeSHA256 returns the hex-encoded SHA-256 digest of data. -func computeSHA256(data []byte) string { +func computeSHA256( + data []byte, +) string { h := sha256.Sum256(data) return hex.EncodeToString(h[:]) diff --git a/internal/controller/api/file/file_stale_public_test.go b/internal/controller/api/file/file_stale_public_test.go index 1f90d47ca..6ae120ff1 100644 --- a/internal/controller/api/file/file_stale_public_test.go +++ b/internal/controller/api/file/file_stale_public_test.go @@ -487,8 +487,7 @@ func (s *FileStalePublicTestSuite) TestGetFileStaleHTTP() { tests := []struct { name string setupMock func() (*mocks.MockObjectStoreManager, *mocks.MockStateKeyValue) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when empty state KV returns 200 with empty list", @@ -500,8 +499,11 @@ func (s *FileStalePublicTestSuite) TestGetFileStaleHTTP() { Return(nil, jetstream.ErrNoKeysFound) return objMock, kvMock }, - wantCode: http.StatusOK, - wantContains: []string{`"stale":[]`, `"total":0`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"stale":[]`) + s.Contains(rec.Body.String(), `"total":0`) + }, }, { name: "when state KV nil returns 500", @@ -509,8 +511,10 @@ func (s *FileStalePublicTestSuite) TestGetFileStaleHTTP() { objMock := mocks.NewMockObjectStoreManager(s.mockCtrl) return objMock, nil }, - wantCode: http.StatusInternalServerError, - wantContains: []string{"file state KV not available"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + s.Contains(rec.Body.String(), "file state KV not available") + }, }, } @@ -534,10 +538,7 @@ func (s *FileStalePublicTestSuite) TestGetFileStaleHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -551,8 +552,7 @@ func (s *FileStalePublicTestSuite) TestGetFileStaleRBACHTTP() { name string setupAuth func(req *http.Request) setupMock func() (*mocks.MockObjectStoreManager, *mocks.MockStateKeyValue) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -563,8 +563,10 @@ func (s *FileStalePublicTestSuite) TestGetFileStaleRBACHTTP() { return mocks.NewMockObjectStoreManager(s.mockCtrl), mocks.NewMockStateKeyValue(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -582,8 +584,10 @@ func (s *FileStalePublicTestSuite) TestGetFileStaleRBACHTTP() { return mocks.NewMockObjectStoreManager(s.mockCtrl), mocks.NewMockStateKeyValue(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with file:read returns 200", @@ -605,8 +609,11 @@ func (s *FileStalePublicTestSuite) TestGetFileStaleRBACHTTP() { Return(nil, jetstream.ErrNoKeysFound) return objMock, kvMock }, - wantCode: http.StatusOK, - wantContains: []string{`"stale"`, `"total":0`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"stale"`) + s.Contains(rec.Body.String(), `"total":0`) + }, }, } @@ -640,20 +647,21 @@ func (s *FileStalePublicTestSuite) TestGetFileStaleRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestFileStalePublicTestSuite(t *testing.T) { +func TestFileStalePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FileStalePublicTestSuite)) } // sha256Hex returns the hex-encoded SHA-256 digest of data. -func sha256Hex(data []byte) string { +func sha256Hex( + data []byte, +) string { h := sha256.Sum256(data) return hex.EncodeToString(h[:]) diff --git a/internal/controller/api/file/file_upload_public_test.go b/internal/controller/api/file/file_upload_public_test.go index 411053592..01a58f2eb 100644 --- a/internal/controller/api/file/file_upload_public_test.go +++ b/internal/controller/api/file/file_upload_public_test.go @@ -33,6 +33,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/nats-io/nats.go" "github.com/nats-io/nats.go/jetstream" "github.com/stretchr/testify/assert" @@ -71,11 +73,6 @@ func (s *FileUploadPublicTestSuite) TearDownTest() { s.mockCtrl.Finish() } -// makeMultipartReader builds a multipart.Reader for testing. Pass empty -// contentType to omit the content_type field. Pass nil data to omit the -// file part entirely. -func boolPtr(v bool) *bool { return &v } - func makeMultipartReader( name string, contentType string, @@ -299,7 +296,7 @@ func (s *FileUploadPublicTestSuite) TestPostFile() { { name: "when force upload bypasses digest check", request: gen.PostFileRequestObject{ - Params: gen.PostFileParams{Force: boolPtr(true)}, + Params: gen.PostFileParams{Force: ptr.To(true)}, Body: makeMultipartReader("nginx.conf", "raw", fileContent), }, setupMock: func() { @@ -320,7 +317,7 @@ func (s *FileUploadPublicTestSuite) TestPostFile() { { name: "when force upload same content still writes", request: gen.PostFileRequestObject{ - Params: gen.PostFileParams{Force: boolPtr(true)}, + Params: gen.PostFileParams{Force: ptr.To(true)}, Body: makeMultipartReader("nginx.conf", "raw", fileContent), }, setupMock: func() { @@ -454,8 +451,7 @@ func (s *FileUploadPublicTestSuite) TestPostFileValidationHTTP() { path string buildBody func() (*bytes.Buffer, string) setupMock func() *mocks.MockObjectStoreManager - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when upload Ok", @@ -475,13 +471,13 @@ func (s *FileUploadPublicTestSuite) TestPostFileValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusCreated, - wantContains: []string{ - `"name":"nginx.conf"`, - `"sha256"`, - `"size"`, - `"changed":true`, - `"content_type":"raw"`, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusCreated, rec.Code) + s.Contains(rec.Body.String(), `"name":"nginx.conf"`) + s.Contains(rec.Body.String(), `"sha256"`) + s.Contains(rec.Body.String(), `"size"`) + s.Contains(rec.Body.String(), `"changed":true`) + s.Contains(rec.Body.String(), `"content_type":"raw"`) }, }, { @@ -492,8 +488,10 @@ func (s *FileUploadPublicTestSuite) TestPostFileValidationHTTP() { setupMock: func() *mocks.MockObjectStoreManager { return mocks.NewMockObjectStoreManager(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{"name is required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), "name is required") + }, }, { name: "when different content without force returns 409", @@ -511,8 +509,10 @@ func (s *FileUploadPublicTestSuite) TestPostFileValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusConflict, - wantContains: []string{"already exists with different content"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusConflict, rec.Code) + s.Contains(rec.Body.String(), "already exists with different content") + }, }, { name: "when force upload bypasses digest check", @@ -530,8 +530,10 @@ func (s *FileUploadPublicTestSuite) TestPostFileValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusCreated, - wantContains: []string{`"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusCreated, rec.Code) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, { name: "when invalid force param returns 400", @@ -542,8 +544,10 @@ func (s *FileUploadPublicTestSuite) TestPostFileValidationHTTP() { setupMock: func() *mocks.MockObjectStoreManager { return mocks.NewMockObjectStoreManager(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{"Invalid format for parameter force"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), "Invalid format for parameter force") + }, }, { name: "when object store error", @@ -560,8 +564,10 @@ func (s *FileUploadPublicTestSuite) TestPostFileValidationHTTP() { Return(nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, - wantContains: []string{"failed to store file"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + s.Contains(rec.Body.String(), "failed to store file") + }, }, } @@ -592,10 +598,7 @@ func (s *FileUploadPublicTestSuite) TestPostFileValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -610,8 +613,7 @@ func (s *FileUploadPublicTestSuite) TestPostFileRBACHTTP() { name string setupAuth func(req *http.Request) setupMock func() *mocks.MockObjectStoreManager - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -621,8 +623,10 @@ func (s *FileUploadPublicTestSuite) TestPostFileRBACHTTP() { setupMock: func() *mocks.MockObjectStoreManager { return mocks.NewMockObjectStoreManager(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -639,8 +643,10 @@ func (s *FileUploadPublicTestSuite) TestPostFileRBACHTTP() { setupMock: func() *mocks.MockObjectStoreManager { return mocks.NewMockObjectStoreManager(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with file:write returns 201", @@ -667,8 +673,11 @@ func (s *FileUploadPublicTestSuite) TestPostFileRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusCreated, - wantContains: []string{`"name":"nginx.conf"`, `"sha256"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusCreated, rec.Code) + s.Contains(rec.Body.String(), `"name":"nginx.conf"`) + s.Contains(rec.Body.String(), `"sha256"`) + }, }, } @@ -708,14 +717,13 @@ func (s *FileUploadPublicTestSuite) TestPostFileRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestFileUploadPublicTestSuite(t *testing.T) { +func TestFileUploadPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FileUploadPublicTestSuite)) } diff --git a/internal/controller/api/file/handler_public_test.go b/internal/controller/api/file/handler_public_test.go index 19c0e103a..208f835fa 100644 --- a/internal/controller/api/file/handler_public_test.go +++ b/internal/controller/api/file/handler_public_test.go @@ -40,18 +40,18 @@ type HandlerPublicTestSuite struct { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -79,11 +79,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/handler_public_test.go b/internal/controller/api/handler_public_test.go index 228d783c2..a87e23d2f 100644 --- a/internal/controller/api/handler_public_test.go +++ b/internal/controller/api/handler_public_test.go @@ -69,10 +69,14 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestRegisterHandlers() { tests := []struct { - name string + name string + validateFunc func(int, int) }{ { name: "registers handlers with Echo", + validateFunc: func(routesAfter int, routesBefore int) { + s.Greater(routesAfter, routesBefore) + }, }, } @@ -111,12 +115,13 @@ func (s *HandlerPublicTestSuite) TestRegisterHandlers() { routesBefore := len(s.server.Echo.Routes()) s.server.RegisterHandlers(handlers) routesAfter := len(s.server.Echo.Routes()) - - s.Greater(routesAfter, routesBefore) + tt.validateFunc(routesAfter, routesBefore) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/health/checker_public_test.go b/internal/controller/api/health/checker_public_test.go index 696af477d..d288db179 100644 --- a/internal/controller/api/health/checker_public_test.go +++ b/internal/controller/api/health/checker_public_test.go @@ -42,10 +42,9 @@ func (s *CheckerPublicTestSuite) SetupTest() { func (s *CheckerPublicTestSuite) TestCheckHealth() { tests := []struct { - name string - checker *health.NATSChecker - expectErr bool - errMsg string + name string + checker *health.NATSChecker + validateFunc func(error) }{ { name: "all checks pass", @@ -53,7 +52,9 @@ func (s *CheckerPublicTestSuite) TestCheckHealth() { NATSCheck: func() error { return nil }, KVCheck: func() error { return nil }, }, - expectErr: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "NATS check fails", @@ -61,8 +62,10 @@ func (s *CheckerPublicTestSuite) TestCheckHealth() { NATSCheck: func() error { return fmt.Errorf("nats error") }, KVCheck: func() error { return nil }, }, - expectErr: true, - errMsg: "nats error", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "nats error") + }, }, { name: "KV check fails", @@ -70,8 +73,10 @@ func (s *CheckerPublicTestSuite) TestCheckHealth() { NATSCheck: func() error { return nil }, KVCheck: func() error { return fmt.Errorf("kv error") }, }, - expectErr: true, - errMsg: "kv error", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "kv error") + }, }, { name: "both checks fail", @@ -79,110 +84,109 @@ func (s *CheckerPublicTestSuite) TestCheckHealth() { NATSCheck: func() error { return fmt.Errorf("nats error") }, KVCheck: func() error { return fmt.Errorf("kv error") }, }, - expectErr: true, - errMsg: "nats error", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "nats error") + }, }, { - name: "nil checks pass", - checker: &health.NATSChecker{}, - expectErr: false, + name: "nil checks pass", + checker: &health.NATSChecker{}, + validateFunc: func(err error) { + s.NoError(err) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - err := tt.checker.CheckHealth(s.ctx) - - if tt.expectErr { - s.Error(err) - s.Contains(err.Error(), tt.errMsg) - } else { - s.NoError(err) - } + tt.validateFunc(tt.checker.CheckHealth(s.ctx)) }) } } func (s *CheckerPublicTestSuite) TestCheckNATS() { tests := []struct { - name string - checker *health.NATSChecker - expectErr bool + name string + checker *health.NATSChecker + validateFunc func(error) }{ { name: "NATS check passes", checker: &health.NATSChecker{ NATSCheck: func() error { return nil }, }, - expectErr: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "NATS check fails", checker: &health.NATSChecker{ NATSCheck: func() error { return fmt.Errorf("nats error") }, }, - expectErr: true, + validateFunc: func(err error) { + s.Error(err) + }, }, { - name: "nil NATS check passes", - checker: &health.NATSChecker{}, - expectErr: false, + name: "nil NATS check passes", + checker: &health.NATSChecker{}, + validateFunc: func(err error) { + s.NoError(err) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - err := tt.checker.CheckNATS() - - if tt.expectErr { - s.Error(err) - } else { - s.NoError(err) - } + tt.validateFunc(tt.checker.CheckNATS()) }) } } func (s *CheckerPublicTestSuite) TestCheckKV() { tests := []struct { - name string - checker *health.NATSChecker - expectErr bool + name string + checker *health.NATSChecker + validateFunc func(error) }{ { name: "KV check passes", checker: &health.NATSChecker{ KVCheck: func() error { return nil }, }, - expectErr: false, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "KV check fails", checker: &health.NATSChecker{ KVCheck: func() error { return fmt.Errorf("kv error") }, }, - expectErr: true, + validateFunc: func(err error) { + s.Error(err) + }, }, { - name: "nil KV check passes", - checker: &health.NATSChecker{}, - expectErr: false, + name: "nil KV check passes", + checker: &health.NATSChecker{}, + validateFunc: func(err error) { + s.NoError(err) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - err := tt.checker.CheckKV() - - if tt.expectErr { - s.Error(err) - } else { - s.NoError(err) - } + tt.validateFunc(tt.checker.CheckKV()) }) } } -func TestCheckerPublicTestSuite(t *testing.T) { +func TestCheckerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CheckerPublicTestSuite)) } diff --git a/internal/controller/api/health/handler_public_test.go b/internal/controller/api/health/handler_public_test.go index f6255ffd9..24ab165b8 100644 --- a/internal/controller/api/health/handler_public_test.go +++ b/internal/controller/api/health/handler_public_test.go @@ -39,18 +39,18 @@ type HandlerPublicTestSuite struct { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes for unauthenticated", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -64,7 +64,7 @@ func (s *HandlerPublicTestSuite) TestHandler() { }, { name: "closure registers routes and middleware executes for authenticated", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -92,11 +92,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/health/health_get_public_test.go b/internal/controller/api/health/health_get_public_test.go index 5da573651..f478b7048 100644 --- a/internal/controller/api/health/health_get_public_test.go +++ b/internal/controller/api/health/health_get_public_test.go @@ -86,14 +86,15 @@ func (s *HealthGetPublicTestSuite) TestGetHealth() { func (s *HealthGetPublicTestSuite) TestGetHealthHTTP() { tests := []struct { - name string - wantCode int - wantBody string + name string + validateFunc func(*httptest.ResponseRecorder) }{ { - name: "when liveness probe returns ok", - wantCode: http.StatusOK, - wantBody: `{"status":"ok"}`, + name: "when liveness probe returns ok", + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.JSONEq(`{"status":"ok"}`, rec.Body.String()) + }, }, } @@ -118,12 +119,13 @@ func (s *HealthGetPublicTestSuite) TestGetHealthHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - s.JSONEq(tc.wantBody, rec.Body.String()) + tc.validateFunc(rec) }) } } -func TestHealthGetPublicTestSuite(t *testing.T) { +func TestHealthGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HealthGetPublicTestSuite)) } diff --git a/internal/controller/api/health/health_ready_get_public_test.go b/internal/controller/api/health/health_ready_get_public_test.go index a1668a20b..fe51e1d75 100644 --- a/internal/controller/api/health/health_ready_get_public_test.go +++ b/internal/controller/api/health/health_ready_get_public_test.go @@ -130,8 +130,7 @@ func (s *HealthReadyGetPublicTestSuite) TestGetHealthReadyHTTP() { tests := []struct { name string checker *health.NATSChecker - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when all checks pass returns ready", @@ -139,8 +138,10 @@ func (s *HealthReadyGetPublicTestSuite) TestGetHealthReadyHTTP() { NATSCheck: func() error { return nil }, KVCheck: func() error { return nil }, }, - wantCode: http.StatusOK, - wantContains: []string{`"status":"ready"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"status":"ready"`) + }, }, { name: "when NATS check fails returns not ready", @@ -148,8 +149,11 @@ func (s *HealthReadyGetPublicTestSuite) TestGetHealthReadyHTTP() { NATSCheck: func() error { return fmt.Errorf("nats not connected") }, KVCheck: func() error { return nil }, }, - wantCode: http.StatusServiceUnavailable, - wantContains: []string{`"status":"not_ready"`, `"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusServiceUnavailable, rec.Code) + s.Contains(rec.Body.String(), `"status":"not_ready"`) + s.Contains(rec.Body.String(), `"error"`) + }, }, } @@ -173,14 +177,13 @@ func (s *HealthReadyGetPublicTestSuite) TestGetHealthReadyHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, want := range tc.wantContains { - s.Contains(rec.Body.String(), want) - } + tc.validateFunc(rec) }) } } -func TestHealthReadyGetPublicTestSuite(t *testing.T) { +func TestHealthReadyGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HealthReadyGetPublicTestSuite)) } diff --git a/internal/controller/api/health/health_status_get_public_test.go b/internal/controller/api/health/health_status_get_public_test.go index d058ed7da..d7d7ad2d3 100644 --- a/internal/controller/api/health/health_status_get_public_test.go +++ b/internal/controller/api/health/health_status_get_public_test.go @@ -665,8 +665,7 @@ func (s *HealthStatusGetPublicTestSuite) TestGetHealthStatusHTTP() { name string checker *health.NATSChecker metrics health.MetricsProvider - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when all components healthy returns status with metrics", @@ -736,24 +735,24 @@ func (s *HealthStatusGetPublicTestSuite) TestGetHealthStatusHTTP() { }, nil }, }, - wantCode: http.StatusOK, - wantContains: []string{ - `"status":"ok"`, - `"version":"0.1.0"`, - `"uptime"`, - `"nats"`, - `"streams"`, - `"kv_buckets"`, - `"object_stores"`, - `"consumers"`, - `"jobs"`, - `"agents"`, - `"web-01"`, - `"group=web.prod"`, - `"total":1`, - `"file-objects"`, - `"registry"`, - `"api-server-01"`, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"status":"ok"`) + s.Contains(rec.Body.String(), `"version":"0.1.0"`) + s.Contains(rec.Body.String(), `"uptime"`) + s.Contains(rec.Body.String(), `"nats"`) + s.Contains(rec.Body.String(), `"streams"`) + s.Contains(rec.Body.String(), `"kv_buckets"`) + s.Contains(rec.Body.String(), `"object_stores"`) + s.Contains(rec.Body.String(), `"consumers"`) + s.Contains(rec.Body.String(), `"jobs"`) + s.Contains(rec.Body.String(), `"agents"`) + s.Contains(rec.Body.String(), `"web-01"`) + s.Contains(rec.Body.String(), `"group=web.prod"`) + s.Contains(rec.Body.String(), `"total":1`) + s.Contains(rec.Body.String(), `"file-objects"`) + s.Contains(rec.Body.String(), `"registry"`) + s.Contains(rec.Body.String(), `"api-server-01"`) }, }, { @@ -762,11 +761,11 @@ func (s *HealthStatusGetPublicTestSuite) TestGetHealthStatusHTTP() { NATSCheck: func() error { return nil }, KVCheck: func() error { return nil }, }, - metrics: nil, - wantCode: http.StatusOK, - wantContains: []string{ - `"status":"ok"`, - `"version":"0.1.0"`, + metrics: nil, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"status":"ok"`) + s.Contains(rec.Body.String(), `"version":"0.1.0"`) }, }, } @@ -791,10 +790,7 @@ func (s *HealthStatusGetPublicTestSuite) TestGetHealthStatusHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, want := range tc.wantContains { - s.Contains(rec.Body.String(), want) - } + tc.validateFunc(rec) }) } } @@ -805,16 +801,17 @@ func (s *HealthStatusGetPublicTestSuite) TestGetHealthStatusRBACHTTP() { tests := []struct { name string setupAuth func(req *http.Request) - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", setupAuth: func(_ *http.Request) { // No auth header set }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -828,8 +825,10 @@ func (s *HealthStatusGetPublicTestSuite) TestGetHealthStatusRBACHTTP() { s.Require().NoError(err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with health:read returns 200", @@ -843,8 +842,11 @@ func (s *HealthStatusGetPublicTestSuite) TestGetHealthStatusRBACHTTP() { s.Require().NoError(err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, - wantCode: http.StatusOK, - wantContains: []string{`"status":"ok"`, `"version"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"status":"ok"`) + s.Contains(rec.Body.String(), `"version"`) + }, }, } @@ -924,10 +926,7 @@ func (s *HealthStatusGetPublicTestSuite) TestGetHealthStatusRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, want := range tc.wantContains { - s.Contains(rec.Body.String(), want) - } + tc.validateFunc(rec) }) } } @@ -998,6 +997,8 @@ func (s *HealthStatusGetPublicTestSuite) TestMetricsCache() { } } -func TestHealthStatusGetPublicTestSuite(t *testing.T) { +func TestHealthStatusGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HealthStatusGetPublicTestSuite)) } diff --git a/internal/controller/api/health/metrics_refresh_public_test.go b/internal/controller/api/health/metrics_refresh_public_test.go index 2b766d935..0edcf0bbb 100644 --- a/internal/controller/api/health/metrics_refresh_public_test.go +++ b/internal/controller/api/health/metrics_refresh_public_test.go @@ -164,6 +164,8 @@ func (s *MetricsRefreshPublicTestSuite) TestStartMetricsRefresh() { } } -func TestMetricsRefreshPublicTestSuite(t *testing.T) { +func TestMetricsRefreshPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(MetricsRefreshPublicTestSuite)) } diff --git a/internal/controller/api/job/handler_public_test.go b/internal/controller/api/job/handler_public_test.go index 63a7e962e..8d82aabbd 100644 --- a/internal/controller/api/job/handler_public_test.go +++ b/internal/controller/api/job/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/job/job_delete_public_test.go b/internal/controller/api/job/job_delete_public_test.go index 3b09f7321..37d747420 100644 --- a/internal/controller/api/job/job_delete_public_test.go +++ b/internal/controller/api/job/job_delete_public_test.go @@ -131,8 +131,7 @@ func (s *JobDeletePublicTestSuite) TestDeleteJobByIDHTTP() { name string jobID string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid uuid", @@ -144,7 +143,9 @@ func (s *JobDeletePublicTestSuite) TestDeleteJobByIDHTTP() { Return(nil) return mock }, - wantCode: http.StatusNoContent, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusNoContent, rec.Code) + }, }, { name: "when invalid uuid", @@ -152,8 +153,11 @@ func (s *JobDeletePublicTestSuite) TestDeleteJobByIDHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"message"`, "Invalid format for parameter id"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"message"`) + s.Contains(rec.Body.String(), "Invalid format for parameter id") + }, }, } @@ -176,10 +180,7 @@ func (s *JobDeletePublicTestSuite) TestDeleteJobByIDHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -193,8 +194,7 @@ func (s *JobDeletePublicTestSuite) TestDeleteJobByIDRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -204,8 +204,10 @@ func (s *JobDeletePublicTestSuite) TestDeleteJobByIDRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -222,8 +224,10 @@ func (s *JobDeletePublicTestSuite) TestDeleteJobByIDRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with job:write returns 204", @@ -244,7 +248,9 @@ func (s *JobDeletePublicTestSuite) TestDeleteJobByIDRBACHTTP() { Return(nil) return mock }, - wantCode: http.StatusNoContent, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusNoContent, rec.Code) + }, }, } @@ -281,14 +287,13 @@ func (s *JobDeletePublicTestSuite) TestDeleteJobByIDRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestJobDeletePublicTestSuite(t *testing.T) { +func TestJobDeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(JobDeletePublicTestSuite)) } diff --git a/internal/controller/api/job/job_get.go b/internal/controller/api/job/job_get.go index 67dd4cf48..8a5f3b71b 100644 --- a/internal/controller/api/job/job_get.go +++ b/internal/controller/api/job/job_get.go @@ -26,6 +26,8 @@ import ( "log/slog" "strings" + "k8s.io/utils/ptr" + "github.com/google/uuid" "github.com/osapi-io/osapi/internal/controller/api/job/gen" @@ -100,8 +102,8 @@ func (j *Job) GetJobByID( Status *string `json:"status,omitempty"` }{ Changed: r.Changed, - Status: strPtr(string(r.Status)), - Hostname: strPtr(r.Hostname), + Status: ptr.To(string(r.Status)), + Hostname: ptr.To(r.Hostname), } if r.Data != nil { var data interface{} @@ -109,7 +111,7 @@ func (j *Job) GetJobByID( entry.Data = data } if r.Error != "" { - entry.Error = strPtr(r.Error) + entry.Error = ptr.To(r.Error) } respMap[hostname] = entry } @@ -128,11 +130,11 @@ func (j *Job) GetJobByID( for i, te := range qj.Timeline { ts := te.Timestamp.Format("2006-01-02T15:04:05Z07:00") timeline[i].Timestamp = &ts - timeline[i].Event = strPtr(te.Event) - timeline[i].Hostname = strPtr(te.Hostname) - timeline[i].Message = strPtr(te.Message) + timeline[i].Event = ptr.To(te.Event) + timeline[i].Hostname = ptr.To(te.Hostname) + timeline[i].Message = ptr.To(te.Message) if te.Error != "" { - timeline[i].Error = strPtr(te.Error) + timeline[i].Error = ptr.To(te.Error) } } resp.Timeline = &timeline @@ -151,13 +153,13 @@ func (j *Job) GetJobByID( Error *string `json:"error,omitempty"` Status *string `json:"status,omitempty"` }{ - Status: strPtr(ws.Status), + Status: ptr.To(ws.Status), } if ws.Error != "" { - entry.Error = strPtr(ws.Error) + entry.Error = ptr.To(ws.Error) } if ws.Duration != "" { - entry.Duration = strPtr(ws.Duration) + entry.Duration = ptr.To(ws.Duration) } wsMap[hostname] = entry } @@ -166,9 +168,3 @@ func (j *Job) GetJobByID( return resp, nil } - -func strPtr( - s string, -) *string { - return &s -} diff --git a/internal/controller/api/job/job_get_public_test.go b/internal/controller/api/job/job_get_public_test.go index 2795ea6ea..5d57c44df 100644 --- a/internal/controller/api/job/job_get_public_test.go +++ b/internal/controller/api/job/job_get_public_test.go @@ -411,8 +411,7 @@ func (s *JobGetPublicTestSuite) TestGetJobByIDHTTP() { name string jobID string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid uuid with changed field", @@ -430,11 +429,11 @@ func (s *JobGetPublicTestSuite) TestGetJobByIDHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{ - `"id":"550e8400-e29b-41d4-a716-446655440000"`, - `"status":"completed"`, - `"changed":true`, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"id":"550e8400-e29b-41d4-a716-446655440000"`) + s.Contains(rec.Body.String(), `"status":"completed"`) + s.Contains(rec.Body.String(), `"changed":true`) }, }, { @@ -443,8 +442,11 @@ func (s *JobGetPublicTestSuite) TestGetJobByIDHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"message"`, "Invalid format for parameter id"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"message"`) + s.Contains(rec.Body.String(), "Invalid format for parameter id") + }, }, { name: "when job has timeline events", @@ -475,13 +477,13 @@ func (s *JobGetPublicTestSuite) TestGetJobByIDHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{ - `"timeline"`, - `"submitted"`, - `"failed"`, - `"Job submitted to queue"`, - `"timeout"`, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"timeline"`) + s.Contains(rec.Body.String(), `"submitted"`) + s.Contains(rec.Body.String(), `"failed"`) + s.Contains(rec.Body.String(), `"Job submitted to queue"`) + s.Contains(rec.Body.String(), `"timeout"`) }, }, } @@ -505,10 +507,7 @@ func (s *JobGetPublicTestSuite) TestGetJobByIDHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -522,8 +521,7 @@ func (s *JobGetPublicTestSuite) TestGetJobByIDRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -533,8 +531,10 @@ func (s *JobGetPublicTestSuite) TestGetJobByIDRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -551,8 +551,10 @@ func (s *JobGetPublicTestSuite) TestGetJobByIDRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with job:read returns 200", @@ -577,8 +579,10 @@ func (s *JobGetPublicTestSuite) TestGetJobByIDRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"id":"550e8400-e29b-41d4-a716-446655440000"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"id":"550e8400-e29b-41d4-a716-446655440000"`) + }, }, } @@ -615,14 +619,13 @@ func (s *JobGetPublicTestSuite) TestGetJobByIDRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestJobGetPublicTestSuite(t *testing.T) { +func TestJobGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(JobGetPublicTestSuite)) } diff --git a/internal/controller/api/job/job_list_public_test.go b/internal/controller/api/job/job_list_public_test.go index 670d006df..553876cc2 100644 --- a/internal/controller/api/job/job_list_public_test.go +++ b/internal/controller/api/job/job_list_public_test.go @@ -307,8 +307,7 @@ func (s *JobListPublicTestSuite) TestListJobsValidationHTTP() { name string query string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request without filter", @@ -325,8 +324,10 @@ func (s *JobListPublicTestSuite) TestListJobsValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"total_items":1`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"total_items":1`) + }, }, { name: "when valid status filter", @@ -341,8 +342,10 @@ func (s *JobListPublicTestSuite) TestListJobsValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"total_items":0`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"total_items":0`) + }, }, { name: "when invalid status filter", @@ -350,8 +353,11 @@ func (s *JobListPublicTestSuite) TestListJobsValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "'oneof'"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "'oneof'") + }, }, { name: "when negative limit returns 400", @@ -359,8 +365,10 @@ func (s *JobListPublicTestSuite) TestListJobsValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when negative offset returns 400", @@ -368,8 +376,10 @@ func (s *JobListPublicTestSuite) TestListJobsValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when limit=0 returns 400", @@ -377,8 +387,10 @@ func (s *JobListPublicTestSuite) TestListJobsValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when limit exceeds max returns 400", @@ -386,8 +398,10 @@ func (s *JobListPublicTestSuite) TestListJobsValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when valid limit and offset", @@ -402,8 +416,10 @@ func (s *JobListPublicTestSuite) TestListJobsValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"total_items":50`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"total_items":50`) + }, }, } @@ -426,10 +442,7 @@ func (s *JobListPublicTestSuite) TestListJobsValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -443,8 +456,7 @@ func (s *JobListPublicTestSuite) TestListJobsRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -454,8 +466,10 @@ func (s *JobListPublicTestSuite) TestListJobsRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -472,8 +486,10 @@ func (s *JobListPublicTestSuite) TestListJobsRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with job:read returns 200", @@ -499,8 +515,10 @@ func (s *JobListPublicTestSuite) TestListJobsRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"total_items":1`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"total_items":1`) + }, }, } @@ -537,14 +555,13 @@ func (s *JobListPublicTestSuite) TestListJobsRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestJobListPublicTestSuite(t *testing.T) { +func TestJobListPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(JobListPublicTestSuite)) } diff --git a/internal/controller/api/job/job_retry_public_test.go b/internal/controller/api/job/job_retry_public_test.go index 88bc98ce4..b4d4b445f 100644 --- a/internal/controller/api/job/job_retry_public_test.go +++ b/internal/controller/api/job/job_retry_public_test.go @@ -214,8 +214,7 @@ func (s *JobRetryPublicTestSuite) TestRetryJobByIDValidationHTTP() { jobID string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request with target", @@ -233,10 +232,10 @@ func (s *JobRetryPublicTestSuite) TestRetryJobByIDValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusCreated, - wantContains: []string{ - `"job_id":"660e8400-e29b-41d4-a716-446655440000"`, - `"status":"created"`, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusCreated, rec.Code) + s.Contains(rec.Body.String(), `"job_id":"660e8400-e29b-41d4-a716-446655440000"`) + s.Contains(rec.Body.String(), `"status":"created"`) }, }, { @@ -255,8 +254,10 @@ func (s *JobRetryPublicTestSuite) TestRetryJobByIDValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusCreated, - wantContains: []string{`"job_id":"770e8400-e29b-41d4-a716-446655440000"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusCreated, rec.Code) + s.Contains(rec.Body.String(), `"job_id":"770e8400-e29b-41d4-a716-446655440000"`) + }, }, { name: "when invalid uuid", @@ -265,8 +266,11 @@ func (s *JobRetryPublicTestSuite) TestRetryJobByIDValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"message"`, "Invalid format for parameter id"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"message"`) + s.Contains(rec.Body.String(), "Invalid format for parameter id") + }, }, { name: "when empty target hostname in body", @@ -275,8 +279,11 @@ func (s *JobRetryPublicTestSuite) TestRetryJobByIDValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "TargetHostname"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "TargetHostname") + }, }, } @@ -300,10 +307,7 @@ func (s *JobRetryPublicTestSuite) TestRetryJobByIDValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -317,8 +321,7 @@ func (s *JobRetryPublicTestSuite) TestRetryJobByIDRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -328,8 +331,10 @@ func (s *JobRetryPublicTestSuite) TestRetryJobByIDRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -346,8 +351,10 @@ func (s *JobRetryPublicTestSuite) TestRetryJobByIDRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with job:write returns 201", @@ -373,8 +380,10 @@ func (s *JobRetryPublicTestSuite) TestRetryJobByIDRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusCreated, - wantContains: []string{`"job_id":"660e8400-e29b-41d4-a716-446655440000"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusCreated, rec.Code) + s.Contains(rec.Body.String(), `"job_id":"660e8400-e29b-41d4-a716-446655440000"`) + }, }, } @@ -412,14 +421,13 @@ func (s *JobRetryPublicTestSuite) TestRetryJobByIDRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestJobRetryPublicTestSuite(t *testing.T) { +func TestJobRetryPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(JobRetryPublicTestSuite)) } diff --git a/internal/controller/api/middleware_audit_public_test.go b/internal/controller/api/middleware_audit_public_test.go index 27cea7af1..720c30c8e 100644 --- a/internal/controller/api/middleware_audit_public_test.go +++ b/internal/controller/api/middleware_audit_public_test.go @@ -182,6 +182,8 @@ func (s *AuditMiddlewarePublicTestSuite) TestAuditMiddleware() { } } -func TestAuditMiddlewarePublicTestSuite(t *testing.T) { +func TestAuditMiddlewarePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AuditMiddlewarePublicTestSuite)) } diff --git a/internal/controller/api/middleware_public_test.go b/internal/controller/api/middleware_public_test.go index fa1d0b83e..244fbeb80 100644 --- a/internal/controller/api/middleware_public_test.go +++ b/internal/controller/api/middleware_public_test.go @@ -75,63 +75,81 @@ func (s *MiddlewarePublicTestSuite) TestScopeMiddleware() { requiredScopes []string customRoles map[string][]string expectedStatus int - expectCalled bool setupContextKey bool + validateFunc func(bool, *httptest.ResponseRecorder) }{ { - name: "no auth header returns 401", - authHeader: "", - requiredScopes: []string{"node:read"}, - expectedStatus: http.StatusUnauthorized, - expectCalled: false, + name: "no auth header returns 401", + authHeader: "", + requiredScopes: []string{"node:read"}, + expectedStatus: http.StatusUnauthorized, + validateFunc: func(called bool, rec *httptest.ResponseRecorder) { + s.False(called) + s.Equal(http.StatusUnauthorized, rec.Code) + }, setupContextKey: true, }, { - name: "non-bearer auth header returns 401", - authHeader: "Basic dXNlcjpwYXNz", - requiredScopes: []string{"node:read"}, - expectedStatus: http.StatusUnauthorized, - expectCalled: false, + name: "non-bearer auth header returns 401", + authHeader: "Basic dXNlcjpwYXNz", + requiredScopes: []string{"node:read"}, + expectedStatus: http.StatusUnauthorized, + validateFunc: func(called bool, rec *httptest.ResponseRecorder) { + s.False(called) + s.Equal(http.StatusUnauthorized, rec.Code) + }, setupContextKey: true, }, { - name: "invalid token returns 401", - authHeader: "Bearer invalid-token-string", - requiredScopes: []string{"node:read"}, - expectedStatus: http.StatusUnauthorized, - expectCalled: false, + name: "invalid token returns 401", + authHeader: "Bearer invalid-token-string", + requiredScopes: []string{"node:read"}, + expectedStatus: http.StatusUnauthorized, + validateFunc: func(called bool, rec *httptest.ResponseRecorder) { + s.False(called) + s.Equal(http.StatusUnauthorized, rec.Code) + }, setupContextKey: true, }, { - name: "admin role has node:read", - authHeader: "", // set dynamically - requiredScopes: []string{"node:read"}, - expectedStatus: http.StatusOK, - expectCalled: true, + name: "admin role has node:read", + authHeader: "", // set dynamically + requiredScopes: []string{"node:read"}, + expectedStatus: http.StatusOK, + validateFunc: func(called bool, _ *httptest.ResponseRecorder) { + s.True(called) + }, setupContextKey: true, }, { - name: "read role has node:read", - authHeader: "", // set dynamically - requiredScopes: []string{"node:read"}, - expectedStatus: http.StatusOK, - expectCalled: true, + name: "read role has node:read", + authHeader: "", // set dynamically + requiredScopes: []string{"node:read"}, + expectedStatus: http.StatusOK, + validateFunc: func(called bool, _ *httptest.ResponseRecorder) { + s.True(called) + }, setupContextKey: true, }, { - name: "read role lacks network:write returns 403", - authHeader: "", // set dynamically - requiredScopes: []string{"network:write"}, - expectedStatus: http.StatusForbidden, - expectCalled: false, + name: "read role lacks network:write returns 403", + authHeader: "", // set dynamically + requiredScopes: []string{"network:write"}, + expectedStatus: http.StatusForbidden, + validateFunc: func(called bool, rec *httptest.ResponseRecorder) { + s.False(called) + s.Equal(http.StatusForbidden, rec.Code) + }, setupContextKey: true, }, { - name: "valid token with no required scopes calls handler", - authHeader: "", // set dynamically - requiredScopes: nil, - expectedStatus: http.StatusOK, - expectCalled: true, + name: "valid token with no required scopes calls handler", + authHeader: "", // set dynamically + requiredScopes: nil, + expectedStatus: http.StatusOK, + validateFunc: func(called bool, _ *httptest.ResponseRecorder) { + s.True(called) + }, setupContextKey: false, }, } @@ -177,10 +195,7 @@ func (s *MiddlewarePublicTestSuite) TestScopeMiddleware() { ) _, _ = wrapped(ctx, nil) - s.Equal(tt.expectCalled, handlerCalled) - if !tt.expectCalled { - s.Equal(tt.expectedStatus, rec.Code) - } + tt.validateFunc(handlerCalled, rec) }) } } @@ -194,7 +209,7 @@ func (s *MiddlewarePublicTestSuite) TestScopeMiddlewareCustomRoles() { customRoles map[string][]string requiredScope string expectedStatus int - expectCalled bool + validateFunc func(bool, *httptest.ResponseRecorder) }{ { name: "custom role grants access", @@ -204,7 +219,9 @@ func (s *MiddlewarePublicTestSuite) TestScopeMiddlewareCustomRoles() { }, requiredScope: "node:read", expectedStatus: http.StatusOK, - expectCalled: true, + validateFunc: func(called bool, _ *httptest.ResponseRecorder) { + s.True(called) + }, }, { name: "custom role lacks permission", @@ -214,7 +231,10 @@ func (s *MiddlewarePublicTestSuite) TestScopeMiddlewareCustomRoles() { }, requiredScope: "node:read", expectedStatus: http.StatusForbidden, - expectCalled: false, + validateFunc: func(called bool, rec *httptest.ResponseRecorder) { + s.False(called) + s.Equal(http.StatusForbidden, rec.Code) + }, }, } @@ -258,10 +278,7 @@ func (s *MiddlewarePublicTestSuite) TestScopeMiddlewareCustomRoles() { ) _, _ = wrapped(ctx, nil) - s.Equal(tt.expectCalled, handlerCalled) - if !tt.expectCalled { - s.Equal(tt.expectedStatus, rec.Code) - } + tt.validateFunc(handlerCalled, rec) }) } } @@ -274,21 +291,26 @@ func (s *MiddlewarePublicTestSuite) TestScopeMiddlewareDirectPermissions() { permissions []string requiredScope string expectedStatus int - expectCalled bool + validateFunc func(bool, *httptest.ResponseRecorder) }{ { name: "direct permission grants access", permissions: []string{"node:read"}, requiredScope: "node:read", expectedStatus: http.StatusOK, - expectCalled: true, + validateFunc: func(called bool, _ *httptest.ResponseRecorder) { + s.True(called) + }, }, { name: "direct permission restricts to only listed", permissions: []string{"health:read"}, requiredScope: "node:read", expectedStatus: http.StatusForbidden, - expectCalled: false, + validateFunc: func(called bool, rec *httptest.ResponseRecorder) { + s.False(called) + s.Equal(http.StatusForbidden, rec.Code) + }, }, } @@ -321,10 +343,7 @@ func (s *MiddlewarePublicTestSuite) TestScopeMiddlewareDirectPermissions() { ) _, _ = wrapped(ctx, nil) - s.Equal(tt.expectCalled, handlerCalled) - if !tt.expectCalled { - s.Equal(tt.expectedStatus, rec.Code) - } + tt.validateFunc(handlerCalled, rec) }) } } @@ -333,35 +352,39 @@ func (s *MiddlewarePublicTestSuite) TestScopeMiddlewareInjectsIdentity() { contextKey := "BearerAuthScopes" tests := []struct { - name string - tokenRoles []string - authHeader string - requiredScopes []string - expectCalled bool - expectedSubject string - expectedRoles []string + name string + tokenRoles []string + authHeader string + requiredScopes []string + validateFunc func(bool, string, []string) }{ { - name: "admin token injects subject and roles", - tokenRoles: []string{"admin"}, - requiredScopes: []string{"node:read"}, - expectCalled: true, - expectedSubject: "test-subject", - expectedRoles: []string{"admin"}, + name: "admin token injects subject and roles", + tokenRoles: []string{"admin"}, + requiredScopes: []string{"node:read"}, + validateFunc: func(called bool, subject string, roles []string) { + s.True(called) + s.Equal("test-subject", subject) + s.Equal([]string{"admin"}, roles) + }, }, { - name: "read token injects subject and read role", - tokenRoles: []string{"read"}, - requiredScopes: []string{"node:read"}, - expectCalled: true, - expectedSubject: "test-subject", - expectedRoles: []string{"read"}, + name: "read token injects subject and read role", + tokenRoles: []string{"read"}, + requiredScopes: []string{"node:read"}, + validateFunc: func(called bool, subject string, roles []string) { + s.True(called) + s.Equal("test-subject", subject) + s.Equal([]string{"read"}, roles) + }, }, { name: "invalid token does not inject identity", authHeader: "Bearer invalid-token-string", requiredScopes: []string{"node:read"}, - expectCalled: false, + validateFunc: func(called bool, _ string, _ []string) { + s.False(called) + }, }, } @@ -406,15 +429,13 @@ func (s *MiddlewarePublicTestSuite) TestScopeMiddlewareInjectsIdentity() { ) _, _ = wrapped(ctx, nil) - s.Equal(tt.expectCalled, handlerCalled) - if tt.expectCalled { - s.Equal(tt.expectedSubject, capturedSubject) - s.Equal(tt.expectedRoles, capturedRoles) - } + tt.validateFunc(handlerCalled, capturedSubject, capturedRoles) }) } } -func TestMiddlewarePublicTestSuite(t *testing.T) { +func TestMiddlewarePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(MiddlewarePublicTestSuite)) } diff --git a/internal/controller/api/node/certificate/ca_create_post_public_test.go b/internal/controller/api/node/certificate/ca_create_post_public_test.go index 36af0aeac..ce9ea3d10 100644 --- a/internal/controller/api/node/certificate/ca_create_post_public_test.go +++ b/internal/controller/api/node/certificate/ca_create_post_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -108,7 +110,7 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCa() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, nil, @@ -148,7 +150,7 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCa() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, nil, @@ -297,13 +299,13 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCa() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, }, nil) @@ -337,7 +339,7 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCa() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, }, nil) @@ -466,8 +468,7 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCaValidationHTTP() path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -482,15 +483,18 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCaValidationHTTP() &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when missing name", @@ -499,8 +503,12 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCaValidationHTTP() setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Name", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Name") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when target agent not found", @@ -509,8 +517,11 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCaValidationHTTP() setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -534,10 +545,7 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCaValidationHTTP() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -551,8 +559,7 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCaRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -562,8 +569,10 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCaRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -580,8 +589,10 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCaRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -604,15 +615,18 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCaRBACHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -652,14 +666,13 @@ func (s *CACreatePostPublicTestSuite) TestPostNodeCertificateCaRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestCACreatePostPublicTestSuite(t *testing.T) { +func TestCACreatePostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CACreatePostPublicTestSuite)) } diff --git a/internal/controller/api/node/certificate/ca_delete_public_test.go b/internal/controller/api/node/certificate/ca_delete_public_test.go index b637218ea..3d170cef8 100644 --- a/internal/controller/api/node/certificate/ca_delete_public_test.go +++ b/internal/controller/api/node/certificate/ca_delete_public_test.go @@ -30,6 +30,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -104,7 +106,7 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCa() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, nil, @@ -141,7 +143,7 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCa() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, nil, @@ -247,13 +249,13 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCa() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, }, nil) @@ -284,7 +286,7 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCa() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, }, nil) @@ -316,7 +318,7 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCa() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, "server2": { @@ -406,8 +408,7 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCaValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -421,15 +422,18 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCaValidationHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -437,8 +441,11 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCaValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -457,10 +464,7 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCaValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -474,8 +478,7 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCaRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -485,8 +488,10 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCaRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -503,8 +508,10 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCaRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -527,15 +534,18 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCaRBACHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -572,14 +582,13 @@ func (s *CADeletePublicTestSuite) TestDeleteNodeCertificateCaRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestCADeletePublicTestSuite(t *testing.T) { +func TestCADeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CADeletePublicTestSuite)) } diff --git a/internal/controller/api/node/certificate/ca_list_get_public_test.go b/internal/controller/api/node/certificate/ca_list_get_public_test.go index b26256c77..1ec89c0a5 100644 --- a/internal/controller/api/node/certificate/ca_list_get_public_test.go +++ b/internal/controller/api/node/certificate/ca_list_get_public_test.go @@ -393,8 +393,7 @@ func (s *CAListGetPublicTestSuite) TestGetNodeCertificateCaValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -409,8 +408,11 @@ func (s *CAListGetPublicTestSuite) TestGetNodeCertificateCaValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -418,8 +420,11 @@ func (s *CAListGetPublicTestSuite) TestGetNodeCertificateCaValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -438,10 +443,7 @@ func (s *CAListGetPublicTestSuite) TestGetNodeCertificateCaValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -455,8 +457,7 @@ func (s *CAListGetPublicTestSuite) TestGetNodeCertificateCaRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -466,8 +467,10 @@ func (s *CAListGetPublicTestSuite) TestGetNodeCertificateCaRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -484,8 +487,10 @@ func (s *CAListGetPublicTestSuite) TestGetNodeCertificateCaRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -509,8 +514,11 @@ func (s *CAListGetPublicTestSuite) TestGetNodeCertificateCaRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -547,14 +555,13 @@ func (s *CAListGetPublicTestSuite) TestGetNodeCertificateCaRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestCAListGetPublicTestSuite(t *testing.T) { +func TestCAListGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CAListGetPublicTestSuite)) } diff --git a/internal/controller/api/node/certificate/ca_update_put_public_test.go b/internal/controller/api/node/certificate/ca_update_put_public_test.go index c4710d359..a3de57080 100644 --- a/internal/controller/api/node/certificate/ca_update_put_public_test.go +++ b/internal/controller/api/node/certificate/ca_update_put_public_test.go @@ -32,6 +32,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -109,7 +111,7 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCa() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, nil, @@ -149,7 +151,7 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCa() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, nil, @@ -336,13 +338,13 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCa() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, }, nil) @@ -376,7 +378,7 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCa() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, }, nil) @@ -505,8 +507,7 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCaValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -521,15 +522,18 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCaValidationHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when missing object", @@ -538,8 +542,12 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCaValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Object", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Object") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when target agent not found", @@ -548,8 +556,11 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCaValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -573,10 +584,7 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCaValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -590,8 +598,7 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCaRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -601,8 +608,10 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCaRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -619,8 +628,10 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCaRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -643,15 +654,18 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCaRBACHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-ca","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -689,14 +703,13 @@ func (s *CAUpdatePutPublicTestSuite) TestPutNodeCertificateCaRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestCAUpdatePutPublicTestSuite(t *testing.T) { +func TestCAUpdatePutPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CAUpdatePutPublicTestSuite)) } diff --git a/internal/controller/api/node/certificate/handler_public_test.go b/internal/controller/api/node/certificate/handler_public_test.go index b755c085d..0f0f2cb47 100644 --- a/internal/controller/api/node/certificate/handler_public_test.go +++ b/internal/controller/api/node/certificate/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/certificate/support_public_test.go b/internal/controller/api/node/certificate/support_public_test.go deleted file mode 100644 index 1d2d98257..000000000 --- a/internal/controller/api/node/certificate/support_public_test.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2026 John Dewey - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -package certificate_test - -func boolPtr( - b bool, -) *bool { - return &b -} diff --git a/internal/controller/api/node/command/exec_post_public_test.go b/internal/controller/api/node/command/exec_post_public_test.go index 2796999be..a11c08091 100644 --- a/internal/controller/api/node/command/exec_post_public_test.go +++ b/internal/controller/api/node/command/exec_post_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -79,18 +81,6 @@ func (s *CommandExecPostPublicTestSuite) TearDownTest() { s.mockCtrl.Finish() } -func intPtr( - i int, -) *int { - return &i -} - -func strPtr( - s string, -) *string { - return &s -} - func (s *CommandExecPostPublicTestSuite) TestPostNodeCommandExec() { tests := []struct { name string @@ -105,7 +95,7 @@ func (s *CommandExecPostPublicTestSuite) TestPostNodeCommandExec() { Body: &gen.PostNodeCommandExecJSONRequestBody{ Command: "ls", Args: &[]string{"-la"}, - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -153,8 +143,8 @@ func (s *CommandExecPostPublicTestSuite) TestPostNodeCommandExec() { Body: &gen.PostNodeCommandExecJSONRequestBody{ Command: "ls", Args: &[]string{"-la"}, - Cwd: strPtr("/tmp"), - Timeout: intPtr(30), + Cwd: ptr.To("/tmp"), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -225,7 +215,7 @@ func (s *CommandExecPostPublicTestSuite) TestPostNodeCommandExec() { Body: &gen.PostNodeCommandExecJSONRequestBody{ Command: "ls", Args: &[]string{"-la"}, - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -251,7 +241,7 @@ func (s *CommandExecPostPublicTestSuite) TestPostNodeCommandExec() { Body: &gen.PostNodeCommandExecJSONRequestBody{ Command: "ls", Args: &[]string{"-la"}, - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -286,7 +276,7 @@ func (s *CommandExecPostPublicTestSuite) TestPostNodeCommandExec() { Body: &gen.PostNodeCommandExecJSONRequestBody{ Command: "ls", Args: &[]string{"-la"}, - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -320,7 +310,7 @@ func (s *CommandExecPostPublicTestSuite) TestPostNodeCommandExec() { Body: &gen.PostNodeCommandExecJSONRequestBody{ Command: "ls", Args: &[]string{"-la"}, - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -368,7 +358,7 @@ func (s *CommandExecPostPublicTestSuite) TestPostNodeCommandExec() { Body: &gen.PostNodeCommandExecJSONRequestBody{ Command: "ls", Args: &[]string{"-la"}, - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -409,7 +399,7 @@ func (s *CommandExecPostPublicTestSuite) TestPostNodeCommandExec() { Body: &gen.PostNodeCommandExecJSONRequestBody{ Command: "ls", Args: &[]string{"-la"}, - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -450,7 +440,7 @@ func (s *CommandExecPostPublicTestSuite) TestPostNodeCommandExec() { Body: &gen.PostNodeCommandExecJSONRequestBody{ Command: "ls", Args: &[]string{"-la"}, - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -488,8 +478,7 @@ func (s *CommandExecPostPublicTestSuite) TestPostCommandExecValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -512,8 +501,12 @@ func (s *CommandExecPostPublicTestSuite) TestPostCommandExecValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"results"`, `"agent1"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"agent1"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, { name: "when missing command", @@ -522,8 +515,12 @@ func (s *CommandExecPostPublicTestSuite) TestPostCommandExecValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Command", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Command") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when invalid timeout", @@ -532,8 +529,12 @@ func (s *CommandExecPostPublicTestSuite) TestPostCommandExecValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Timeout", "max"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Timeout") + s.Contains(rec.Body.String(), "max") + }, }, { name: "when target agent not found", @@ -542,8 +543,12 @@ func (s *CommandExecPostPublicTestSuite) TestPostCommandExecValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -567,10 +572,7 @@ func (s *CommandExecPostPublicTestSuite) TestPostCommandExecValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -584,8 +586,7 @@ func (s *CommandExecPostPublicTestSuite) TestPostCommandExecRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -595,8 +596,10 @@ func (s *CommandExecPostPublicTestSuite) TestPostCommandExecRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -613,8 +616,10 @@ func (s *CommandExecPostPublicTestSuite) TestPostCommandExecRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with command:execute returns 202", @@ -649,8 +654,11 @@ func (s *CommandExecPostPublicTestSuite) TestPostCommandExecRBACHTTP() { ) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"results"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, } @@ -688,14 +696,13 @@ func (s *CommandExecPostPublicTestSuite) TestPostCommandExecRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestCommandExecPostPublicTestSuite(t *testing.T) { +func TestCommandExecPostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CommandExecPostPublicTestSuite)) } diff --git a/internal/controller/api/node/command/handler_public_test.go b/internal/controller/api/node/command/handler_public_test.go index 8f96270e0..b153fc4ca 100644 --- a/internal/controller/api/node/command/handler_public_test.go +++ b/internal/controller/api/node/command/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/command/shell_post_public_test.go b/internal/controller/api/node/command/shell_post_public_test.go index 02a4e36f6..01f221361 100644 --- a/internal/controller/api/node/command/shell_post_public_test.go +++ b/internal/controller/api/node/command/shell_post_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -92,7 +94,7 @@ func (s *CommandShellPostPublicTestSuite) TestPostNodeCommandShell() { Hostname: "_any", Body: &gen.PostNodeCommandShellJSONRequestBody{ Command: "echo hello", - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -139,8 +141,8 @@ func (s *CommandShellPostPublicTestSuite) TestPostNodeCommandShell() { Hostname: "_any", Body: &gen.PostNodeCommandShellJSONRequestBody{ Command: "echo hello", - Cwd: strPtr("/tmp"), - Timeout: intPtr(30), + Cwd: ptr.To("/tmp"), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -210,7 +212,7 @@ func (s *CommandShellPostPublicTestSuite) TestPostNodeCommandShell() { Hostname: "_any", Body: &gen.PostNodeCommandShellJSONRequestBody{ Command: "echo hello", - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -235,7 +237,7 @@ func (s *CommandShellPostPublicTestSuite) TestPostNodeCommandShell() { Hostname: "server1", Body: &gen.PostNodeCommandShellJSONRequestBody{ Command: "echo hello", - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -269,7 +271,7 @@ func (s *CommandShellPostPublicTestSuite) TestPostNodeCommandShell() { Hostname: "_all", Body: &gen.PostNodeCommandShellJSONRequestBody{ Command: "echo hello", - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -302,7 +304,7 @@ func (s *CommandShellPostPublicTestSuite) TestPostNodeCommandShell() { Hostname: "_all", Body: &gen.PostNodeCommandShellJSONRequestBody{ Command: "echo hello", - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -349,7 +351,7 @@ func (s *CommandShellPostPublicTestSuite) TestPostNodeCommandShell() { Hostname: "_all", Body: &gen.PostNodeCommandShellJSONRequestBody{ Command: "echo hello", - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -389,7 +391,7 @@ func (s *CommandShellPostPublicTestSuite) TestPostNodeCommandShell() { Hostname: "_all", Body: &gen.PostNodeCommandShellJSONRequestBody{ Command: "echo hello", - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -429,7 +431,7 @@ func (s *CommandShellPostPublicTestSuite) TestPostNodeCommandShell() { Hostname: "_all", Body: &gen.PostNodeCommandShellJSONRequestBody{ Command: "echo hello", - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -467,8 +469,7 @@ func (s *CommandShellPostPublicTestSuite) TestPostCommandShellValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -491,8 +492,12 @@ func (s *CommandShellPostPublicTestSuite) TestPostCommandShellValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"results"`, `"agent1"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"agent1"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, { name: "when missing command", @@ -501,8 +506,12 @@ func (s *CommandShellPostPublicTestSuite) TestPostCommandShellValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Command", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Command") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when invalid timeout", @@ -511,8 +520,12 @@ func (s *CommandShellPostPublicTestSuite) TestPostCommandShellValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Timeout", "max"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Timeout") + s.Contains(rec.Body.String(), "max") + }, }, { name: "when target agent not found", @@ -521,8 +534,12 @@ func (s *CommandShellPostPublicTestSuite) TestPostCommandShellValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -546,10 +563,7 @@ func (s *CommandShellPostPublicTestSuite) TestPostCommandShellValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -563,8 +577,7 @@ func (s *CommandShellPostPublicTestSuite) TestPostCommandShellRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -574,8 +587,10 @@ func (s *CommandShellPostPublicTestSuite) TestPostCommandShellRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -592,8 +607,10 @@ func (s *CommandShellPostPublicTestSuite) TestPostCommandShellRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with command:execute returns 202", @@ -628,8 +645,11 @@ func (s *CommandShellPostPublicTestSuite) TestPostCommandShellRBACHTTP() { ) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"results"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, } @@ -667,14 +687,13 @@ func (s *CommandShellPostPublicTestSuite) TestPostCommandShellRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestCommandShellPostPublicTestSuite(t *testing.T) { +func TestCommandShellPostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CommandShellPostPublicTestSuite)) } diff --git a/internal/controller/api/node/docker/container_create_public_test.go b/internal/controller/api/node/docker/container_create_public_test.go index 785b3547c..ab3e2edf4 100644 --- a/internal/controller/api/node/docker/container_create_public_test.go +++ b/internal/controller/api/node/docker/container_create_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -91,7 +93,7 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDocker() { Hostname: "server1", Body: &gen.PostNodeContainerDockerJSONRequestBody{ Image: "nginx:latest", - Name: strPtr("my-nginx"), + Name: ptr.To("my-nginx"), }, }, setupMock: func() { @@ -106,7 +108,7 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDocker() { Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"id":"abc123"}`), }, nil) }, @@ -158,7 +160,7 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDocker() { Hostname: "server1", Body: &gen.PostNodeContainerDockerJSONRequestBody{ Image: "nginx:latest", - Hostname: strPtr("web-01"), + Hostname: ptr.To("web-01"), Dns: &[]string{"8.8.8.8", "8.8.4.4"}, }, }, @@ -185,7 +187,7 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDocker() { return "550e8400-e29b-41d4-a716-446655440000", &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"id":"abc123"}`), }, nil }) @@ -205,7 +207,7 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDocker() { Hostname: "server1", Body: &gen.PostNodeContainerDockerJSONRequestBody{ Image: "nginx:latest", - AutoStart: boolPtr(false), + AutoStart: ptr.To(false), }, }, setupMock: func() { @@ -220,7 +222,7 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDocker() { Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"id":"xyz789"}`), }, nil) }, @@ -255,7 +257,7 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDocker() { Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, nil) }, @@ -346,13 +348,13 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDocker() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"id":"abc123"}`), }, "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"id":"def456"}`), }, }, nil) @@ -385,7 +387,7 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDocker() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"id":"abc123"}`), }, "server2": { @@ -480,8 +482,7 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDockerValidationHT path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -494,13 +495,17 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDockerValidationHT Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"id":"abc123"}`), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`, `"agent1"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"agent1"`) + }, }, { name: "when missing image", @@ -509,8 +514,12 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDockerValidationHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Image", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Image") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when hostname exceeds max length", @@ -519,8 +528,12 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDockerValidationHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Hostname", "max"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Hostname") + s.Contains(rec.Body.String(), "max") + }, }, { name: "when dns contains invalid ip", @@ -529,8 +542,12 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDockerValidationHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Dns", "ip"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Dns") + s.Contains(rec.Body.String(), "ip") + }, }, { name: "when target agent not found", @@ -539,8 +556,12 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDockerValidationHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -564,10 +585,7 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDockerValidationHT a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -581,8 +599,7 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDockerRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -592,8 +609,10 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDockerRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -610,8 +629,10 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDockerRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 202", @@ -632,13 +653,16 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDockerRBACHTTP() { Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"id":"abc123"}`), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -676,14 +700,13 @@ func (s *ContainerCreatePublicTestSuite) TestPostNodeContainerDockerRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestContainerCreatePublicTestSuite(t *testing.T) { +func TestContainerCreatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ContainerCreatePublicTestSuite)) } diff --git a/internal/controller/api/node/docker/container_exec_public_test.go b/internal/controller/api/node/docker/container_exec_public_test.go index ef9dc1336..508d56239 100644 --- a/internal/controller/api/node/docker/container_exec_public_test.go +++ b/internal/controller/api/node/docker/container_exec_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -105,7 +107,7 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExec() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"stdout":"file1\nfile2","stderr":"","exit_code":0}`, ), @@ -180,7 +182,7 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExec() { Id: "abc123", Body: &gen.PostNodeContainerDockerExecJSONRequestBody{ Command: []string{"ls", "-la"}, - WorkingDir: strPtr("/app"), + WorkingDir: ptr.To("/app"), }, }, setupMock: func() { @@ -194,7 +196,7 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExec() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"stdout":"app files","stderr":"","exit_code":0}`, ), @@ -233,7 +235,7 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExec() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, nil) }, @@ -332,7 +334,7 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExec() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"stdout":"file1\n","stderr":"","exit_code":0}`, ), @@ -340,7 +342,7 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExec() { "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"stdout":"file2\n","stderr":"","exit_code":0}`, ), @@ -376,7 +378,7 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExec() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"stdout":"file1\n","stderr":"","exit_code":0}`, ), @@ -475,8 +477,7 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExecValidation path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -488,13 +489,17 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExecValidation Modify(gomock.Any(), "server1", "docker", job.OperationDockerExec, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"stdout":"output","stderr":"","exit_code":0}`), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`, `"stdout"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"stdout"`) + }, }, { name: "when missing command", @@ -503,8 +508,12 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExecValidation setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Command", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Command") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when target agent not found", @@ -513,8 +522,12 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExecValidation setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -538,10 +551,7 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExecValidation a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -555,8 +565,7 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExecRBACHTTP() name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -566,8 +575,10 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExecRBACHTTP() setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -584,8 +595,10 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExecRBACHTTP() setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 202", @@ -605,13 +618,16 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExecRBACHTTP() Modify(gomock.Any(), "server1", "docker", job.OperationDockerExec, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"stdout":"output","stderr":"","exit_code":0}`), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -649,14 +665,13 @@ func (s *ContainerExecPublicTestSuite) TestPostNodeContainerDockerExecRBACHTTP() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestContainerExecPublicTestSuite(t *testing.T) { +func TestContainerExecPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ContainerExecPublicTestSuite)) } diff --git a/internal/controller/api/node/docker/container_image_remove_public_test.go b/internal/controller/api/node/docker/container_image_remove_public_test.go index 9c1a5a16a..d40da0bbb 100644 --- a/internal/controller/api/node/docker/container_image_remove_public_test.go +++ b/internal/controller/api/node/docker/container_image_remove_public_test.go @@ -29,6 +29,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -103,7 +105,7 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) }, validateFunc: func(resp gen.DeleteNodeContainerDockerImageResponseObject) { @@ -139,7 +141,7 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) }, validateFunc: func(resp gen.DeleteNodeContainerDockerImageResponseObject) { @@ -276,12 +278,12 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), }, }, nil) }, @@ -312,7 +314,7 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, "server2": { Status: job.StatusFailed, @@ -403,8 +405,7 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -415,12 +416,16 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage Modify(gomock.Any(), "server1", "docker", job.OperationDockerImageRemove, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`, `"image removed"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"image removed"`) + }, }, { name: "when empty image returns 400", @@ -428,7 +433,9 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusNotFound, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusNotFound, rec.Code) + }, }, { name: "when target agent not found", @@ -436,8 +443,12 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -460,10 +471,7 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -477,8 +485,7 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -488,8 +495,10 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -506,8 +515,10 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 202", @@ -527,12 +538,15 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage Modify(gomock.Any(), "server1", "docker", job.OperationDockerImageRemove, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -569,14 +583,13 @@ func (s *ContainerImageRemovePublicTestSuite) TestDeleteNodeContainerDockerImage server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestContainerImageRemovePublicTestSuite(t *testing.T) { +func TestContainerImageRemovePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ContainerImageRemovePublicTestSuite)) } diff --git a/internal/controller/api/node/docker/container_inspect_public_test.go b/internal/controller/api/node/docker/container_inspect_public_test.go index 4d6777563..081726c20 100644 --- a/internal/controller/api/node/docker/container_inspect_public_test.go +++ b/internal/controller/api/node/docker/container_inspect_public_test.go @@ -353,8 +353,7 @@ func (s *ContainerInspectPublicTestSuite) TestGetNodeContainerDockerByIDValidati name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -372,8 +371,12 @@ func (s *ContainerInspectPublicTestSuite) TestGetNodeContainerDockerByIDValidati }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`, `"abc123"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"abc123"`) + }, }, { name: "when target agent not found", @@ -381,8 +384,12 @@ func (s *ContainerInspectPublicTestSuite) TestGetNodeContainerDockerByIDValidati setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -401,10 +408,7 @@ func (s *ContainerInspectPublicTestSuite) TestGetNodeContainerDockerByIDValidati a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -418,8 +422,7 @@ func (s *ContainerInspectPublicTestSuite) TestGetNodeContainerDockerByIDRBACHTTP name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -429,8 +432,10 @@ func (s *ContainerInspectPublicTestSuite) TestGetNodeContainerDockerByIDRBACHTTP setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -447,8 +452,10 @@ func (s *ContainerInspectPublicTestSuite) TestGetNodeContainerDockerByIDRBACHTTP setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -475,8 +482,11 @@ func (s *ContainerInspectPublicTestSuite) TestGetNodeContainerDockerByIDRBACHTTP }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -513,14 +523,13 @@ func (s *ContainerInspectPublicTestSuite) TestGetNodeContainerDockerByIDRBACHTTP server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestContainerInspectPublicTestSuite(t *testing.T) { +func TestContainerInspectPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ContainerInspectPublicTestSuite)) } diff --git a/internal/controller/api/node/docker/container_list_public_test.go b/internal/controller/api/node/docker/container_list_public_test.go index 08b7816cb..0fea9c402 100644 --- a/internal/controller/api/node/docker/container_list_public_test.go +++ b/internal/controller/api/node/docker/container_list_public_test.go @@ -30,6 +30,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -142,7 +144,7 @@ func (s *ContainerListPublicTestSuite) TestGetNodeContainerDocker() { request: gen.GetNodeContainerDockerRequestObject{ Hostname: "server1", Params: gen.GetNodeContainerDockerParams{ - Limit: intPtr(0), + Limit: ptr.To(0), }, }, setupMock: func() {}, @@ -159,7 +161,7 @@ func (s *ContainerListPublicTestSuite) TestGetNodeContainerDocker() { Hostname: "server1", Params: gen.GetNodeContainerDockerParams{ State: &stateAll, - Limit: intPtr(5), + Limit: ptr.To(5), }, }, setupMock: func() { @@ -461,8 +463,7 @@ func (s *ContainerListPublicTestSuite) TestGetNodeContainerDockerValidationHTTP( name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -478,8 +479,11 @@ func (s *ContainerListPublicTestSuite) TestGetNodeContainerDockerValidationHTTP( }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -487,8 +491,12 @@ func (s *ContainerListPublicTestSuite) TestGetNodeContainerDockerValidationHTTP( setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -507,10 +515,7 @@ func (s *ContainerListPublicTestSuite) TestGetNodeContainerDockerValidationHTTP( a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -524,8 +529,7 @@ func (s *ContainerListPublicTestSuite) TestGetNodeContainerDockerRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -535,8 +539,10 @@ func (s *ContainerListPublicTestSuite) TestGetNodeContainerDockerRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -553,8 +559,10 @@ func (s *ContainerListPublicTestSuite) TestGetNodeContainerDockerRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -579,8 +587,11 @@ func (s *ContainerListPublicTestSuite) TestGetNodeContainerDockerRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -617,14 +628,13 @@ func (s *ContainerListPublicTestSuite) TestGetNodeContainerDockerRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestContainerListPublicTestSuite(t *testing.T) { +func TestContainerListPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ContainerListPublicTestSuite)) } diff --git a/internal/controller/api/node/docker/container_pull_public_test.go b/internal/controller/api/node/docker/container_pull_public_test.go index 389730982..33569e9b0 100644 --- a/internal/controller/api/node/docker/container_pull_public_test.go +++ b/internal/controller/api/node/docker/container_pull_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -104,7 +106,7 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPull() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"image_id":"sha256:abc123","tag":"latest","size":12345}`, ), @@ -233,7 +235,7 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPull() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"image_id":"sha256:abc","tag":"latest","size":2048}`, ), @@ -241,7 +243,7 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPull() { "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"image_id":"sha256:def","tag":"latest","size":2048}`, ), @@ -276,7 +278,7 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPull() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"image_id":"sha256:abc","tag":"latest","size":2048}`, ), @@ -373,8 +375,7 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPullValidation path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -386,15 +387,19 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPullValidation Modify(gomock.Any(), "server1", "docker", job.OperationDockerPull, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"image_id":"sha256:abc123","tag":"latest","size":12345}`, ), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`, `"image_id"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"image_id"`) + }, }, { name: "when missing image", @@ -403,8 +408,12 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPullValidation setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Image", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Image") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when target agent not found", @@ -413,8 +422,12 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPullValidation setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -438,10 +451,7 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPullValidation a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -455,8 +465,7 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPullRBACHTTP() name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -466,8 +475,10 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPullRBACHTTP() setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -484,8 +495,10 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPullRBACHTTP() setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 202", @@ -505,15 +518,18 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPullRBACHTTP() Modify(gomock.Any(), "server1", "docker", job.OperationDockerPull, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"image_id":"sha256:abc123","tag":"latest","size":12345}`, ), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -551,14 +567,13 @@ func (s *ContainerPullPublicTestSuite) TestPostNodeContainerDockerPullRBACHTTP() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestContainerPullPublicTestSuite(t *testing.T) { +func TestContainerPullPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ContainerPullPublicTestSuite)) } diff --git a/internal/controller/api/node/docker/container_remove_public_test.go b/internal/controller/api/node/docker/container_remove_public_test.go index f581590f9..a32ca4da8 100644 --- a/internal/controller/api/node/docker/container_remove_public_test.go +++ b/internal/controller/api/node/docker/container_remove_public_test.go @@ -29,6 +29,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -101,7 +103,7 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByID() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) }, validateFunc: func(resp gen.DeleteNodeContainerDockerByIDResponseObject) { @@ -122,7 +124,7 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByID() { request: gen.DeleteNodeContainerDockerByIDRequestObject{ Hostname: "server1", Id: "abc123", - Params: gen.DeleteNodeContainerDockerByIDParams{Force: boolPtr(true)}, + Params: gen.DeleteNodeContainerDockerByIDParams{Force: ptr.To(true)}, }, setupMock: func() { s.mockJobClient.EXPECT(). @@ -135,7 +137,7 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByID() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) }, validateFunc: func(resp gen.DeleteNodeContainerDockerByIDResponseObject) { @@ -247,12 +249,12 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByID() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), }, }, nil) }, @@ -283,7 +285,7 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByID() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, "server2": { Status: job.StatusFailed, @@ -374,8 +376,7 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByIDValida name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -386,12 +387,16 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByIDValida Modify(gomock.Any(), "server1", "docker", job.OperationDockerRemove, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`, `"container removed"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"container removed"`) + }, }, { name: "when target agent not found", @@ -399,8 +404,12 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByIDValida setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -419,10 +428,7 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByIDValida a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -436,8 +442,7 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByIDRBACHT name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -447,8 +452,10 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByIDRBACHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -465,8 +472,10 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByIDRBACHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 202", @@ -486,12 +495,15 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByIDRBACHT Modify(gomock.Any(), "server1", "docker", job.OperationDockerRemove, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -528,14 +540,13 @@ func (s *ContainerRemovePublicTestSuite) TestDeleteNodeContainerDockerByIDRBACHT server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestContainerRemovePublicTestSuite(t *testing.T) { +func TestContainerRemovePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ContainerRemovePublicTestSuite)) } diff --git a/internal/controller/api/node/docker/container_start_public_test.go b/internal/controller/api/node/docker/container_start_public_test.go index 8a19fb62b..33253a9c8 100644 --- a/internal/controller/api/node/docker/container_start_public_test.go +++ b/internal/controller/api/node/docker/container_start_public_test.go @@ -29,6 +29,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -100,7 +102,7 @@ func (s *ContainerStartPublicTestSuite) TestPostNodeContainerDockerStart() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) }, validateFunc: func(resp gen.PostNodeContainerDockerStartResponseObject) { @@ -214,12 +216,12 @@ func (s *ContainerStartPublicTestSuite) TestPostNodeContainerDockerStart() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), }, }, nil) }, @@ -249,7 +251,7 @@ func (s *ContainerStartPublicTestSuite) TestPostNodeContainerDockerStart() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, "server2": { Status: job.StatusFailed, @@ -338,8 +340,7 @@ func (s *ContainerStartPublicTestSuite) TestPostNodeContainerDockerStartValidati name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -350,12 +351,16 @@ func (s *ContainerStartPublicTestSuite) TestPostNodeContainerDockerStartValidati Modify(gomock.Any(), "server1", "docker", job.OperationDockerStart, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`, `"container started"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"container started"`) + }, }, { name: "when target agent not found", @@ -363,8 +368,12 @@ func (s *ContainerStartPublicTestSuite) TestPostNodeContainerDockerStartValidati setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -383,10 +392,7 @@ func (s *ContainerStartPublicTestSuite) TestPostNodeContainerDockerStartValidati a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -400,8 +406,7 @@ func (s *ContainerStartPublicTestSuite) TestPostNodeContainerDockerStartRBACHTTP name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -411,8 +416,10 @@ func (s *ContainerStartPublicTestSuite) TestPostNodeContainerDockerStartRBACHTTP setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -429,8 +436,10 @@ func (s *ContainerStartPublicTestSuite) TestPostNodeContainerDockerStartRBACHTTP setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 202", @@ -450,12 +459,15 @@ func (s *ContainerStartPublicTestSuite) TestPostNodeContainerDockerStartRBACHTTP Modify(gomock.Any(), "server1", "docker", job.OperationDockerStart, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -492,14 +504,13 @@ func (s *ContainerStartPublicTestSuite) TestPostNodeContainerDockerStartRBACHTTP server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestContainerStartPublicTestSuite(t *testing.T) { +func TestContainerStartPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ContainerStartPublicTestSuite)) } diff --git a/internal/controller/api/node/docker/container_stop_public_test.go b/internal/controller/api/node/docker/container_stop_public_test.go index d060bad6b..01d19020a 100644 --- a/internal/controller/api/node/docker/container_stop_public_test.go +++ b/internal/controller/api/node/docker/container_stop_public_test.go @@ -30,6 +30,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -102,7 +104,7 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStop() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) }, validateFunc: func(resp gen.PostNodeContainerDockerStopResponseObject) { @@ -124,7 +126,7 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStop() { Hostname: "server1", Id: "abc123", Body: &gen.PostNodeContainerDockerStopJSONRequestBody{ - Timeout: intPtr(30), + Timeout: ptr.To(30), }, }, setupMock: func() { @@ -138,7 +140,7 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStop() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) }, validateFunc: func(resp gen.PostNodeContainerDockerStopResponseObject) { @@ -154,7 +156,7 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStop() { Hostname: "server1", Id: "abc123", Body: &gen.PostNodeContainerDockerStopJSONRequestBody{ - Timeout: intPtr(999), + Timeout: ptr.To(999), }, }, setupMock: func() {}, @@ -265,12 +267,12 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStop() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), }, }, nil) }, @@ -301,7 +303,7 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStop() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, "server2": { Status: job.StatusFailed, @@ -393,8 +395,7 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStopValidation path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -406,12 +407,16 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStopValidation Modify(gomock.Any(), "server1", "docker", job.OperationDockerStop, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`, `"container stopped"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"container stopped"`) + }, }, { name: "when invalid timeout", @@ -420,8 +425,11 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStopValidation setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Timeout"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Timeout") + }, }, { name: "when target agent not found", @@ -430,8 +438,12 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStopValidation setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -455,10 +467,7 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStopValidation a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -472,8 +481,7 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStopRBACHTTP() name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -483,8 +491,10 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStopRBACHTTP() setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -501,8 +511,10 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStopRBACHTTP() setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 202", @@ -522,12 +534,15 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStopRBACHTTP() Modify(gomock.Any(), "server1", "docker", job.OperationDockerStop, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -565,14 +580,13 @@ func (s *ContainerStopPublicTestSuite) TestPostNodeContainerDockerStopRBACHTTP() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestContainerStopPublicTestSuite(t *testing.T) { +func TestContainerStopPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ContainerStopPublicTestSuite)) } diff --git a/internal/controller/api/node/docker/convert_public_test.go b/internal/controller/api/node/docker/convert_public_test.go index 9dbe8ed1d..ff3b297fc 100644 --- a/internal/controller/api/node/docker/convert_public_test.go +++ b/internal/controller/api/node/docker/convert_public_test.go @@ -397,6 +397,8 @@ func (s *ConvertPublicTestSuite) TestInt64PtrOrNil() { } } -func TestConvertPublicTestSuite(t *testing.T) { +func TestConvertPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ConvertPublicTestSuite)) } diff --git a/internal/controller/api/node/docker/handler_public_test.go b/internal/controller/api/node/docker/handler_public_test.go index 37a73f238..1aa39b98b 100644 --- a/internal/controller/api/node/docker/handler_public_test.go +++ b/internal/controller/api/node/docker/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -90,11 +90,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/docker/support_public_test.go b/internal/controller/api/node/docker/support_public_test.go deleted file mode 100644 index 502b92cac..000000000 --- a/internal/controller/api/node/docker/support_public_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2026 John Dewey - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -package container_test - -func strPtr( - s string, -) *string { - return &s -} - -func intPtr( - i int, -) *int { - return &i -} - -func boolPtr( - b bool, -) *bool { - return &b -} diff --git a/internal/controller/api/node/file/deploy_post_public_test.go b/internal/controller/api/node/file/deploy_post_public_test.go index e655dde60..ddcd5b169 100644 --- a/internal/controller/api/node/file/deploy_post_public_test.go +++ b/internal/controller/api/node/file/deploy_post_public_test.go @@ -30,6 +30,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -94,9 +96,9 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeploy() { ObjectName: "nginx.conf", Path: "/etc/nginx/nginx.conf", ContentType: gen.Raw, - Mode: strPtr("0644"), - Owner: strPtr("root"), - Group: strPtr("root"), + Mode: ptr.To("0644"), + Owner: ptr.To("root"), + Group: ptr.To("root"), }, }, setupMock: func() { @@ -514,8 +516,7 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeployValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -531,8 +532,13 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeployValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"agent1"`, `"changed":true`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"agent1"`) + s.Contains(rec.Body.String(), `"changed":true`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when missing object_name", @@ -541,8 +547,12 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeployValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "ObjectName", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "ObjectName") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when invalid content_type", @@ -551,8 +561,11 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeployValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "ContentType"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "ContentType") + }, }, { name: "when server error", @@ -565,8 +578,10 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeployValidationHTTP() { Return("", nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when target agent not found", @@ -575,8 +590,12 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeployValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -600,10 +619,7 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeployValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -618,8 +634,7 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeployRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -629,8 +644,10 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeployRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -647,8 +664,10 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeployRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with file:write returns 202", @@ -676,8 +695,12 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeployRBACHTTP() { ) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"changed":true`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"changed":true`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -717,14 +740,13 @@ func (s *FileDeployPostPublicTestSuite) TestPostNodeFileDeployRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestFileDeployPostPublicTestSuite(t *testing.T) { +func TestFileDeployPostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FileDeployPostPublicTestSuite)) } diff --git a/internal/controller/api/node/file/handler_public_test.go b/internal/controller/api/node/file/handler_public_test.go index 60277d7a4..ac054e745 100644 --- a/internal/controller/api/node/file/handler_public_test.go +++ b/internal/controller/api/node/file/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/file/status_post_public_test.go b/internal/controller/api/node/file/status_post_public_test.go index 20e8fb94a..da194ef34 100644 --- a/internal/controller/api/node/file/status_post_public_test.go +++ b/internal/controller/api/node/file/status_post_public_test.go @@ -79,7 +79,9 @@ func (s *FileStatusPostPublicTestSuite) TearDownTest() { s.mockCtrl.Finish() } -func marshalStatusResult(r providerFile.StatusResult) json.RawMessage { +func marshalStatusResult( + r providerFile.StatusResult, +) json.RawMessage { b, _ := json.Marshal(r) return b } @@ -477,8 +479,7 @@ func (s *FileStatusPostPublicTestSuite) TestPostNodeFileStatusValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -498,8 +499,14 @@ func (s *FileStatusPostPublicTestSuite) TestPostNodeFileStatusValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"agent1"`, `"in-sync"`, `"sha256"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"agent1"`) + s.Contains(rec.Body.String(), `"in-sync"`) + s.Contains(rec.Body.String(), `"sha256"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when missing path", @@ -508,8 +515,12 @@ func (s *FileStatusPostPublicTestSuite) TestPostNodeFileStatusValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Path", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Path") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when target agent not found", @@ -518,8 +529,12 @@ func (s *FileStatusPostPublicTestSuite) TestPostNodeFileStatusValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -543,10 +558,7 @@ func (s *FileStatusPostPublicTestSuite) TestPostNodeFileStatusValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -560,8 +572,7 @@ func (s *FileStatusPostPublicTestSuite) TestPostNodeFileStatusRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -571,8 +582,10 @@ func (s *FileStatusPostPublicTestSuite) TestPostNodeFileStatusRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -589,8 +602,10 @@ func (s *FileStatusPostPublicTestSuite) TestPostNodeFileStatusRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with file:read returns 200", @@ -622,8 +637,12 @@ func (s *FileStatusPostPublicTestSuite) TestPostNodeFileStatusRBACHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"in-sync"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"in-sync"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -661,14 +680,13 @@ func (s *FileStatusPostPublicTestSuite) TestPostNodeFileStatusRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestFileStatusPostPublicTestSuite(t *testing.T) { +func TestFileStatusPostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FileStatusPostPublicTestSuite)) } diff --git a/internal/controller/api/node/file/support_public_test.go b/internal/controller/api/node/file/support_public_test.go deleted file mode 100644 index c7a711d06..000000000 --- a/internal/controller/api/node/file/support_public_test.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2026 John Dewey - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -package file_test - -func strPtr( - s string, -) *string { - return &s -} diff --git a/internal/controller/api/node/file/undeploy_post_public_test.go b/internal/controller/api/node/file/undeploy_post_public_test.go index f2da19769..55d260edc 100644 --- a/internal/controller/api/node/file/undeploy_post_public_test.go +++ b/internal/controller/api/node/file/undeploy_post_public_test.go @@ -415,8 +415,7 @@ func (s *FileUndeployPostPublicTestSuite) TestPostNodeFileUndeployValidationHTTP path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -432,8 +431,13 @@ func (s *FileUndeployPostPublicTestSuite) TestPostNodeFileUndeployValidationHTTP }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"agent1"`, `"changed":true`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"agent1"`) + s.Contains(rec.Body.String(), `"changed":true`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when missing path", @@ -442,8 +446,12 @@ func (s *FileUndeployPostPublicTestSuite) TestPostNodeFileUndeployValidationHTTP setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Path", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Path") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when server error", @@ -456,8 +464,10 @@ func (s *FileUndeployPostPublicTestSuite) TestPostNodeFileUndeployValidationHTTP Return("", nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when target agent not found", @@ -466,8 +476,12 @@ func (s *FileUndeployPostPublicTestSuite) TestPostNodeFileUndeployValidationHTTP setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -491,10 +505,7 @@ func (s *FileUndeployPostPublicTestSuite) TestPostNodeFileUndeployValidationHTTP a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -509,8 +520,7 @@ func (s *FileUndeployPostPublicTestSuite) TestPostNodeFileUndeployRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -520,8 +530,10 @@ func (s *FileUndeployPostPublicTestSuite) TestPostNodeFileUndeployRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -538,8 +550,10 @@ func (s *FileUndeployPostPublicTestSuite) TestPostNodeFileUndeployRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with file:write returns 202", @@ -567,8 +581,12 @@ func (s *FileUndeployPostPublicTestSuite) TestPostNodeFileUndeployRBACHTTP() { ) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"job_id"`, `"changed":true`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"changed":true`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -606,14 +624,13 @@ func (s *FileUndeployPostPublicTestSuite) TestPostNodeFileUndeployRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestFileUndeployPostPublicTestSuite(t *testing.T) { +func TestFileUndeployPostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FileUndeployPostPublicTestSuite)) } diff --git a/internal/controller/api/node/handler_public_test.go b/internal/controller/api/node/handler_public_test.go index 54e28dbee..98eb814e9 100644 --- a/internal/controller/api/node/handler_public_test.go +++ b/internal/controller/api/node/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/hostname/handler_public_test.go b/internal/controller/api/node/hostname/handler_public_test.go index 96cf97e34..db5540205 100644 --- a/internal/controller/api/node/hostname/handler_public_test.go +++ b/internal/controller/api/node/hostname/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/hostname/hostname_get_public_test.go b/internal/controller/api/node/hostname/hostname_get_public_test.go index 5608782bd..99492e407 100644 --- a/internal/controller/api/node/hostname/hostname_get_public_test.go +++ b/internal/controller/api/node/hostname/hostname_get_public_test.go @@ -317,9 +317,7 @@ func (s *HostnameGetPublicTestSuite) TestGetNodeHostnameValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantBody string - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when empty hostname returns 400", @@ -327,8 +325,12 @@ func (s *HostnameGetPublicTestSuite) TestGetNodeHostnameValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + for _, str := range []string{`"error"`} { + s.Contains(rec.Body.String(), str) + } + }, }, { name: "when get Ok", @@ -346,8 +348,18 @@ func (s *HostnameGetPublicTestSuite) TestGetNodeHostnameValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantBody: `{"job_id":"550e8400-e29b-41d4-a716-446655440000","results":[{"changed":false,"hostname":"default-hostname","status":"ok"}]}`, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + if `{"job_id":"550e8400-e29b-41d4-a716-446655440000","results":[{"changed":false,"hostname":"default-hostname","status":"ok"}]}` != "" { + s.JSONEq( + `{"job_id":"550e8400-e29b-41d4-a716-446655440000","results":[{"changed":false,"hostname":"default-hostname","status":"ok"}]}`, + rec.Body.String(), + ) + } + for _, str := range []string(nil) { + s.Contains(rec.Body.String(), str) + } + }, }, { name: "when job client errors", @@ -359,8 +371,18 @@ func (s *HostnameGetPublicTestSuite) TestGetNodeHostnameValidationHTTP() { Return("", nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, - wantBody: `{"error":"assert.AnError general error for testing"}`, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + if `{"error":"assert.AnError general error for testing"}` != "" { + s.JSONEq( + `{"error":"assert.AnError general error for testing"}`, + rec.Body.String(), + ) + } + for _, str := range []string(nil) { + s.Contains(rec.Body.String(), str) + } + }, }, { name: "when broadcast all", @@ -377,8 +399,12 @@ func (s *HostnameGetPublicTestSuite) TestGetNodeHostnameValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"host1"`, `"host2"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + for _, str := range []string{`"results"`, `"host1"`, `"host2"`} { + s.Contains(rec.Body.String(), str) + } + }, }, } @@ -397,13 +423,7 @@ func (s *HostnameGetPublicTestSuite) TestGetNodeHostnameValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - if tc.wantBody != "" { - s.JSONEq(tc.wantBody, rec.Body.String()) - } - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -417,8 +437,7 @@ func (s *HostnameGetPublicTestSuite) TestGetNodeHostnameRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -428,8 +447,10 @@ func (s *HostnameGetPublicTestSuite) TestGetNodeHostnameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -446,8 +467,10 @@ func (s *HostnameGetPublicTestSuite) TestGetNodeHostnameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with node:read returns 200", @@ -476,8 +499,10 @@ func (s *HostnameGetPublicTestSuite) TestGetNodeHostnameRBACHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"hostname":"test-host"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"hostname":"test-host"`) + }, }, } @@ -510,14 +535,13 @@ func (s *HostnameGetPublicTestSuite) TestGetNodeHostnameRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestHostnameGetPublicTestSuite(t *testing.T) { +func TestHostnameGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HostnameGetPublicTestSuite)) } diff --git a/internal/controller/api/node/hostname/hostname_put_public_test.go b/internal/controller/api/node/hostname/hostname_put_public_test.go index fcfd7bddd..1a4c48a77 100644 --- a/internal/controller/api/node/hostname/hostname_put_public_test.go +++ b/internal/controller/api/node/hostname/hostname_put_public_test.go @@ -414,8 +414,7 @@ func (s *HostnamePutPublicTestSuite) TestPutNodeHostnameHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -431,8 +430,13 @@ func (s *HostnamePutPublicTestSuite) TestPutNodeHostnameHTTP() { }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"results"`, `"agent1"`, `"ok"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"agent1"`) + s.Contains(rec.Body.String(), `"ok"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, { name: "when missing hostname body returns 400", @@ -441,8 +445,12 @@ func (s *HostnamePutPublicTestSuite) TestPutNodeHostnameHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Hostname", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Hostname") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when empty hostname path returns 400", @@ -451,8 +459,10 @@ func (s *HostnamePutPublicTestSuite) TestPutNodeHostnameHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, } @@ -476,10 +486,7 @@ func (s *HostnamePutPublicTestSuite) TestPutNodeHostnameHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -494,8 +501,7 @@ func (s *HostnamePutPublicTestSuite) TestPutNodeHostnameRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -505,8 +511,10 @@ func (s *HostnamePutPublicTestSuite) TestPutNodeHostnameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -523,8 +531,10 @@ func (s *HostnamePutPublicTestSuite) TestPutNodeHostnameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with node:write returns 202", @@ -552,8 +562,11 @@ func (s *HostnamePutPublicTestSuite) TestPutNodeHostnameRBACHTTP() { ) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"results"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, } @@ -591,14 +604,13 @@ func (s *HostnamePutPublicTestSuite) TestPutNodeHostnameRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestHostnamePutPublicTestSuite(t *testing.T) { +func TestHostnamePutPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HostnamePutPublicTestSuite)) } diff --git a/internal/controller/api/node/log/handler_public_test.go b/internal/controller/api/node/log/handler_public_test.go index 5640556a2..e8762183f 100644 --- a/internal/controller/api/node/log/handler_public_test.go +++ b/internal/controller/api/node/log/handler_public_test.go @@ -52,18 +52,18 @@ func (s *LogHandlerPublicTestSuite) TearDownTest() { func (s *LogHandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *LogHandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestLogHandlerPublicTestSuite(t *testing.T) { +func TestLogHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LogHandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/log/log_query_get_public_test.go b/internal/controller/api/node/log/log_query_get_public_test.go index fdbff3e1b..965434104 100644 --- a/internal/controller/api/node/log/log_query_get_public_test.go +++ b/internal/controller/api/node/log/log_query_get_public_test.go @@ -30,6 +30,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -124,7 +126,7 @@ func (s *LogQueryPublicTestSuite) TestGetNodeLog() { request: gen.GetNodeLogRequestObject{ Hostname: "server1", Params: gen.GetNodeLogParams{ - Lines: intPtr(50), + Lines: ptr.To(50), Since: stringPtr("1 hour ago"), Priority: stringPtr("err"), }, @@ -371,8 +373,7 @@ func (s *LogQueryPublicTestSuite) TestGetNodeLogHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -388,8 +389,11 @@ func (s *LogQueryPublicTestSuite) TestGetNodeLogHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -397,8 +401,12 @@ func (s *LogQueryPublicTestSuite) TestGetNodeLogHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, { name: "when invalid priority returns 400", @@ -406,8 +414,11 @@ func (s *LogQueryPublicTestSuite) TestGetNodeLogHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "oneof"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "oneof") + }, }, } @@ -426,10 +437,7 @@ func (s *LogQueryPublicTestSuite) TestGetNodeLogHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -443,8 +451,7 @@ func (s *LogQueryPublicTestSuite) TestGetNodeLogRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -454,8 +461,10 @@ func (s *LogQueryPublicTestSuite) TestGetNodeLogRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -472,8 +481,10 @@ func (s *LogQueryPublicTestSuite) TestGetNodeLogRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with log:read returns 200", @@ -498,8 +509,11 @@ func (s *LogQueryPublicTestSuite) TestGetNodeLogRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -536,17 +550,15 @@ func (s *LogQueryPublicTestSuite) TestGetNodeLogRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func intPtr(i int) *int { return &i } func stringPtr(s string) *string { return &s } -func TestLogQueryPublicTestSuite(t *testing.T) { +func TestLogQueryPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LogQueryPublicTestSuite)) } diff --git a/internal/controller/api/node/log/log_source_get_public_test.go b/internal/controller/api/node/log/log_source_get_public_test.go index 7477dacfe..643ae24b0 100644 --- a/internal/controller/api/node/log/log_source_get_public_test.go +++ b/internal/controller/api/node/log/log_source_get_public_test.go @@ -316,8 +316,7 @@ func (s *LogSourcePublicTestSuite) TestGetNodeLogSourceHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -333,8 +332,11 @@ func (s *LogSourcePublicTestSuite) TestGetNodeLogSourceHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -342,8 +344,12 @@ func (s *LogSourcePublicTestSuite) TestGetNodeLogSourceHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -362,10 +368,7 @@ func (s *LogSourcePublicTestSuite) TestGetNodeLogSourceHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -379,8 +382,7 @@ func (s *LogSourcePublicTestSuite) TestGetNodeLogSourceRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -390,8 +392,10 @@ func (s *LogSourcePublicTestSuite) TestGetNodeLogSourceRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -408,8 +412,10 @@ func (s *LogSourcePublicTestSuite) TestGetNodeLogSourceRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with log:read returns 200", @@ -434,8 +440,11 @@ func (s *LogSourcePublicTestSuite) TestGetNodeLogSourceRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -472,14 +481,13 @@ func (s *LogSourcePublicTestSuite) TestGetNodeLogSourceRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestLogSourcePublicTestSuite(t *testing.T) { +func TestLogSourcePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LogSourcePublicTestSuite)) } diff --git a/internal/controller/api/node/log/log_unit_get_public_test.go b/internal/controller/api/node/log/log_unit_get_public_test.go index a9bec84e6..23118322f 100644 --- a/internal/controller/api/node/log/log_unit_get_public_test.go +++ b/internal/controller/api/node/log/log_unit_get_public_test.go @@ -29,6 +29,8 @@ import ( "net/http/httptest" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -114,7 +116,7 @@ func (s *LogUnitPublicTestSuite) TestGetNodeLogUnit() { Hostname: "server1", Name: "nginx.service", Params: gen.GetNodeLogUnitParams{ - Lines: intPtr(25), + Lines: ptr.To(25), Since: stringPtr("2026-03-31"), Priority: stringPtr("warning"), }, @@ -368,8 +370,7 @@ func (s *LogUnitPublicTestSuite) TestGetNodeLogUnitHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -385,8 +386,11 @@ func (s *LogUnitPublicTestSuite) TestGetNodeLogUnitHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -394,8 +398,12 @@ func (s *LogUnitPublicTestSuite) TestGetNodeLogUnitHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, { name: "when invalid priority returns 400", @@ -403,8 +411,11 @@ func (s *LogUnitPublicTestSuite) TestGetNodeLogUnitHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "oneof"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "oneof") + }, }, } @@ -423,10 +434,7 @@ func (s *LogUnitPublicTestSuite) TestGetNodeLogUnitHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -440,8 +448,7 @@ func (s *LogUnitPublicTestSuite) TestGetNodeLogUnitRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -451,8 +458,10 @@ func (s *LogUnitPublicTestSuite) TestGetNodeLogUnitRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -469,8 +478,10 @@ func (s *LogUnitPublicTestSuite) TestGetNodeLogUnitRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with log:read returns 200", @@ -495,8 +506,11 @@ func (s *LogUnitPublicTestSuite) TestGetNodeLogUnitRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -533,14 +547,13 @@ func (s *LogUnitPublicTestSuite) TestGetNodeLogUnitRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestLogUnitPublicTestSuite(t *testing.T) { +func TestLogUnitPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LogUnitPublicTestSuite)) } diff --git a/internal/controller/api/node/network/dns_delete_public_test.go b/internal/controller/api/node/network/dns_delete_public_test.go index 47f3782f3..19f0eb38d 100644 --- a/internal/controller/api/node/network/dns_delete_public_test.go +++ b/internal/controller/api/node/network/dns_delete_public_test.go @@ -274,8 +274,7 @@ func (s *NetworkDNSDeletePublicTestSuite) TestDeleteNetworkDNSValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -290,8 +289,11 @@ func (s *NetworkDNSDeletePublicTestSuite) TestDeleteNetworkDNSValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"server1"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"server1"`) + }, }, { name: "when missing interface name", @@ -300,8 +302,12 @@ func (s *NetworkDNSDeletePublicTestSuite) TestDeleteNetworkDNSValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "InterfaceName", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "InterfaceName") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when target agent not found", @@ -310,8 +316,11 @@ func (s *NetworkDNSDeletePublicTestSuite) TestDeleteNetworkDNSValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -328,10 +337,7 @@ func (s *NetworkDNSDeletePublicTestSuite) TestDeleteNetworkDNSValidationHTTP() { rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -346,8 +352,7 @@ func (s *NetworkDNSDeletePublicTestSuite) TestDeleteNetworkDNSRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -355,8 +360,10 @@ func (s *NetworkDNSDeletePublicTestSuite) TestDeleteNetworkDNSRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -372,8 +379,10 @@ func (s *NetworkDNSDeletePublicTestSuite) TestDeleteNetworkDNSRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with network:write returns 200", @@ -393,8 +402,11 @@ func (s *NetworkDNSDeletePublicTestSuite) TestDeleteNetworkDNSRBACHTTP() { Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{Hostname: "server1", Changed: &trueVal}, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, } @@ -427,14 +439,13 @@ func (s *NetworkDNSDeletePublicTestSuite) TestDeleteNetworkDNSRBACHTTP() { rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkDNSDeletePublicTestSuite(t *testing.T) { +func TestNetworkDNSDeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkDNSDeletePublicTestSuite)) } diff --git a/internal/controller/api/node/network/dns_get_public_test.go b/internal/controller/api/node/network/dns_get_public_test.go index 8ce7bee2d..567932c77 100644 --- a/internal/controller/api/node/network/dns_get_public_test.go +++ b/internal/controller/api/node/network/dns_get_public_test.go @@ -358,8 +358,7 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceVa name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -379,13 +378,13 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceVa }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{ - `"results"`, - `"servers"`, - `"8.8.8.8"`, - `"search_domains"`, - `"example.com"`, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"servers"`) + s.Contains(rec.Body.String(), `"8.8.8.8"`) + s.Contains(rec.Body.String(), `"search_domains"`) + s.Contains(rec.Body.String(), `"example.com"`) }, }, { @@ -405,8 +404,11 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceVa }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"8.8.8.8"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"8.8.8.8"`) + }, }, { name: "when partial fact reference rejected", @@ -414,8 +416,11 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceVa setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "alphanum_or_fact"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "alphanum_or_fact") + }, }, { name: "when non-alphanum interface name", @@ -423,8 +428,11 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceVa setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "alphanum_or_fact"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "alphanum_or_fact") + }, }, { name: "when unknown fact key rejected", @@ -432,8 +440,11 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceVa setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "alphanum_or_fact"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "alphanum_or_fact") + }, }, { name: "when broadcast all", @@ -452,8 +463,11 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceVa }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"8.8.8.8"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"8.8.8.8"`) + }, }, } @@ -472,10 +486,7 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceVa a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -489,8 +500,7 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceRB name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -500,8 +510,10 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceRB setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -518,8 +530,10 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceRB setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with network:read returns 200", @@ -552,8 +566,11 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceRB ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"8.8.8.8"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"8.8.8.8"`) + }, }, } @@ -586,14 +603,13 @@ func (s *NetworkDNSGetByInterfacePublicTestSuite) TestGetNetworkDNSByInterfaceRB server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkDNSGetByInterfacePublicTestSuite(t *testing.T) { +func TestNetworkDNSGetByInterfacePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkDNSGetByInterfacePublicTestSuite)) } diff --git a/internal/controller/api/node/network/dns_put_public_test.go b/internal/controller/api/node/network/dns_put_public_test.go index 3965bd714..37b51080d 100644 --- a/internal/controller/api/node/network/dns_put_public_test.go +++ b/internal/controller/api/node/network/dns_put_public_test.go @@ -505,8 +505,7 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -522,8 +521,13 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"results"`, `"agent1"`, `"ok"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"agent1"`) + s.Contains(rec.Body.String(), `"ok"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, { name: "when missing interface name", @@ -532,8 +536,12 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "InterfaceName", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "InterfaceName") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when fact reference interface name passes validation", @@ -549,8 +557,11 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"results"`, `"agent1"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"agent1"`) + }, }, { name: "when partial fact reference rejected", @@ -559,8 +570,12 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "InterfaceName", "alphanum_or_fact"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "InterfaceName") + s.Contains(rec.Body.String(), "alphanum_or_fact") + }, }, { name: "when non-alphanum interface name", @@ -569,8 +584,12 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "InterfaceName", "alphanum_or_fact"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "InterfaceName") + s.Contains(rec.Body.String(), "alphanum_or_fact") + }, }, { name: "when invalid server IP", @@ -579,8 +598,12 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Servers", "ip"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Servers") + s.Contains(rec.Body.String(), "ip") + }, }, { name: "when invalid search domain", @@ -589,8 +612,12 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "SearchDomains", "hostname"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "SearchDomains") + s.Contains(rec.Body.String(), "hostname") + }, }, { name: "when unknown fact key interface rejected", @@ -599,8 +626,12 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "InterfaceName", "alphanum_or_fact"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "InterfaceName") + s.Contains(rec.Body.String(), "alphanum_or_fact") + }, }, { name: "when target agent not found", @@ -609,8 +640,12 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, { name: "when override_dhcp true in HTTP request", @@ -626,8 +661,12 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"results"`, `"agent1"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"agent1"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, { name: "when broadcast all", @@ -642,8 +681,12 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT }, nil) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"results"`, `"server1"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"server1"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, } @@ -667,10 +710,7 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSValidationHTT a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -685,8 +725,7 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -696,8 +735,10 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -714,8 +755,10 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with network:write returns 202", @@ -743,8 +786,11 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSRBACHTTP() { ) return mock }, - wantCode: http.StatusAccepted, - wantContains: []string{`"results"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusAccepted, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, } @@ -782,14 +828,13 @@ func (s *NetworkDNSPutByInterfacePublicTestSuite) TestPutNetworkDNSRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkDNSPutByInterfacePublicTestSuite(t *testing.T) { +func TestNetworkDNSPutByInterfacePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkDNSPutByInterfacePublicTestSuite)) } diff --git a/internal/controller/api/node/network/handler_public_test.go b/internal/controller/api/node/network/handler_public_test.go index 9221b12d3..82d9df36e 100644 --- a/internal/controller/api/node/network/handler_public_test.go +++ b/internal/controller/api/node/network/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -90,11 +90,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/network/interface_create_post_public_test.go b/internal/controller/api/node/network/interface_create_post_public_test.go index 68854825b..6b499ce70 100644 --- a/internal/controller/api/node/network/interface_create_post_public_test.go +++ b/internal/controller/api/node/network/interface_create_post_public_test.go @@ -388,8 +388,7 @@ func (s *NetworkInterfaceCreatePostPublicTestSuite) TestPostNetworkInterfaceVali path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -405,8 +404,11 @@ func (s *NetworkInterfaceCreatePostPublicTestSuite) TestPostNetworkInterfaceVali }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"server1"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"server1"`) + }, }, { name: "when invalid address CIDR", @@ -415,8 +417,12 @@ func (s *NetworkInterfaceCreatePostPublicTestSuite) TestPostNetworkInterfaceVali setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Addresses", "cidr"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Addresses") + s.Contains(rec.Body.String(), "cidr") + }, }, { name: "when target agent not found", @@ -425,8 +431,11 @@ func (s *NetworkInterfaceCreatePostPublicTestSuite) TestPostNetworkInterfaceVali setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -450,10 +459,7 @@ func (s *NetworkInterfaceCreatePostPublicTestSuite) TestPostNetworkInterfaceVali a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -468,8 +474,7 @@ func (s *NetworkInterfaceCreatePostPublicTestSuite) TestPostNetworkInterfaceRBAC name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -478,8 +483,10 @@ func (s *NetworkInterfaceCreatePostPublicTestSuite) TestPostNetworkInterfaceRBAC setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -496,8 +503,10 @@ func (s *NetworkInterfaceCreatePostPublicTestSuite) TestPostNetworkInterfaceRBAC setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with network:write returns 200", @@ -521,8 +530,11 @@ func (s *NetworkInterfaceCreatePostPublicTestSuite) TestPostNetworkInterfaceRBAC }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, } @@ -560,14 +572,13 @@ func (s *NetworkInterfaceCreatePostPublicTestSuite) TestPostNetworkInterfaceRBAC server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkInterfaceCreatePostPublicTestSuite(t *testing.T) { +func TestNetworkInterfaceCreatePostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkInterfaceCreatePostPublicTestSuite)) } diff --git a/internal/controller/api/node/network/interface_delete_public_test.go b/internal/controller/api/node/network/interface_delete_public_test.go index e70727551..e5a6a6f3f 100644 --- a/internal/controller/api/node/network/interface_delete_public_test.go +++ b/internal/controller/api/node/network/interface_delete_public_test.go @@ -265,8 +265,7 @@ func (s *NetworkInterfaceDeletePublicTestSuite) TestDeleteNetworkInterfaceValida name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -281,8 +280,11 @@ func (s *NetworkInterfaceDeletePublicTestSuite) TestDeleteNetworkInterfaceValida }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"server1"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"server1"`) + }, }, { name: "when target agent not found", @@ -290,8 +292,11 @@ func (s *NetworkInterfaceDeletePublicTestSuite) TestDeleteNetworkInterfaceValida setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -310,10 +315,7 @@ func (s *NetworkInterfaceDeletePublicTestSuite) TestDeleteNetworkInterfaceValida a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -328,8 +330,7 @@ func (s *NetworkInterfaceDeletePublicTestSuite) TestDeleteNetworkInterfaceRBACHT name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -338,8 +339,10 @@ func (s *NetworkInterfaceDeletePublicTestSuite) TestDeleteNetworkInterfaceRBACHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -356,8 +359,10 @@ func (s *NetworkInterfaceDeletePublicTestSuite) TestDeleteNetworkInterfaceRBACHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with network:write returns 200", @@ -381,8 +386,11 @@ func (s *NetworkInterfaceDeletePublicTestSuite) TestDeleteNetworkInterfaceRBACHT }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, } @@ -419,14 +427,13 @@ func (s *NetworkInterfaceDeletePublicTestSuite) TestDeleteNetworkInterfaceRBACHT server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkInterfaceDeletePublicTestSuite(t *testing.T) { +func TestNetworkInterfaceDeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkInterfaceDeletePublicTestSuite)) } diff --git a/internal/controller/api/node/network/interface_get_public_test.go b/internal/controller/api/node/network/interface_get_public_test.go index b647c7f2c..41c084d2c 100644 --- a/internal/controller/api/node/network/interface_get_public_test.go +++ b/internal/controller/api/node/network/interface_get_public_test.go @@ -430,8 +430,7 @@ func (s *NetworkInterfaceGetPublicTestSuite) TestGetNetworkInterfaceByNameValida name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -446,8 +445,11 @@ func (s *NetworkInterfaceGetPublicTestSuite) TestGetNetworkInterfaceByNameValida }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"server1"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"server1"`) + }, }, { name: "when target agent not found", @@ -455,8 +457,11 @@ func (s *NetworkInterfaceGetPublicTestSuite) TestGetNetworkInterfaceByNameValida setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -475,10 +480,7 @@ func (s *NetworkInterfaceGetPublicTestSuite) TestGetNetworkInterfaceByNameValida a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -495,8 +497,7 @@ func (s *NetworkInterfaceGetPublicTestSuite) TestGetNetworkInterfaceByNameRBACHT name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -505,8 +506,10 @@ func (s *NetworkInterfaceGetPublicTestSuite) TestGetNetworkInterfaceByNameRBACHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -523,8 +526,10 @@ func (s *NetworkInterfaceGetPublicTestSuite) TestGetNetworkInterfaceByNameRBACHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with network:read returns 200", @@ -548,8 +553,10 @@ func (s *NetworkInterfaceGetPublicTestSuite) TestGetNetworkInterfaceByNameRBACHT }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -586,14 +593,13 @@ func (s *NetworkInterfaceGetPublicTestSuite) TestGetNetworkInterfaceByNameRBACHT server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkInterfaceGetPublicTestSuite(t *testing.T) { +func TestNetworkInterfaceGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkInterfaceGetPublicTestSuite)) } diff --git a/internal/controller/api/node/network/interface_list_get_public_test.go b/internal/controller/api/node/network/interface_list_get_public_test.go index fd2a4d666..3991686e8 100644 --- a/internal/controller/api/node/network/interface_list_get_public_test.go +++ b/internal/controller/api/node/network/interface_list_get_public_test.go @@ -435,8 +435,7 @@ func (s *NetworkInterfaceListGetPublicTestSuite) TestGetNetworkInterfaceListVali name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -451,8 +450,11 @@ func (s *NetworkInterfaceListGetPublicTestSuite) TestGetNetworkInterfaceListVali }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"server1"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"server1"`) + }, }, { name: "when target agent not found", @@ -460,8 +462,11 @@ func (s *NetworkInterfaceListGetPublicTestSuite) TestGetNetworkInterfaceListVali setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -484,10 +489,7 @@ func (s *NetworkInterfaceListGetPublicTestSuite) TestGetNetworkInterfaceListVali a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -506,8 +508,7 @@ func (s *NetworkInterfaceListGetPublicTestSuite) TestGetNetworkInterfaceListRBAC name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -516,8 +517,10 @@ func (s *NetworkInterfaceListGetPublicTestSuite) TestGetNetworkInterfaceListRBAC setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -534,8 +537,10 @@ func (s *NetworkInterfaceListGetPublicTestSuite) TestGetNetworkInterfaceListRBAC setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with network:read returns 200", @@ -559,8 +564,10 @@ func (s *NetworkInterfaceListGetPublicTestSuite) TestGetNetworkInterfaceListRBAC }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -597,14 +604,13 @@ func (s *NetworkInterfaceListGetPublicTestSuite) TestGetNetworkInterfaceListRBAC server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkInterfaceListGetPublicTestSuite(t *testing.T) { +func TestNetworkInterfaceListGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkInterfaceListGetPublicTestSuite)) } diff --git a/internal/controller/api/node/network/interface_update_put_public_test.go b/internal/controller/api/node/network/interface_update_put_public_test.go index e3c54b21d..a98464158 100644 --- a/internal/controller/api/node/network/interface_update_put_public_test.go +++ b/internal/controller/api/node/network/interface_update_put_public_test.go @@ -308,8 +308,7 @@ func (s *NetworkInterfaceUpdatePutPublicTestSuite) TestPutNetworkInterfaceValida path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -325,8 +324,11 @@ func (s *NetworkInterfaceUpdatePutPublicTestSuite) TestPutNetworkInterfaceValida }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"server1"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"server1"`) + }, }, { name: "when empty body", @@ -335,8 +337,11 @@ func (s *NetworkInterfaceUpdatePutPublicTestSuite) TestPutNetworkInterfaceValida setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "at least one"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "at least one") + }, }, { name: "when target agent not found", @@ -345,8 +350,11 @@ func (s *NetworkInterfaceUpdatePutPublicTestSuite) TestPutNetworkInterfaceValida setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -370,10 +378,7 @@ func (s *NetworkInterfaceUpdatePutPublicTestSuite) TestPutNetworkInterfaceValida a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -388,8 +393,7 @@ func (s *NetworkInterfaceUpdatePutPublicTestSuite) TestPutNetworkInterfaceRBACHT name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -398,8 +402,10 @@ func (s *NetworkInterfaceUpdatePutPublicTestSuite) TestPutNetworkInterfaceRBACHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -416,8 +422,10 @@ func (s *NetworkInterfaceUpdatePutPublicTestSuite) TestPutNetworkInterfaceRBACHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with network:write returns 200", @@ -441,8 +449,11 @@ func (s *NetworkInterfaceUpdatePutPublicTestSuite) TestPutNetworkInterfaceRBACHT }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"changed":true`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"changed":true`) + }, }, } @@ -480,14 +491,13 @@ func (s *NetworkInterfaceUpdatePutPublicTestSuite) TestPutNetworkInterfaceRBACHT server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkInterfaceUpdatePutPublicTestSuite(t *testing.T) { +func TestNetworkInterfaceUpdatePutPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkInterfaceUpdatePutPublicTestSuite)) } diff --git a/internal/controller/api/node/network/ping_post_public_test.go b/internal/controller/api/node/network/ping_post_public_test.go index 80b8128b9..f0309f392 100644 --- a/internal/controller/api/node/network/ping_post_public_test.go +++ b/internal/controller/api/node/network/ping_post_public_test.go @@ -387,8 +387,7 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -413,8 +412,12 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"packets_sent":3`, `"packets_received":3`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"packets_sent":3`) + s.Contains(rec.Body.String(), `"packets_received":3`) + }, }, { name: "when missing address", @@ -423,8 +426,12 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Address", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Address") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when invalid address format", @@ -433,8 +440,12 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Address", "ip_or_fact"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Address") + s.Contains(rec.Body.String(), "ip_or_fact") + }, }, { name: "when fact reference passes validation", @@ -459,8 +470,11 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"packets_sent":3`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"packets_sent":3`) + }, }, { name: "when partial fact reference rejected", @@ -469,8 +483,11 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "ip_or_fact"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "ip_or_fact") + }, }, { name: "when unknown fact key rejected", @@ -479,8 +496,11 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "ip_or_fact"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "ip_or_fact") + }, }, { name: "when broadcast all", @@ -504,8 +524,11 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"packets_sent":3`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"packets_sent":3`) + }, }, } @@ -529,10 +552,7 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -546,8 +566,7 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -557,8 +576,10 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -575,8 +596,10 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with network:write returns 200", @@ -613,8 +636,11 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingRBACHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"packets_sent":3`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + s.Contains(rec.Body.String(), `"packets_sent":3`) + }, }, } @@ -652,10 +678,7 @@ func (s *NetworkPingPostPublicTestSuite) TestPostNetworkPingRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -664,30 +687,36 @@ func (s *NetworkPingPostPublicTestSuite) TestDurationToString() { dur := 20 * time.Millisecond tests := []struct { - name string - d *time.Duration - want *string + name string + d *time.Duration + validateFunc func(*string) }{ { name: "when nil", d: nil, - want: nil, + validateFunc: func(got *string) { + s.Equal((*string)(nil), got) + }, }, { name: "when valid duration", d: &dur, - want: func() *string { str := "20.00ms"; return &str }(), + validateFunc: func(got *string) { + s.Equal(func() *string { str := "20.00ms"; return &str }(), got) + }, }, } for _, tc := range tests { s.Run(tc.name, func() { got := apinetwork.ExportDurationToString(tc.d) - s.Equal(tc.want, got) + tc.validateFunc(got) }) } } -func TestNetworkPingPostPublicTestSuite(t *testing.T) { +func TestNetworkPingPostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkPingPostPublicTestSuite)) } diff --git a/internal/controller/api/node/network/route_create_post_public_test.go b/internal/controller/api/node/network/route_create_post_public_test.go index b01967080..049ec6650 100644 --- a/internal/controller/api/node/network/route_create_post_public_test.go +++ b/internal/controller/api/node/network/route_create_post_public_test.go @@ -325,8 +325,7 @@ func (s *NetworkRouteCreatePostPublicTestSuite) TestPostNetworkRouteValidationHT path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -341,8 +340,10 @@ func (s *NetworkRouteCreatePostPublicTestSuite) TestPostNetworkRouteValidationHT }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when invalid route to", @@ -351,8 +352,11 @@ func (s *NetworkRouteCreatePostPublicTestSuite) TestPostNetworkRouteValidationHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "cidr"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "cidr") + }, }, { name: "when target agent not found", @@ -361,8 +365,11 @@ func (s *NetworkRouteCreatePostPublicTestSuite) TestPostNetworkRouteValidationHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -379,10 +386,7 @@ func (s *NetworkRouteCreatePostPublicTestSuite) TestPostNetworkRouteValidationHT rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -397,8 +401,7 @@ func (s *NetworkRouteCreatePostPublicTestSuite) TestPostNetworkRouteRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -406,8 +409,10 @@ func (s *NetworkRouteCreatePostPublicTestSuite) TestPostNetworkRouteRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -423,8 +428,10 @@ func (s *NetworkRouteCreatePostPublicTestSuite) TestPostNetworkRouteRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token returns 200", @@ -444,8 +451,10 @@ func (s *NetworkRouteCreatePostPublicTestSuite) TestPostNetworkRouteRBACHTTP() { Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{Hostname: "server1", Changed: &trueVal}, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -478,14 +487,13 @@ func (s *NetworkRouteCreatePostPublicTestSuite) TestPostNetworkRouteRBACHTTP() { rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkRouteCreatePostPublicTestSuite(t *testing.T) { +func TestNetworkRouteCreatePostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkRouteCreatePostPublicTestSuite)) } diff --git a/internal/controller/api/node/network/route_delete_public_test.go b/internal/controller/api/node/network/route_delete_public_test.go index 3c465f712..6446737c8 100644 --- a/internal/controller/api/node/network/route_delete_public_test.go +++ b/internal/controller/api/node/network/route_delete_public_test.go @@ -210,8 +210,7 @@ func (s *NetworkRouteDeletePublicTestSuite) TestDeleteNetworkRouteValidationHTTP name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -223,8 +222,10 @@ func (s *NetworkRouteDeletePublicTestSuite) TestDeleteNetworkRouteValidationHTTP Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{Hostname: "server1", Changed: &trueVal}, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -232,8 +233,11 @@ func (s *NetworkRouteDeletePublicTestSuite) TestDeleteNetworkRouteValidationHTTP setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -249,10 +253,7 @@ func (s *NetworkRouteDeletePublicTestSuite) TestDeleteNetworkRouteValidationHTTP rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -267,8 +268,7 @@ func (s *NetworkRouteDeletePublicTestSuite) TestDeleteNetworkRouteRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -276,8 +276,10 @@ func (s *NetworkRouteDeletePublicTestSuite) TestDeleteNetworkRouteRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -293,8 +295,10 @@ func (s *NetworkRouteDeletePublicTestSuite) TestDeleteNetworkRouteRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token returns 200", @@ -314,8 +318,10 @@ func (s *NetworkRouteDeletePublicTestSuite) TestDeleteNetworkRouteRBACHTTP() { Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{Hostname: "server1", Changed: &trueVal}, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -347,14 +353,13 @@ func (s *NetworkRouteDeletePublicTestSuite) TestDeleteNetworkRouteRBACHTTP() { rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkRouteDeletePublicTestSuite(t *testing.T) { +func TestNetworkRouteDeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkRouteDeletePublicTestSuite)) } diff --git a/internal/controller/api/node/network/route_get_public_test.go b/internal/controller/api/node/network/route_get_public_test.go index f1ca864c8..cc4e3ef8b 100644 --- a/internal/controller/api/node/network/route_get_public_test.go +++ b/internal/controller/api/node/network/route_get_public_test.go @@ -332,8 +332,7 @@ func (s *NetworkRouteGetPublicTestSuite) TestGetNetworkRouteByInterfaceValidatio name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -347,8 +346,10 @@ func (s *NetworkRouteGetPublicTestSuite) TestGetNetworkRouteByInterfaceValidatio }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -356,8 +357,11 @@ func (s *NetworkRouteGetPublicTestSuite) TestGetNetworkRouteByInterfaceValidatio setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -373,10 +377,7 @@ func (s *NetworkRouteGetPublicTestSuite) TestGetNetworkRouteByInterfaceValidatio rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -395,8 +396,7 @@ func (s *NetworkRouteGetPublicTestSuite) TestGetNetworkRouteByInterfaceRBACHTTP( name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -404,8 +404,10 @@ func (s *NetworkRouteGetPublicTestSuite) TestGetNetworkRouteByInterfaceRBACHTTP( setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -421,8 +423,10 @@ func (s *NetworkRouteGetPublicTestSuite) TestGetNetworkRouteByInterfaceRBACHTTP( setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token returns 200", @@ -442,8 +446,10 @@ func (s *NetworkRouteGetPublicTestSuite) TestGetNetworkRouteByInterfaceRBACHTTP( Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{Hostname: "server1", Data: entryData}, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -471,14 +477,13 @@ func (s *NetworkRouteGetPublicTestSuite) TestGetNetworkRouteByInterfaceRBACHTTP( rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkRouteGetPublicTestSuite(t *testing.T) { +func TestNetworkRouteGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkRouteGetPublicTestSuite)) } diff --git a/internal/controller/api/node/network/route_list_get_public_test.go b/internal/controller/api/node/network/route_list_get_public_test.go index 6a19c41d0..bdc174ddd 100644 --- a/internal/controller/api/node/network/route_list_get_public_test.go +++ b/internal/controller/api/node/network/route_list_get_public_test.go @@ -319,8 +319,7 @@ func (s *NetworkRouteListGetPublicTestSuite) TestGetNetworkRouteListValidationHT name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -334,8 +333,10 @@ func (s *NetworkRouteListGetPublicTestSuite) TestGetNetworkRouteListValidationHT }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -343,8 +344,11 @@ func (s *NetworkRouteListGetPublicTestSuite) TestGetNetworkRouteListValidationHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -360,10 +364,7 @@ func (s *NetworkRouteListGetPublicTestSuite) TestGetNetworkRouteListValidationHT rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -381,8 +382,7 @@ func (s *NetworkRouteListGetPublicTestSuite) TestGetNetworkRouteListRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -390,8 +390,10 @@ func (s *NetworkRouteListGetPublicTestSuite) TestGetNetworkRouteListRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -407,8 +409,10 @@ func (s *NetworkRouteListGetPublicTestSuite) TestGetNetworkRouteListRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token returns 200", @@ -430,8 +434,10 @@ func (s *NetworkRouteListGetPublicTestSuite) TestGetNetworkRouteListRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -459,14 +465,13 @@ func (s *NetworkRouteListGetPublicTestSuite) TestGetNetworkRouteListRBACHTTP() { rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkRouteListGetPublicTestSuite(t *testing.T) { +func TestNetworkRouteListGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkRouteListGetPublicTestSuite)) } diff --git a/internal/controller/api/node/network/route_update_put_public_test.go b/internal/controller/api/node/network/route_update_put_public_test.go index aa6702358..66bf64e59 100644 --- a/internal/controller/api/node/network/route_update_put_public_test.go +++ b/internal/controller/api/node/network/route_update_put_public_test.go @@ -284,8 +284,7 @@ func (s *NetworkRouteUpdatePutPublicTestSuite) TestPutNetworkRouteValidationHTTP path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -298,8 +297,10 @@ func (s *NetworkRouteUpdatePutPublicTestSuite) TestPutNetworkRouteValidationHTTP Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{Hostname: "server1", Changed: &trueVal}, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when invalid route", @@ -308,8 +309,10 @@ func (s *NetworkRouteUpdatePutPublicTestSuite) TestPutNetworkRouteValidationHTTP setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, } @@ -326,10 +329,7 @@ func (s *NetworkRouteUpdatePutPublicTestSuite) TestPutNetworkRouteValidationHTTP rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -344,8 +344,7 @@ func (s *NetworkRouteUpdatePutPublicTestSuite) TestPutNetworkRouteRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -353,8 +352,10 @@ func (s *NetworkRouteUpdatePutPublicTestSuite) TestPutNetworkRouteRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -370,8 +371,10 @@ func (s *NetworkRouteUpdatePutPublicTestSuite) TestPutNetworkRouteRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token returns 200", @@ -391,8 +394,10 @@ func (s *NetworkRouteUpdatePutPublicTestSuite) TestPutNetworkRouteRBACHTTP() { Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{Hostname: "server1", Changed: &trueVal}, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -425,14 +430,13 @@ func (s *NetworkRouteUpdatePutPublicTestSuite) TestPutNetworkRouteRBACHTTP() { rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNetworkRouteUpdatePutPublicTestSuite(t *testing.T) { +func TestNetworkRouteUpdatePutPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NetworkRouteUpdatePutPublicTestSuite)) } diff --git a/internal/controller/api/node/node_disk_get_public_test.go b/internal/controller/api/node/node_disk_get_public_test.go index 13cdd03a0..a371d95aa 100644 --- a/internal/controller/api/node/node_disk_get_public_test.go +++ b/internal/controller/api/node/node_disk_get_public_test.go @@ -304,8 +304,7 @@ func (s *NodeDiskGetPublicTestSuite) TestGetNodeDiskValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when get Ok", @@ -330,7 +329,9 @@ func (s *NodeDiskGetPublicTestSuite) TestGetNodeDiskValidationHTTP() { ) return mock }, - wantCode: http.StatusOK, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + }, }, { name: "when empty hostname returns 400", @@ -338,8 +339,10 @@ func (s *NodeDiskGetPublicTestSuite) TestGetNodeDiskValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{"error"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), "error") + }, }, { name: "when job client errors", @@ -351,7 +354,9 @@ func (s *NodeDiskGetPublicTestSuite) TestGetNodeDiskValidationHTTP() { Return("", nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + }, }, } @@ -370,10 +375,7 @@ func (s *NodeDiskGetPublicTestSuite) TestGetNodeDiskValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -387,8 +389,7 @@ func (s *NodeDiskGetPublicTestSuite) TestGetNodeDiskRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -398,8 +399,10 @@ func (s *NodeDiskGetPublicTestSuite) TestGetNodeDiskRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -416,8 +419,10 @@ func (s *NodeDiskGetPublicTestSuite) TestGetNodeDiskRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with node:read returns 200", @@ -451,8 +456,10 @@ func (s *NodeDiskGetPublicTestSuite) TestGetNodeDiskRBACHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + }, }, } @@ -485,14 +492,13 @@ func (s *NodeDiskGetPublicTestSuite) TestGetNodeDiskRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNodeDiskGetPublicTestSuite(t *testing.T) { +func TestNodeDiskGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NodeDiskGetPublicTestSuite)) } diff --git a/internal/controller/api/node/node_load_get_public_test.go b/internal/controller/api/node/node_load_get_public_test.go index d44ecca58..c1c36cea4 100644 --- a/internal/controller/api/node/node_load_get_public_test.go +++ b/internal/controller/api/node/node_load_get_public_test.go @@ -292,8 +292,7 @@ func (s *NodeLoadGetPublicTestSuite) TestGetNodeLoadValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when get Ok", @@ -314,7 +313,9 @@ func (s *NodeLoadGetPublicTestSuite) TestGetNodeLoadValidationHTTP() { ) return mock }, - wantCode: http.StatusOK, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + }, }, { name: "when empty hostname returns 400", @@ -322,8 +323,10 @@ func (s *NodeLoadGetPublicTestSuite) TestGetNodeLoadValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{"error"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), "error") + }, }, { name: "when job client errors", @@ -335,7 +338,9 @@ func (s *NodeLoadGetPublicTestSuite) TestGetNodeLoadValidationHTTP() { Return("", nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + }, }, } @@ -354,10 +359,7 @@ func (s *NodeLoadGetPublicTestSuite) TestGetNodeLoadValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -371,8 +373,7 @@ func (s *NodeLoadGetPublicTestSuite) TestGetNodeLoadRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -382,8 +383,10 @@ func (s *NodeLoadGetPublicTestSuite) TestGetNodeLoadRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -400,8 +403,10 @@ func (s *NodeLoadGetPublicTestSuite) TestGetNodeLoadRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with node:read returns 200", @@ -431,8 +436,10 @@ func (s *NodeLoadGetPublicTestSuite) TestGetNodeLoadRBACHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + }, }, } @@ -465,14 +472,13 @@ func (s *NodeLoadGetPublicTestSuite) TestGetNodeLoadRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNodeLoadGetPublicTestSuite(t *testing.T) { +func TestNodeLoadGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NodeLoadGetPublicTestSuite)) } diff --git a/internal/controller/api/node/node_memory_get_public_test.go b/internal/controller/api/node/node_memory_get_public_test.go index a6e0346a1..d1913d101 100644 --- a/internal/controller/api/node/node_memory_get_public_test.go +++ b/internal/controller/api/node/node_memory_get_public_test.go @@ -292,8 +292,7 @@ func (s *NodeMemoryGetPublicTestSuite) TestGetNodeMemoryValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when get Ok", @@ -314,7 +313,9 @@ func (s *NodeMemoryGetPublicTestSuite) TestGetNodeMemoryValidationHTTP() { ) return mock }, - wantCode: http.StatusOK, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + }, }, { name: "when empty hostname returns 400", @@ -322,8 +323,10 @@ func (s *NodeMemoryGetPublicTestSuite) TestGetNodeMemoryValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{"error"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), "error") + }, }, { name: "when job client errors", @@ -335,7 +338,9 @@ func (s *NodeMemoryGetPublicTestSuite) TestGetNodeMemoryValidationHTTP() { Return("", nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + }, }, } @@ -354,10 +359,7 @@ func (s *NodeMemoryGetPublicTestSuite) TestGetNodeMemoryValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -371,8 +373,7 @@ func (s *NodeMemoryGetPublicTestSuite) TestGetNodeMemoryRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -382,8 +383,10 @@ func (s *NodeMemoryGetPublicTestSuite) TestGetNodeMemoryRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -400,8 +403,10 @@ func (s *NodeMemoryGetPublicTestSuite) TestGetNodeMemoryRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with node:read returns 200", @@ -431,8 +436,10 @@ func (s *NodeMemoryGetPublicTestSuite) TestGetNodeMemoryRBACHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + }, }, } @@ -465,14 +472,13 @@ func (s *NodeMemoryGetPublicTestSuite) TestGetNodeMemoryRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNodeMemoryGetPublicTestSuite(t *testing.T) { +func TestNodeMemoryGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NodeMemoryGetPublicTestSuite)) } diff --git a/internal/controller/api/node/node_os_get_public_test.go b/internal/controller/api/node/node_os_get_public_test.go index d056100f2..0c03310d5 100644 --- a/internal/controller/api/node/node_os_get_public_test.go +++ b/internal/controller/api/node/node_os_get_public_test.go @@ -291,8 +291,7 @@ func (s *NodeOSGetPublicTestSuite) TestGetNodeOSValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when get Ok", @@ -313,7 +312,9 @@ func (s *NodeOSGetPublicTestSuite) TestGetNodeOSValidationHTTP() { ) return mock }, - wantCode: http.StatusOK, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + }, }, { name: "when empty hostname returns 400", @@ -321,8 +322,10 @@ func (s *NodeOSGetPublicTestSuite) TestGetNodeOSValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{"error"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), "error") + }, }, { name: "when job client errors", @@ -334,7 +337,9 @@ func (s *NodeOSGetPublicTestSuite) TestGetNodeOSValidationHTTP() { Return("", nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + }, }, } @@ -353,10 +358,7 @@ func (s *NodeOSGetPublicTestSuite) TestGetNodeOSValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -370,8 +372,7 @@ func (s *NodeOSGetPublicTestSuite) TestGetNodeOSRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -381,8 +382,10 @@ func (s *NodeOSGetPublicTestSuite) TestGetNodeOSRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -399,8 +402,10 @@ func (s *NodeOSGetPublicTestSuite) TestGetNodeOSRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with node:read returns 200", @@ -430,8 +435,10 @@ func (s *NodeOSGetPublicTestSuite) TestGetNodeOSRBACHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + }, }, } @@ -464,14 +471,13 @@ func (s *NodeOSGetPublicTestSuite) TestGetNodeOSRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNodeOSGetPublicTestSuite(t *testing.T) { +func TestNodeOSGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NodeOSGetPublicTestSuite)) } diff --git a/internal/controller/api/node/node_status_get_public_test.go b/internal/controller/api/node/node_status_get_public_test.go index 8fe4579da..10e6e5d56 100644 --- a/internal/controller/api/node/node_status_get_public_test.go +++ b/internal/controller/api/node/node_status_get_public_test.go @@ -316,9 +316,7 @@ func (s *NodeStatusGetPublicTestSuite) TestGetNodeStatusValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantBody string - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when empty hostname returns 400", @@ -326,8 +324,12 @@ func (s *NodeStatusGetPublicTestSuite) TestGetNodeStatusValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + for _, str := range []string{`"error"`} { + s.Contains(rec.Body.String(), str) + } + }, }, { name: "when get Ok", @@ -373,8 +375,9 @@ func (s *NodeStatusGetPublicTestSuite) TestGetNodeStatusValidationHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantBody: ` + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.JSONEq(` { "job_id": "550e8400-e29b-41d4-a716-446655440000", "results": [ @@ -408,7 +411,8 @@ func (s *NodeStatusGetPublicTestSuite) TestGetNodeStatusValidationHTTP() { } ] } -`, +`, rec.Body.String()) + }, }, { name: "when job client errors", @@ -420,8 +424,13 @@ func (s *NodeStatusGetPublicTestSuite) TestGetNodeStatusValidationHTTP() { Return("", nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, - wantBody: `{"error":"assert.AnError general error for testing"}`, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + s.JSONEq( + `{"error":"assert.AnError general error for testing"}`, + rec.Body.String(), + ) + }, }, { name: "when broadcast all", @@ -440,8 +449,12 @@ func (s *NodeStatusGetPublicTestSuite) TestGetNodeStatusValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"results"`, `"server1"`, `"server2"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + for _, str := range []string{`"results"`, `"server1"`, `"server2"`} { + s.Contains(rec.Body.String(), str) + } + }, }, } @@ -460,13 +473,7 @@ func (s *NodeStatusGetPublicTestSuite) TestGetNodeStatusValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - if tc.wantBody != "" { - s.JSONEq(tc.wantBody, rec.Body.String()) - } - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -480,8 +487,7 @@ func (s *NodeStatusGetPublicTestSuite) TestGetNodeStatusRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -491,8 +497,10 @@ func (s *NodeStatusGetPublicTestSuite) TestGetNodeStatusRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -509,8 +517,10 @@ func (s *NodeStatusGetPublicTestSuite) TestGetNodeStatusRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with node:read returns 200", @@ -565,8 +575,11 @@ func (s *NodeStatusGetPublicTestSuite) TestGetNodeStatusRBACHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"hostname":"default-hostname"`, `"job_id"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"hostname":"default-hostname"`) + s.Contains(rec.Body.String(), `"job_id"`) + }, }, } @@ -599,111 +612,136 @@ func (s *NodeStatusGetPublicTestSuite) TestGetNodeStatusRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } func (s *NodeStatusGetPublicTestSuite) TestFormatDuration() { tests := []struct { - name string - input time.Duration - want string + name string + input time.Duration + validateFunc func(string) }{ { name: "0 days, 0 hours, 0 minutes", input: time.Duration(0) * time.Second, - want: "0 days, 0 hours, 0 minutes", + validateFunc: func(got string) { + s.Equal("0 days, 0 hours, 0 minutes", got) + }, }, { name: "0 days, 0 hours, 1 minute", input: time.Duration(60) * time.Second, - want: "0 days, 0 hours, 1 minute", + validateFunc: func(got string) { + s.Equal("0 days, 0 hours, 1 minute", got) + }, }, { name: "0 days, 1 hour, 0 minutes", input: time.Duration(3600) * time.Second, - want: "0 days, 1 hour, 0 minutes", + validateFunc: func(got string) { + s.Equal("0 days, 1 hour, 0 minutes", got) + }, }, { name: "1 day, 0 hours, 0 minutes", input: time.Duration(24*3600) * time.Second, - want: "1 day, 0 hours, 0 minutes", + validateFunc: func(got string) { + s.Equal("1 day, 0 hours, 0 minutes", got) + }, }, { name: "1 day, 1 hour, 1 minute", input: time.Duration(24*3600+3600+60) * time.Second, - want: "1 day, 1 hour, 1 minute", + validateFunc: func(got string) { + s.Equal("1 day, 1 hour, 1 minute", got) + }, }, { name: "4 days, 1 hour, 25 minutes", input: time.Duration(int64(math.Trunc(350735.47))) * time.Second, - want: "4 days, 1 hour, 25 minutes", + validateFunc: func(got string) { + s.Equal("4 days, 1 hour, 25 minutes", got) + }, }, { name: "2 days, 2 hours, 2 minutes", input: time.Duration(2*24*3600+2*3600+2*60) * time.Second, - want: "2 days, 2 hours, 2 minutes", + validateFunc: func(got string) { + s.Equal("2 days, 2 hours, 2 minutes", got) + }, }, { name: "0 days, 0 hours, 59 minutes", input: time.Duration(59) * time.Minute, - want: "0 days, 0 hours, 59 minutes", + validateFunc: func(got string) { + s.Equal("0 days, 0 hours, 59 minutes", got) + }, }, { name: "0 days, 23 hours, 59 minutes", input: time.Duration(23*3600+59*60) * time.Second, - want: "0 days, 23 hours, 59 minutes", + validateFunc: func(got string) { + s.Equal("0 days, 23 hours, 59 minutes", got) + }, }, } for _, tc := range tests { s.Run(tc.name, func() { got := apinode.ExportFormatDuration(tc.input) - s.Equal(tc.want, got) + tc.validateFunc(got) }) } } func (s *NodeStatusGetPublicTestSuite) TestUint64ToInt() { tests := []struct { - name string - input uint64 - want int + name string + input uint64 + validateFunc func(int) }{ { name: "when within bounds - small value", input: 123, - want: 123, + validateFunc: func(got int) { + s.Equal(123, got) + }, }, { name: "when within bounds - max int value", input: uint64(math.MaxInt), - want: math.MaxInt, + validateFunc: func(got int) { + s.Equal(math.MaxInt, got) + }, }, { name: "when overflow value - just above max int", input: uint64(math.MaxInt) + 1, - want: math.MaxInt, + validateFunc: func(got int) { + s.Equal(math.MaxInt, got) + }, }, { name: "when overflow value - large uint64", input: math.MaxUint64, - want: math.MaxInt, + validateFunc: func(got int) { + s.Equal(math.MaxInt, got) + }, }, } for _, tc := range tests { s.Run(tc.name, func() { result := apinode.ExportUint64ToInt(tc.input) - s.Equal(tc.want, result) + tc.validateFunc(result) }) } } -func TestNodeStatusGetPublicTestSuite(t *testing.T) { +func TestNodeStatusGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NodeStatusGetPublicTestSuite)) } diff --git a/internal/controller/api/node/node_uptime_get_public_test.go b/internal/controller/api/node/node_uptime_get_public_test.go index 1a71f70ae..32b95d52d 100644 --- a/internal/controller/api/node/node_uptime_get_public_test.go +++ b/internal/controller/api/node/node_uptime_get_public_test.go @@ -289,8 +289,7 @@ func (s *NodeUptimeGetPublicTestSuite) TestGetNodeUptimeValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when get Ok", @@ -311,7 +310,9 @@ func (s *NodeUptimeGetPublicTestSuite) TestGetNodeUptimeValidationHTTP() { ) return mock }, - wantCode: http.StatusOK, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + }, }, { name: "when empty hostname returns 400", @@ -319,8 +320,10 @@ func (s *NodeUptimeGetPublicTestSuite) TestGetNodeUptimeValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{"error"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), "error") + }, }, { name: "when job client errors", @@ -332,7 +335,9 @@ func (s *NodeUptimeGetPublicTestSuite) TestGetNodeUptimeValidationHTTP() { Return("", nil, assert.AnError) return mock }, - wantCode: http.StatusInternalServerError, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusInternalServerError, rec.Code) + }, }, } @@ -351,10 +356,7 @@ func (s *NodeUptimeGetPublicTestSuite) TestGetNodeUptimeValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -368,8 +370,7 @@ func (s *NodeUptimeGetPublicTestSuite) TestGetNodeUptimeRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -379,8 +380,10 @@ func (s *NodeUptimeGetPublicTestSuite) TestGetNodeUptimeRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -397,8 +400,10 @@ func (s *NodeUptimeGetPublicTestSuite) TestGetNodeUptimeRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid token with node:read returns 200", @@ -428,8 +433,10 @@ func (s *NodeUptimeGetPublicTestSuite) TestGetNodeUptimeRBACHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + }, }, } @@ -462,14 +469,13 @@ func (s *NodeUptimeGetPublicTestSuite) TestGetNodeUptimeRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNodeUptimeGetPublicTestSuite(t *testing.T) { +func TestNodeUptimeGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NodeUptimeGetPublicTestSuite)) } diff --git a/internal/controller/api/node/ntp/ntp_create_public_test.go b/internal/controller/api/node/ntp/ntp_create_public_test.go index 0b0f15423..8f466204d 100644 --- a/internal/controller/api/node/ntp/ntp_create_public_test.go +++ b/internal/controller/api/node/ntp/ntp_create_public_test.go @@ -374,8 +374,7 @@ func (s *NtpCreatePublicTestSuite) TestPostNodeNtpValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -394,8 +393,11 @@ func (s *NtpCreatePublicTestSuite) TestPostNodeNtpValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when missing servers returns 400", @@ -404,8 +406,11 @@ func (s *NtpCreatePublicTestSuite) TestPostNodeNtpValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Servers"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Servers") + }, }, { name: "when target agent not found", @@ -414,8 +419,11 @@ func (s *NtpCreatePublicTestSuite) TestPostNodeNtpValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -439,10 +447,7 @@ func (s *NtpCreatePublicTestSuite) TestPostNodeNtpValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -457,8 +462,7 @@ func (s *NtpCreatePublicTestSuite) TestPostNodeNtpRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -468,8 +472,10 @@ func (s *NtpCreatePublicTestSuite) TestPostNodeNtpRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -486,8 +492,10 @@ func (s *NtpCreatePublicTestSuite) TestPostNodeNtpRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -514,8 +522,11 @@ func (s *NtpCreatePublicTestSuite) TestPostNodeNtpRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -553,14 +564,13 @@ func (s *NtpCreatePublicTestSuite) TestPostNodeNtpRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNtpCreatePublicTestSuite(t *testing.T) { +func TestNtpCreatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NtpCreatePublicTestSuite)) } diff --git a/internal/controller/api/node/ntp/ntp_delete_public_test.go b/internal/controller/api/node/ntp/ntp_delete_public_test.go index 18dc2698e..9e3560ab7 100644 --- a/internal/controller/api/node/ntp/ntp_delete_public_test.go +++ b/internal/controller/api/node/ntp/ntp_delete_public_test.go @@ -369,8 +369,7 @@ func (s *NtpDeletePublicTestSuite) TestDeleteNodeNtpValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -388,8 +387,11 @@ func (s *NtpDeletePublicTestSuite) TestDeleteNodeNtpValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -397,8 +399,11 @@ func (s *NtpDeletePublicTestSuite) TestDeleteNodeNtpValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -417,10 +422,7 @@ func (s *NtpDeletePublicTestSuite) TestDeleteNodeNtpValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -435,8 +437,7 @@ func (s *NtpDeletePublicTestSuite) TestDeleteNodeNtpRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -446,8 +447,10 @@ func (s *NtpDeletePublicTestSuite) TestDeleteNodeNtpRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -464,8 +467,10 @@ func (s *NtpDeletePublicTestSuite) TestDeleteNodeNtpRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -492,8 +497,11 @@ func (s *NtpDeletePublicTestSuite) TestDeleteNodeNtpRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -530,14 +538,13 @@ func (s *NtpDeletePublicTestSuite) TestDeleteNodeNtpRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNtpDeletePublicTestSuite(t *testing.T) { +func TestNtpDeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NtpDeletePublicTestSuite)) } diff --git a/internal/controller/api/node/ntp/ntp_get_public_test.go b/internal/controller/api/node/ntp/ntp_get_public_test.go index 8a2562947..5da96e927 100644 --- a/internal/controller/api/node/ntp/ntp_get_public_test.go +++ b/internal/controller/api/node/ntp/ntp_get_public_test.go @@ -347,8 +347,7 @@ func (s *NtpGetPublicTestSuite) TestGetNodeNtpValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -365,8 +364,11 @@ func (s *NtpGetPublicTestSuite) TestGetNodeNtpValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -374,8 +376,11 @@ func (s *NtpGetPublicTestSuite) TestGetNodeNtpValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -394,10 +399,7 @@ func (s *NtpGetPublicTestSuite) TestGetNodeNtpValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -411,8 +413,7 @@ func (s *NtpGetPublicTestSuite) TestGetNodeNtpRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -422,8 +423,10 @@ func (s *NtpGetPublicTestSuite) TestGetNodeNtpRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -440,8 +443,10 @@ func (s *NtpGetPublicTestSuite) TestGetNodeNtpRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -467,8 +472,11 @@ func (s *NtpGetPublicTestSuite) TestGetNodeNtpRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -505,14 +513,13 @@ func (s *NtpGetPublicTestSuite) TestGetNodeNtpRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNtpGetPublicTestSuite(t *testing.T) { +func TestNtpGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NtpGetPublicTestSuite)) } diff --git a/internal/controller/api/node/ntp/ntp_update_public_test.go b/internal/controller/api/node/ntp/ntp_update_public_test.go index 65b9eb4ed..9f64c2d3f 100644 --- a/internal/controller/api/node/ntp/ntp_update_public_test.go +++ b/internal/controller/api/node/ntp/ntp_update_public_test.go @@ -403,8 +403,7 @@ func (s *NtpUpdatePublicTestSuite) TestPutNodeNtpValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -423,8 +422,11 @@ func (s *NtpUpdatePublicTestSuite) TestPutNodeNtpValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when missing servers returns 400", @@ -433,8 +435,11 @@ func (s *NtpUpdatePublicTestSuite) TestPutNodeNtpValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Servers"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Servers") + }, }, { name: "when target agent not found", @@ -443,8 +448,11 @@ func (s *NtpUpdatePublicTestSuite) TestPutNodeNtpValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -468,10 +476,7 @@ func (s *NtpUpdatePublicTestSuite) TestPutNodeNtpValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -486,8 +491,7 @@ func (s *NtpUpdatePublicTestSuite) TestPutNodeNtpRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -497,8 +501,10 @@ func (s *NtpUpdatePublicTestSuite) TestPutNodeNtpRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -515,8 +521,10 @@ func (s *NtpUpdatePublicTestSuite) TestPutNodeNtpRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -543,8 +551,11 @@ func (s *NtpUpdatePublicTestSuite) TestPutNodeNtpRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -582,14 +593,13 @@ func (s *NtpUpdatePublicTestSuite) TestPutNodeNtpRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestNtpUpdatePublicTestSuite(t *testing.T) { +func TestNtpUpdatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NtpUpdatePublicTestSuite)) } diff --git a/internal/controller/api/node/package/handler_public_test.go b/internal/controller/api/node/package/handler_public_test.go index c0fdf9dd9..6d50bb62e 100644 --- a/internal/controller/api/node/package/handler_public_test.go +++ b/internal/controller/api/node/package/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/package/package_get_public_test.go b/internal/controller/api/node/package/package_get_public_test.go index 09796fec0..d6cf0eded 100644 --- a/internal/controller/api/node/package/package_get_public_test.go +++ b/internal/controller/api/node/package/package_get_public_test.go @@ -336,8 +336,7 @@ func (s *PackageGetPublicTestSuite) TestGetNodePackageByNameValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -355,8 +354,11 @@ func (s *PackageGetPublicTestSuite) TestGetNodePackageByNameValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -364,8 +366,11 @@ func (s *PackageGetPublicTestSuite) TestGetNodePackageByNameValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -384,10 +389,7 @@ func (s *PackageGetPublicTestSuite) TestGetNodePackageByNameValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -401,8 +403,7 @@ func (s *PackageGetPublicTestSuite) TestGetNodePackageByNameRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -411,8 +412,10 @@ func (s *PackageGetPublicTestSuite) TestGetNodePackageByNameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -429,8 +432,10 @@ func (s *PackageGetPublicTestSuite) TestGetNodePackageByNameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -457,8 +462,11 @@ func (s *PackageGetPublicTestSuite) TestGetNodePackageByNameRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -495,14 +503,13 @@ func (s *PackageGetPublicTestSuite) TestGetNodePackageByNameRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestPackageGetPublicTestSuite(t *testing.T) { +func TestPackageGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PackageGetPublicTestSuite)) } diff --git a/internal/controller/api/node/package/package_install_public_test.go b/internal/controller/api/node/package/package_install_public_test.go index c8c3534bc..8af2d65b5 100644 --- a/internal/controller/api/node/package/package_install_public_test.go +++ b/internal/controller/api/node/package/package_install_public_test.go @@ -293,8 +293,7 @@ func (s *PackageInstallPublicTestSuite) TestPostNodePackageValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -313,8 +312,11 @@ func (s *PackageInstallPublicTestSuite) TestPostNodePackageValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when empty name returns 400", @@ -323,8 +325,10 @@ func (s *PackageInstallPublicTestSuite) TestPostNodePackageValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, } @@ -345,10 +349,7 @@ func (s *PackageInstallPublicTestSuite) TestPostNodePackageValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -362,8 +363,7 @@ func (s *PackageInstallPublicTestSuite) TestPostNodePackageRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -372,8 +372,10 @@ func (s *PackageInstallPublicTestSuite) TestPostNodePackageRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -390,8 +392,10 @@ func (s *PackageInstallPublicTestSuite) TestPostNodePackageRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -418,8 +422,11 @@ func (s *PackageInstallPublicTestSuite) TestPostNodePackageRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -457,14 +464,13 @@ func (s *PackageInstallPublicTestSuite) TestPostNodePackageRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestPackageInstallPublicTestSuite(t *testing.T) { +func TestPackageInstallPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PackageInstallPublicTestSuite)) } diff --git a/internal/controller/api/node/package/package_list_get_public_test.go b/internal/controller/api/node/package/package_list_get_public_test.go index d908d2c9b..81c45e848 100644 --- a/internal/controller/api/node/package/package_list_get_public_test.go +++ b/internal/controller/api/node/package/package_list_get_public_test.go @@ -359,8 +359,7 @@ func (s *PackageListGetPublicTestSuite) TestGetNodePackageValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -375,8 +374,11 @@ func (s *PackageListGetPublicTestSuite) TestGetNodePackageValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -384,8 +386,11 @@ func (s *PackageListGetPublicTestSuite) TestGetNodePackageValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -404,10 +409,7 @@ func (s *PackageListGetPublicTestSuite) TestGetNodePackageValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -421,8 +423,7 @@ func (s *PackageListGetPublicTestSuite) TestGetNodePackageRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -431,8 +432,10 @@ func (s *PackageListGetPublicTestSuite) TestGetNodePackageRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -449,8 +452,10 @@ func (s *PackageListGetPublicTestSuite) TestGetNodePackageRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -474,8 +479,11 @@ func (s *PackageListGetPublicTestSuite) TestGetNodePackageRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -512,14 +520,13 @@ func (s *PackageListGetPublicTestSuite) TestGetNodePackageRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestPackageListGetPublicTestSuite(t *testing.T) { +func TestPackageListGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PackageListGetPublicTestSuite)) } diff --git a/internal/controller/api/node/package/package_remove_public_test.go b/internal/controller/api/node/package/package_remove_public_test.go index cde039f17..cad191287 100644 --- a/internal/controller/api/node/package/package_remove_public_test.go +++ b/internal/controller/api/node/package/package_remove_public_test.go @@ -325,8 +325,7 @@ func (s *PackageRemovePublicTestSuite) TestDeleteNodePackageValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -344,8 +343,11 @@ func (s *PackageRemovePublicTestSuite) TestDeleteNodePackageValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -353,8 +355,11 @@ func (s *PackageRemovePublicTestSuite) TestDeleteNodePackageValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -373,10 +378,7 @@ func (s *PackageRemovePublicTestSuite) TestDeleteNodePackageValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -390,8 +392,7 @@ func (s *PackageRemovePublicTestSuite) TestDeleteNodePackageRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -400,8 +401,10 @@ func (s *PackageRemovePublicTestSuite) TestDeleteNodePackageRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -418,8 +421,10 @@ func (s *PackageRemovePublicTestSuite) TestDeleteNodePackageRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -446,8 +451,11 @@ func (s *PackageRemovePublicTestSuite) TestDeleteNodePackageRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -484,14 +492,13 @@ func (s *PackageRemovePublicTestSuite) TestDeleteNodePackageRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestPackageRemovePublicTestSuite(t *testing.T) { +func TestPackageRemovePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PackageRemovePublicTestSuite)) } diff --git a/internal/controller/api/node/package/package_update_get_public_test.go b/internal/controller/api/node/package/package_update_get_public_test.go index 42b315224..31965cc54 100644 --- a/internal/controller/api/node/package/package_update_get_public_test.go +++ b/internal/controller/api/node/package/package_update_get_public_test.go @@ -309,8 +309,7 @@ func (s *PackageUpdateGetPublicTestSuite) TestGetNodePackageUpdateValidationHTTP name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -325,8 +324,11 @@ func (s *PackageUpdateGetPublicTestSuite) TestGetNodePackageUpdateValidationHTTP }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -334,8 +336,11 @@ func (s *PackageUpdateGetPublicTestSuite) TestGetNodePackageUpdateValidationHTTP setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -354,10 +359,7 @@ func (s *PackageUpdateGetPublicTestSuite) TestGetNodePackageUpdateValidationHTTP a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -371,8 +373,7 @@ func (s *PackageUpdateGetPublicTestSuite) TestGetNodePackageUpdateRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -381,8 +382,10 @@ func (s *PackageUpdateGetPublicTestSuite) TestGetNodePackageUpdateRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -399,8 +402,10 @@ func (s *PackageUpdateGetPublicTestSuite) TestGetNodePackageUpdateRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -424,8 +429,11 @@ func (s *PackageUpdateGetPublicTestSuite) TestGetNodePackageUpdateRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -462,14 +470,13 @@ func (s *PackageUpdateGetPublicTestSuite) TestGetNodePackageUpdateRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestPackageUpdateGetPublicTestSuite(t *testing.T) { +func TestPackageUpdateGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PackageUpdateGetPublicTestSuite)) } diff --git a/internal/controller/api/node/package/package_update_post_public_test.go b/internal/controller/api/node/package/package_update_post_public_test.go index efbce5d63..d778e0ed3 100644 --- a/internal/controller/api/node/package/package_update_post_public_test.go +++ b/internal/controller/api/node/package/package_update_post_public_test.go @@ -270,8 +270,7 @@ func (s *PackageUpdatePostPublicTestSuite) TestPostNodePackageUpdateValidationHT name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -288,8 +287,11 @@ func (s *PackageUpdatePostPublicTestSuite) TestPostNodePackageUpdateValidationHT }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -297,8 +299,11 @@ func (s *PackageUpdatePostPublicTestSuite) TestPostNodePackageUpdateValidationHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -317,10 +322,7 @@ func (s *PackageUpdatePostPublicTestSuite) TestPostNodePackageUpdateValidationHT a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -334,8 +336,7 @@ func (s *PackageUpdatePostPublicTestSuite) TestPostNodePackageUpdateRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -344,8 +345,10 @@ func (s *PackageUpdatePostPublicTestSuite) TestPostNodePackageUpdateRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -362,8 +365,10 @@ func (s *PackageUpdatePostPublicTestSuite) TestPostNodePackageUpdateRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -389,8 +394,11 @@ func (s *PackageUpdatePostPublicTestSuite) TestPostNodePackageUpdateRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -427,14 +435,13 @@ func (s *PackageUpdatePostPublicTestSuite) TestPostNodePackageUpdateRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestPackageUpdatePostPublicTestSuite(t *testing.T) { +func TestPackageUpdatePostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PackageUpdatePostPublicTestSuite)) } diff --git a/internal/controller/api/node/power/reboot_post_public_test.go b/internal/controller/api/node/power/reboot_post_public_test.go index c8a6c05de..718b2ef5c 100644 --- a/internal/controller/api/node/power/reboot_post_public_test.go +++ b/internal/controller/api/node/power/reboot_post_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -93,8 +95,8 @@ func (s *RebootPostPublicTestSuite) TestPostNodePowerReboot() { request: gen.PostNodePowerRebootRequestObject{ Hostname: "server1", Body: &gen.PowerRequest{ - Delay: intPtr(5), - Message: strPtr("maintenance reboot"), + Delay: ptr.To(5), + Message: ptr.To("maintenance reboot"), }, }, setupMock: func() { @@ -373,8 +375,7 @@ func (s *RebootPostPublicTestSuite) TestPostNodePowerRebootValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request with body", @@ -393,8 +394,11 @@ func (s *RebootPostPublicTestSuite) TestPostNodePowerRebootValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -403,8 +407,11 @@ func (s *RebootPostPublicTestSuite) TestPostNodePowerRebootValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -428,10 +435,7 @@ func (s *RebootPostPublicTestSuite) TestPostNodePowerRebootValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -446,8 +450,7 @@ func (s *RebootPostPublicTestSuite) TestPostNodePowerRebootRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -457,8 +460,10 @@ func (s *RebootPostPublicTestSuite) TestPostNodePowerRebootRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -475,8 +480,10 @@ func (s *RebootPostPublicTestSuite) TestPostNodePowerRebootRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -503,8 +510,11 @@ func (s *RebootPostPublicTestSuite) TestPostNodePowerRebootRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -542,17 +552,13 @@ func (s *RebootPostPublicTestSuite) TestPostNodePowerRebootRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestRebootPostPublicTestSuite(t *testing.T) { +func TestRebootPostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(RebootPostPublicTestSuite)) } - -func intPtr(v int) *int { return &v } -func strPtr(v string) *string { return &v } diff --git a/internal/controller/api/node/power/shutdown_post_public_test.go b/internal/controller/api/node/power/shutdown_post_public_test.go index 2d37255c2..148611c7f 100644 --- a/internal/controller/api/node/power/shutdown_post_public_test.go +++ b/internal/controller/api/node/power/shutdown_post_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -93,8 +95,8 @@ func (s *ShutdownPostPublicTestSuite) TestPostNodePowerShutdown() { request: gen.PostNodePowerShutdownRequestObject{ Hostname: "server1", Body: &gen.PowerRequest{ - Delay: intPtr(10), - Message: strPtr("planned shutdown"), + Delay: ptr.To(10), + Message: ptr.To("planned shutdown"), }, }, setupMock: func() { @@ -373,8 +375,7 @@ func (s *ShutdownPostPublicTestSuite) TestPostNodePowerShutdownValidationHTTP() path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request with body", @@ -393,8 +394,11 @@ func (s *ShutdownPostPublicTestSuite) TestPostNodePowerShutdownValidationHTTP() }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -403,8 +407,11 @@ func (s *ShutdownPostPublicTestSuite) TestPostNodePowerShutdownValidationHTTP() setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -428,10 +435,7 @@ func (s *ShutdownPostPublicTestSuite) TestPostNodePowerShutdownValidationHTTP() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -446,8 +450,7 @@ func (s *ShutdownPostPublicTestSuite) TestPostNodePowerShutdownRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -457,8 +460,10 @@ func (s *ShutdownPostPublicTestSuite) TestPostNodePowerShutdownRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -475,8 +480,10 @@ func (s *ShutdownPostPublicTestSuite) TestPostNodePowerShutdownRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -503,8 +510,11 @@ func (s *ShutdownPostPublicTestSuite) TestPostNodePowerShutdownRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -542,14 +552,13 @@ func (s *ShutdownPostPublicTestSuite) TestPostNodePowerShutdownRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestShutdownPostPublicTestSuite(t *testing.T) { +func TestShutdownPostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ShutdownPostPublicTestSuite)) } diff --git a/internal/controller/api/node/process/handler_public_test.go b/internal/controller/api/node/process/handler_public_test.go index 30ceb6124..1b986f4d1 100644 --- a/internal/controller/api/node/process/handler_public_test.go +++ b/internal/controller/api/node/process/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/process/process_get_public_test.go b/internal/controller/api/node/process/process_get_public_test.go index 0488d0df7..2b5bb56c9 100644 --- a/internal/controller/api/node/process/process_get_public_test.go +++ b/internal/controller/api/node/process/process_get_public_test.go @@ -342,8 +342,7 @@ func (s *ProcessGetPublicTestSuite) TestGetNodeProcessByPidValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -361,8 +360,11 @@ func (s *ProcessGetPublicTestSuite) TestGetNodeProcessByPidValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -370,8 +372,12 @@ func (s *ProcessGetPublicTestSuite) TestGetNodeProcessByPidValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -390,10 +396,7 @@ func (s *ProcessGetPublicTestSuite) TestGetNodeProcessByPidValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -407,8 +410,7 @@ func (s *ProcessGetPublicTestSuite) TestGetNodeProcessByPidRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -418,8 +420,10 @@ func (s *ProcessGetPublicTestSuite) TestGetNodeProcessByPidRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -436,8 +440,10 @@ func (s *ProcessGetPublicTestSuite) TestGetNodeProcessByPidRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -464,8 +470,11 @@ func (s *ProcessGetPublicTestSuite) TestGetNodeProcessByPidRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -502,14 +511,13 @@ func (s *ProcessGetPublicTestSuite) TestGetNodeProcessByPidRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestProcessGetPublicTestSuite(t *testing.T) { +func TestProcessGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessGetPublicTestSuite)) } diff --git a/internal/controller/api/node/process/process_list_get_public_test.go b/internal/controller/api/node/process/process_list_get_public_test.go index df24c917d..458a79865 100644 --- a/internal/controller/api/node/process/process_list_get_public_test.go +++ b/internal/controller/api/node/process/process_list_get_public_test.go @@ -351,8 +351,7 @@ func (s *ProcessListPublicTestSuite) TestGetNodeProcessValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -368,8 +367,11 @@ func (s *ProcessListPublicTestSuite) TestGetNodeProcessValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -377,8 +379,12 @@ func (s *ProcessListPublicTestSuite) TestGetNodeProcessValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -397,10 +403,7 @@ func (s *ProcessListPublicTestSuite) TestGetNodeProcessValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -414,8 +417,7 @@ func (s *ProcessListPublicTestSuite) TestGetNodeProcessRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -425,8 +427,10 @@ func (s *ProcessListPublicTestSuite) TestGetNodeProcessRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -443,8 +447,10 @@ func (s *ProcessListPublicTestSuite) TestGetNodeProcessRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -469,8 +475,11 @@ func (s *ProcessListPublicTestSuite) TestGetNodeProcessRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -507,14 +516,13 @@ func (s *ProcessListPublicTestSuite) TestGetNodeProcessRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestProcessListPublicTestSuite(t *testing.T) { +func TestProcessListPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessListPublicTestSuite)) } diff --git a/internal/controller/api/node/process/process_signal_post_public_test.go b/internal/controller/api/node/process/process_signal_post_public_test.go index 7808802f5..bed3c452b 100644 --- a/internal/controller/api/node/process/process_signal_post_public_test.go +++ b/internal/controller/api/node/process/process_signal_post_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -106,7 +108,7 @@ func (s *ProcessSignalPublicTestSuite) TestPostNodeProcessSignal() { Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"pid":1234,"signal":"TERM","changed":true}`, ), @@ -298,7 +300,7 @@ func (s *ProcessSignalPublicTestSuite) TestPostNodeProcessSignal() { Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ "server1": { Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage( `{"pid":1234,"signal":"TERM","changed":true}`, ), @@ -393,8 +395,7 @@ func (s *ProcessSignalPublicTestSuite) TestPostNodeProcessSignalValidationHTTP() path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -407,13 +408,16 @@ func (s *ProcessSignalPublicTestSuite) TestPostNodeProcessSignalValidationHTTP() Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"pid":1234,"signal":"TERM","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when invalid signal", @@ -422,8 +426,10 @@ func (s *ProcessSignalPublicTestSuite) TestPostNodeProcessSignalValidationHTTP() setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, { name: "when target agent not found", @@ -432,8 +438,12 @@ func (s *ProcessSignalPublicTestSuite) TestPostNodeProcessSignalValidationHTTP() setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target", "not found"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + s.Contains(rec.Body.String(), "not found") + }, }, } @@ -457,10 +467,7 @@ func (s *ProcessSignalPublicTestSuite) TestPostNodeProcessSignalValidationHTTP() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -474,8 +481,7 @@ func (s *ProcessSignalPublicTestSuite) TestPostNodeProcessSignalRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -485,8 +491,10 @@ func (s *ProcessSignalPublicTestSuite) TestPostNodeProcessSignalRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -503,8 +511,10 @@ func (s *ProcessSignalPublicTestSuite) TestPostNodeProcessSignalRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -525,13 +535,16 @@ func (s *ProcessSignalPublicTestSuite) TestPostNodeProcessSignalRBACHTTP() { Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"pid":1234,"signal":"TERM","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -569,14 +582,13 @@ func (s *ProcessSignalPublicTestSuite) TestPostNodeProcessSignalRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestProcessSignalPublicTestSuite(t *testing.T) { +func TestProcessSignalPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessSignalPublicTestSuite)) } diff --git a/internal/controller/api/node/process/support_public_test.go b/internal/controller/api/node/process/support_public_test.go deleted file mode 100644 index d73dd1ca2..000000000 --- a/internal/controller/api/node/process/support_public_test.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2026 John Dewey - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -package process_test - -func boolPtr( - b bool, -) *bool { - return &b -} diff --git a/internal/controller/api/node/schedule/cron_create_public_test.go b/internal/controller/api/node/schedule/cron_create_public_test.go index aadc9c21b..44c2fc06f 100644 --- a/internal/controller/api/node/schedule/cron_create_public_test.go +++ b/internal/controller/api/node/schedule/cron_create_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -91,10 +93,10 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "server1", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("0 2 * * *"), + Schedule: ptr.To("0 2 * * *"), Object: "backup-script", - User: strPtr("root"), - ContentType: (*gen.CronCreateRequestContentType)(strPtr("template")), + User: ptr.To("root"), + ContentType: (*gen.CronCreateRequestContentType)(ptr.To("template")), Vars: &map[string]interface{}{"region": "us-east"}, }, }, @@ -112,7 +114,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, nil, @@ -135,7 +137,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "server1", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("0 2 * * *"), + Schedule: ptr.To("0 2 * * *"), Object: "/usr/bin/backup.sh", }, }, @@ -153,7 +155,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, nil, @@ -173,7 +175,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "server1", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "daily-backup", - Interval: intervalPtr(gen.CronCreateRequestIntervalDaily), + Interval: ptr.To(gen.CronCreateRequestIntervalDaily), Object: "/usr/bin/backup.sh", }, }, @@ -191,7 +193,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"daily-backup","changed":true}`), }, nil, @@ -211,7 +213,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "server1", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("0 2 * * *"), + Schedule: ptr.To("0 2 * * *"), Object: "/usr/bin/backup.sh", }, }, @@ -229,7 +231,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, nil, @@ -249,7 +251,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "_all", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("0 2 * * *"), + Schedule: ptr.To("0 2 * * *"), Object: "backup-script", }, }, @@ -266,13 +268,13 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, }, nil) @@ -290,7 +292,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "_all", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("0 2 * * *"), + Schedule: ptr.To("0 2 * * *"), Object: "backup-script", }, }, @@ -307,7 +309,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, "server2": { @@ -330,7 +332,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "_all", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("0 2 * * *"), + Schedule: ptr.To("0 2 * * *"), Object: "backup-script", }, }, @@ -367,7 +369,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "_all", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("0 2 * * *"), + Schedule: ptr.To("0 2 * * *"), Object: "backup-script", }, }, @@ -393,7 +395,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("0 2 * * *"), + Schedule: ptr.To("0 2 * * *"), Object: "/usr/bin/backup.sh", }, }, @@ -411,7 +413,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "server1", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "", - Schedule: strPtr("0 2 * * *"), + Schedule: ptr.To("0 2 * * *"), Object: "/usr/bin/backup.sh", }, }, @@ -445,8 +447,8 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "server1", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("0 2 * * *"), - Interval: intervalPtr(gen.CronCreateRequestIntervalDaily), + Schedule: ptr.To("0 2 * * *"), + Interval: ptr.To(gen.CronCreateRequestIntervalDaily), Object: "/usr/bin/backup.sh", }, }, @@ -463,7 +465,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "server1", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("not-a-cron"), + Schedule: ptr.To("not-a-cron"), Object: "/usr/bin/backup.sh", }, }, @@ -481,7 +483,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "server1", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("0 2 * * *"), + Schedule: ptr.To("0 2 * * *"), Object: "", }, }, @@ -498,7 +500,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "server1", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("0 2 * * *"), + Schedule: ptr.To("0 2 * * *"), Object: "/usr/bin/backup.sh", }, }, @@ -538,7 +540,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCron() { Hostname: "server1", Body: &gen.PostNodeScheduleCronJSONRequestBody{ Name: "backup", - Schedule: strPtr("0 2 * * *"), + Schedule: ptr.To("0 2 * * *"), Object: "/usr/bin/backup.sh", }, }, @@ -577,8 +579,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCronValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -593,15 +594,18 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCronValidationHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when missing name", @@ -610,8 +614,12 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCronValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Name", "required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Name") + s.Contains(rec.Body.String(), "required") + }, }, { name: "when target agent not found", @@ -620,8 +628,11 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCronValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -645,10 +656,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCronValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -662,8 +670,7 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCronRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -673,8 +680,10 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCronRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -691,8 +700,10 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCronRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -715,15 +726,18 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCronRBACHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -763,14 +777,13 @@ func (s *CronCreatePublicTestSuite) TestPostNodeScheduleCronRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestCronCreatePublicTestSuite(t *testing.T) { +func TestCronCreatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CronCreatePublicTestSuite)) } diff --git a/internal/controller/api/node/schedule/cron_delete_public_test.go b/internal/controller/api/node/schedule/cron_delete_public_test.go index 4c22c6da3..0a15962ca 100644 --- a/internal/controller/api/node/schedule/cron_delete_public_test.go +++ b/internal/controller/api/node/schedule/cron_delete_public_test.go @@ -31,6 +31,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -105,7 +107,7 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCron() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, nil, @@ -142,7 +144,7 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCron() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, nil, @@ -176,13 +178,13 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCron() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, }, nil) @@ -213,7 +215,7 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCron() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, "server2": { @@ -423,8 +425,7 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCronValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -438,15 +439,18 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCronValidationHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -454,8 +458,11 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCronValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -474,10 +481,7 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCronValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -491,8 +495,7 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCronRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -502,8 +505,10 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCronRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -520,8 +525,10 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCronRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -544,15 +551,18 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCronRBACHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -589,14 +599,13 @@ func (s *CronDeletePublicTestSuite) TestDeleteNodeScheduleCronRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestCronDeletePublicTestSuite(t *testing.T) { +func TestCronDeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CronDeletePublicTestSuite)) } diff --git a/internal/controller/api/node/schedule/cron_get_public_test.go b/internal/controller/api/node/schedule/cron_get_public_test.go index 013176016..0381a362c 100644 --- a/internal/controller/api/node/schedule/cron_get_public_test.go +++ b/internal/controller/api/node/schedule/cron_get_public_test.go @@ -450,8 +450,7 @@ func (s *CronGetPublicTestSuite) TestGetNodeScheduleCronByNameValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -468,8 +467,11 @@ func (s *CronGetPublicTestSuite) TestGetNodeScheduleCronByNameValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -477,8 +479,11 @@ func (s *CronGetPublicTestSuite) TestGetNodeScheduleCronByNameValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -497,10 +502,7 @@ func (s *CronGetPublicTestSuite) TestGetNodeScheduleCronByNameValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -514,8 +516,7 @@ func (s *CronGetPublicTestSuite) TestGetNodeScheduleCronByNameRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -525,8 +526,10 @@ func (s *CronGetPublicTestSuite) TestGetNodeScheduleCronByNameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -543,8 +546,10 @@ func (s *CronGetPublicTestSuite) TestGetNodeScheduleCronByNameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -570,8 +575,11 @@ func (s *CronGetPublicTestSuite) TestGetNodeScheduleCronByNameRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -608,14 +616,13 @@ func (s *CronGetPublicTestSuite) TestGetNodeScheduleCronByNameRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestCronGetPublicTestSuite(t *testing.T) { +func TestCronGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CronGetPublicTestSuite)) } diff --git a/internal/controller/api/node/schedule/cron_list_get_public_test.go b/internal/controller/api/node/schedule/cron_list_get_public_test.go index 0a2e02e6a..f991001dd 100644 --- a/internal/controller/api/node/schedule/cron_list_get_public_test.go +++ b/internal/controller/api/node/schedule/cron_list_get_public_test.go @@ -429,8 +429,7 @@ func (s *CronListGetPublicTestSuite) TestGetNodeScheduleCronValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -445,8 +444,11 @@ func (s *CronListGetPublicTestSuite) TestGetNodeScheduleCronValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -454,8 +456,11 @@ func (s *CronListGetPublicTestSuite) TestGetNodeScheduleCronValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -474,10 +479,7 @@ func (s *CronListGetPublicTestSuite) TestGetNodeScheduleCronValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -491,8 +493,7 @@ func (s *CronListGetPublicTestSuite) TestGetNodeScheduleCronRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -502,8 +503,10 @@ func (s *CronListGetPublicTestSuite) TestGetNodeScheduleCronRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -520,8 +523,10 @@ func (s *CronListGetPublicTestSuite) TestGetNodeScheduleCronRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -545,8 +550,11 @@ func (s *CronListGetPublicTestSuite) TestGetNodeScheduleCronRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -583,14 +591,13 @@ func (s *CronListGetPublicTestSuite) TestGetNodeScheduleCronRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestCronListGetPublicTestSuite(t *testing.T) { +func TestCronListGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CronListGetPublicTestSuite)) } diff --git a/internal/controller/api/node/schedule/cron_update_public_test.go b/internal/controller/api/node/schedule/cron_update_public_test.go index c7e8835bc..b8e7fc56c 100644 --- a/internal/controller/api/node/schedule/cron_update_public_test.go +++ b/internal/controller/api/node/schedule/cron_update_public_test.go @@ -32,6 +32,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -92,10 +94,10 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { Hostname: "server1", Name: "backup", Body: &gen.PutNodeScheduleCronJSONRequestBody{ - Schedule: strPtr("0 3 * * *"), - Object: strPtr("backup-v2-script"), - User: strPtr("admin"), - ContentType: (*gen.CronUpdateRequestContentType)(strPtr("template")), + Schedule: ptr.To("0 3 * * *"), + Object: ptr.To("backup-v2-script"), + User: ptr.To("admin"), + ContentType: (*gen.CronUpdateRequestContentType)(ptr.To("template")), Vars: &map[string]interface{}{"region": "us-east"}, }, }, @@ -113,7 +115,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, nil, @@ -151,7 +153,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { Hostname: "server1", Name: "backup", Body: &gen.PutNodeScheduleCronJSONRequestBody{ - Schedule: strPtr("0 3 * * *"), + Schedule: ptr.To("0 3 * * *"), }, }, setupMock: func() { @@ -168,7 +170,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, nil, @@ -188,7 +190,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { Hostname: "_all", Name: "backup", Body: &gen.PutNodeScheduleCronJSONRequestBody{ - Schedule: strPtr("0 3 * * *"), + Schedule: ptr.To("0 3 * * *"), }, }, setupMock: func() { @@ -204,13 +206,13 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, }, nil) @@ -228,7 +230,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { Hostname: "_all", Name: "backup", Body: &gen.PutNodeScheduleCronJSONRequestBody{ - Schedule: strPtr("0 3 * * *"), + Schedule: ptr.To("0 3 * * *"), }, }, setupMock: func() { @@ -244,7 +246,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, "server2": { @@ -275,7 +277,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { Hostname: "_all", Name: "backup", Body: &gen.PutNodeScheduleCronJSONRequestBody{ - Schedule: strPtr("0 3 * * *"), + Schedule: ptr.To("0 3 * * *"), }, }, setupMock: func() { @@ -311,7 +313,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { Hostname: "_all", Name: "backup", Body: &gen.PutNodeScheduleCronJSONRequestBody{ - Schedule: strPtr("0 3 * * *"), + Schedule: ptr.To("0 3 * * *"), }, }, setupMock: func() { @@ -336,7 +338,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { Hostname: "server1", Name: "backup", Body: &gen.PutNodeScheduleCronJSONRequestBody{ - Schedule: strPtr("short"), + Schedule: ptr.To("short"), }, }, setupMock: func() {}, @@ -353,7 +355,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { Hostname: "", Name: "backup", Body: &gen.PutNodeScheduleCronJSONRequestBody{ - Schedule: strPtr("0 3 * * *"), + Schedule: ptr.To("0 3 * * *"), }, }, setupMock: func() {}, @@ -370,7 +372,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { Hostname: "server1", Name: "nonexistent", Body: &gen.PutNodeScheduleCronJSONRequestBody{ - Schedule: strPtr("0 3 * * *"), + Schedule: ptr.To("0 3 * * *"), }, }, setupMock: func() { @@ -397,7 +399,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { Hostname: "server1", Name: "missing", Body: &gen.PutNodeScheduleCronJSONRequestBody{ - Schedule: strPtr("0 3 * * *"), + Schedule: ptr.To("0 3 * * *"), }, }, setupMock: func() { @@ -424,7 +426,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { Hostname: "server1", Name: "backup", Body: &gen.PutNodeScheduleCronJSONRequestBody{ - Schedule: strPtr("0 3 * * *"), + Schedule: ptr.To("0 3 * * *"), }, }, setupMock: func() { @@ -463,7 +465,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCron() { Hostname: "server1", Name: "backup", Body: &gen.PutNodeScheduleCronJSONRequestBody{ - Schedule: strPtr("0 3 * * *"), + Schedule: ptr.To("0 3 * * *"), }, }, setupMock: func() { @@ -501,8 +503,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCronValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -517,15 +518,18 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCronValidationHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when empty body returns 400", @@ -534,8 +538,11 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCronValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "at least one field"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "at least one field") + }, }, { name: "when invalid cron schedule", @@ -544,8 +551,11 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCronValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Schedule"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Schedule") + }, }, { name: "when target agent not found", @@ -554,8 +564,11 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCronValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -579,10 +592,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCronValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -596,8 +606,7 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCronRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -607,8 +616,10 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCronRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -625,8 +636,10 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCronRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -649,15 +662,18 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCronRBACHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"backup","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -695,14 +711,13 @@ func (s *CronUpdatePublicTestSuite) TestPutNodeScheduleCronRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestCronUpdatePublicTestSuite(t *testing.T) { +func TestCronUpdatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CronUpdatePublicTestSuite)) } diff --git a/internal/controller/api/node/schedule/handler_public_test.go b/internal/controller/api/node/schedule/handler_public_test.go index ab9998cda..4d89538e4 100644 --- a/internal/controller/api/node/schedule/handler_public_test.go +++ b/internal/controller/api/node/schedule/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/schedule/support_public_test.go b/internal/controller/api/node/schedule/support_public_test.go deleted file mode 100644 index 97194792b..000000000 --- a/internal/controller/api/node/schedule/support_public_test.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2026 John Dewey - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -package schedule_test - -import ( - "github.com/osapi-io/osapi/internal/controller/api/node/schedule/gen" -) - -func strPtr( - s string, -) *string { - return &s -} - -func boolPtr( - b bool, -) *bool { - return &b -} - -func intervalPtr( - i gen.CronCreateRequestInterval, -) *gen.CronCreateRequestInterval { - return &i -} diff --git a/internal/controller/api/node/service/handler_public_test.go b/internal/controller/api/node/service/handler_public_test.go index 1de996825..74ad77375 100644 --- a/internal/controller/api/node/service/handler_public_test.go +++ b/internal/controller/api/node/service/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/service/service_create_post_public_test.go b/internal/controller/api/node/service/service_create_post_public_test.go index 77af75e62..1fd7042e6 100644 --- a/internal/controller/api/node/service/service_create_post_public_test.go +++ b/internal/controller/api/node/service/service_create_post_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -108,7 +110,7 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeService() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, nil, @@ -148,7 +150,7 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeService() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, nil, @@ -297,13 +299,13 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeService() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, "server2": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, }, nil) @@ -337,7 +339,7 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeService() { "server1": { JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: nil, }, }, nil) @@ -466,8 +468,7 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeServiceValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -482,15 +483,18 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeServiceValidationHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -499,8 +503,11 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeServiceValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, { name: "when invalid body empty name", @@ -509,8 +516,10 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeServiceValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, } @@ -534,10 +543,7 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeServiceValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -551,8 +557,7 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeServiceRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -561,8 +566,10 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeServiceRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -579,8 +586,10 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeServiceRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -603,15 +612,18 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeServiceRBACHTTP() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, nil, ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -649,14 +661,13 @@ func (s *ServiceCreatePostPublicTestSuite) TestPostNodeServiceRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestServiceCreatePostPublicTestSuite(t *testing.T) { +func TestServiceCreatePostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServiceCreatePostPublicTestSuite)) } diff --git a/internal/controller/api/node/service/service_delete_public_test.go b/internal/controller/api/node/service/service_delete_public_test.go index 1c9b782f1..72359bf3a 100644 --- a/internal/controller/api/node/service/service_delete_public_test.go +++ b/internal/controller/api/node/service/service_delete_public_test.go @@ -30,6 +30,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -94,7 +96,7 @@ func (s *ServiceDeletePublicTestSuite) TestDeleteNodeService() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceDelete, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, nil) }, @@ -118,7 +120,7 @@ func (s *ServiceDeletePublicTestSuite) TestDeleteNodeService() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceDelete, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), Data: nil, + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: nil, }, nil) }, validateFunc: func(resp gen.DeleteNodeServiceResponseObject) { @@ -183,12 +185,12 @@ func (s *ServiceDeletePublicTestSuite) TestDeleteNodeService() { Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ "server1": { Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, "server2": { Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, }, nil) @@ -206,7 +208,7 @@ func (s *ServiceDeletePublicTestSuite) TestDeleteNodeService() { s.mockJobClient.EXPECT(). ModifyBroadcast(gomock.Any(), "_all", "node", job.OperationServiceDelete, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ - "server1": {Hostname: "server1", Changed: boolPtr(true), Data: nil}, + "server1": {Hostname: "server1", Changed: ptr.To(true), Data: nil}, }, nil) }, validateFunc: func(resp gen.DeleteNodeServiceResponseObject) { @@ -290,8 +292,7 @@ func (s *ServiceDeletePublicTestSuite) TestDeleteNodeServiceValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -301,13 +302,16 @@ func (s *ServiceDeletePublicTestSuite) TestDeleteNodeServiceValidationHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceDelete, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -315,8 +319,11 @@ func (s *ServiceDeletePublicTestSuite) TestDeleteNodeServiceValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -330,10 +337,7 @@ func (s *ServiceDeletePublicTestSuite) TestDeleteNodeServiceValidationHTTP() { req := httptest.NewRequest(http.MethodDelete, tc.path, nil) rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -346,13 +350,16 @@ func (s *ServiceDeletePublicTestSuite) TestDeleteNodeServiceRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { - name: "when no token returns 401", setupAuth: func(_ *http.Request) {}, + name: "when no token returns 401", + setupAuth: func(_ *http.Request) {}, setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -367,7 +374,10 @@ func (s *ServiceDeletePublicTestSuite) TestDeleteNodeServiceRBACHTTP() { req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -386,12 +396,16 @@ func (s *ServiceDeletePublicTestSuite) TestDeleteNodeServiceRBACHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceDelete, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -423,14 +437,13 @@ func (s *ServiceDeletePublicTestSuite) TestDeleteNodeServiceRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestServiceDeletePublicTestSuite(t *testing.T) { +func TestServiceDeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServiceDeletePublicTestSuite)) } diff --git a/internal/controller/api/node/service/service_disable_post_public_test.go b/internal/controller/api/node/service/service_disable_post_public_test.go index 4b9fe93da..95fdec75a 100644 --- a/internal/controller/api/node/service/service_disable_post_public_test.go +++ b/internal/controller/api/node/service/service_disable_post_public_test.go @@ -30,6 +30,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -94,7 +96,7 @@ func (s *ServiceDisablePostPublicTestSuite) TestPostNodeServiceDisable() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceDisable, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) }, @@ -118,7 +120,7 @@ func (s *ServiceDisablePostPublicTestSuite) TestPostNodeServiceDisable() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceDisable, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), Data: nil, + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: nil, }, nil) }, validateFunc: func(resp gen.PostNodeServiceDisableResponseObject) { @@ -186,12 +188,12 @@ func (s *ServiceDisablePostPublicTestSuite) TestPostNodeServiceDisable() { Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ "server1": { Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, "server2": { Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, }, nil) @@ -212,7 +214,7 @@ func (s *ServiceDisablePostPublicTestSuite) TestPostNodeServiceDisable() { s.mockJobClient.EXPECT(). ModifyBroadcast(gomock.Any(), "_all", "node", job.OperationServiceDisable, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ - "server1": {Hostname: "server1", Changed: boolPtr(true), Data: nil}, + "server1": {Hostname: "server1", Changed: ptr.To(true), Data: nil}, }, nil) }, validateFunc: func(resp gen.PostNodeServiceDisableResponseObject) { @@ -305,8 +307,7 @@ func (s *ServiceDisablePostPublicTestSuite) TestPostNodeServiceDisableValidation name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -316,13 +317,16 @@ func (s *ServiceDisablePostPublicTestSuite) TestPostNodeServiceDisableValidation mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceDisable, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -330,8 +334,11 @@ func (s *ServiceDisablePostPublicTestSuite) TestPostNodeServiceDisableValidation setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -345,10 +352,7 @@ func (s *ServiceDisablePostPublicTestSuite) TestPostNodeServiceDisableValidation req := httptest.NewRequest(http.MethodPost, tc.path, nil) rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -361,13 +365,16 @@ func (s *ServiceDisablePostPublicTestSuite) TestPostNodeServiceDisableRBACHTTP() name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { - name: "when no token returns 401", setupAuth: func(_ *http.Request) {}, + name: "when no token returns 401", + setupAuth: func(_ *http.Request) {}, setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -382,7 +389,10 @@ func (s *ServiceDisablePostPublicTestSuite) TestPostNodeServiceDisableRBACHTTP() req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -401,12 +411,16 @@ func (s *ServiceDisablePostPublicTestSuite) TestPostNodeServiceDisableRBACHTTP() mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceDisable, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -438,14 +452,13 @@ func (s *ServiceDisablePostPublicTestSuite) TestPostNodeServiceDisableRBACHTTP() tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestServiceDisablePostPublicTestSuite(t *testing.T) { +func TestServiceDisablePostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServiceDisablePostPublicTestSuite)) } diff --git a/internal/controller/api/node/service/service_enable_post_public_test.go b/internal/controller/api/node/service/service_enable_post_public_test.go index ebc6e679d..83c46c526 100644 --- a/internal/controller/api/node/service/service_enable_post_public_test.go +++ b/internal/controller/api/node/service/service_enable_post_public_test.go @@ -30,6 +30,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -94,7 +96,7 @@ func (s *ServiceEnablePostPublicTestSuite) TestPostNodeServiceEnable() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceEnable, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) }, @@ -118,7 +120,7 @@ func (s *ServiceEnablePostPublicTestSuite) TestPostNodeServiceEnable() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceEnable, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), Data: nil, + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: nil, }, nil) }, validateFunc: func(resp gen.PostNodeServiceEnableResponseObject) { @@ -186,12 +188,12 @@ func (s *ServiceEnablePostPublicTestSuite) TestPostNodeServiceEnable() { Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ "server1": { Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, "server2": { Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, }, nil) @@ -212,7 +214,7 @@ func (s *ServiceEnablePostPublicTestSuite) TestPostNodeServiceEnable() { s.mockJobClient.EXPECT(). ModifyBroadcast(gomock.Any(), "_all", "node", job.OperationServiceEnable, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ - "server1": {Hostname: "server1", Changed: boolPtr(true), Data: nil}, + "server1": {Hostname: "server1", Changed: ptr.To(true), Data: nil}, }, nil) }, validateFunc: func(resp gen.PostNodeServiceEnableResponseObject) { @@ -305,8 +307,7 @@ func (s *ServiceEnablePostPublicTestSuite) TestPostNodeServiceEnableValidationHT name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -316,13 +317,16 @@ func (s *ServiceEnablePostPublicTestSuite) TestPostNodeServiceEnableValidationHT mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceEnable, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -330,8 +334,11 @@ func (s *ServiceEnablePostPublicTestSuite) TestPostNodeServiceEnableValidationHT setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -345,10 +352,7 @@ func (s *ServiceEnablePostPublicTestSuite) TestPostNodeServiceEnableValidationHT req := httptest.NewRequest(http.MethodPost, tc.path, nil) rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -361,13 +365,16 @@ func (s *ServiceEnablePostPublicTestSuite) TestPostNodeServiceEnableRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { - name: "when no token returns 401", setupAuth: func(_ *http.Request) {}, + name: "when no token returns 401", + setupAuth: func(_ *http.Request) {}, setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -382,7 +389,10 @@ func (s *ServiceEnablePostPublicTestSuite) TestPostNodeServiceEnableRBACHTTP() { req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -401,12 +411,16 @@ func (s *ServiceEnablePostPublicTestSuite) TestPostNodeServiceEnableRBACHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceEnable, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -438,14 +452,13 @@ func (s *ServiceEnablePostPublicTestSuite) TestPostNodeServiceEnableRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestServiceEnablePostPublicTestSuite(t *testing.T) { +func TestServiceEnablePostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServiceEnablePostPublicTestSuite)) } diff --git a/internal/controller/api/node/service/service_get_public_test.go b/internal/controller/api/node/service/service_get_public_test.go index 9f3ca9ccf..fb291cfc0 100644 --- a/internal/controller/api/node/service/service_get_public_test.go +++ b/internal/controller/api/node/service/service_get_public_test.go @@ -419,8 +419,7 @@ func (s *ServiceGetPublicTestSuite) TestGetNodeServiceByNameValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -442,8 +441,11 @@ func (s *ServiceGetPublicTestSuite) TestGetNodeServiceByNameValidationHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -451,8 +453,11 @@ func (s *ServiceGetPublicTestSuite) TestGetNodeServiceByNameValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -475,10 +480,7 @@ func (s *ServiceGetPublicTestSuite) TestGetNodeServiceByNameValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -492,8 +494,7 @@ func (s *ServiceGetPublicTestSuite) TestGetNodeServiceByNameRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -502,8 +503,10 @@ func (s *ServiceGetPublicTestSuite) TestGetNodeServiceByNameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -520,8 +523,10 @@ func (s *ServiceGetPublicTestSuite) TestGetNodeServiceByNameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -552,8 +557,11 @@ func (s *ServiceGetPublicTestSuite) TestGetNodeServiceByNameRBACHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -590,14 +598,13 @@ func (s *ServiceGetPublicTestSuite) TestGetNodeServiceByNameRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestServiceGetPublicTestSuite(t *testing.T) { +func TestServiceGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServiceGetPublicTestSuite)) } diff --git a/internal/controller/api/node/service/service_list_get_public_test.go b/internal/controller/api/node/service/service_list_get_public_test.go index 0fda2609a..b5ed42ff1 100644 --- a/internal/controller/api/node/service/service_list_get_public_test.go +++ b/internal/controller/api/node/service/service_list_get_public_test.go @@ -363,8 +363,7 @@ func (s *ServiceListGetPublicTestSuite) TestGetNodeServiceValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -384,8 +383,11 @@ func (s *ServiceListGetPublicTestSuite) TestGetNodeServiceValidationHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -393,8 +395,11 @@ func (s *ServiceListGetPublicTestSuite) TestGetNodeServiceValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -417,10 +422,7 @@ func (s *ServiceListGetPublicTestSuite) TestGetNodeServiceValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -434,8 +436,7 @@ func (s *ServiceListGetPublicTestSuite) TestGetNodeServiceRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -444,8 +445,10 @@ func (s *ServiceListGetPublicTestSuite) TestGetNodeServiceRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -462,8 +465,10 @@ func (s *ServiceListGetPublicTestSuite) TestGetNodeServiceRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -492,8 +497,11 @@ func (s *ServiceListGetPublicTestSuite) TestGetNodeServiceRBACHTTP() { ) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -530,14 +538,13 @@ func (s *ServiceListGetPublicTestSuite) TestGetNodeServiceRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestServiceListGetPublicTestSuite(t *testing.T) { +func TestServiceListGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServiceListGetPublicTestSuite)) } diff --git a/internal/controller/api/node/service/service_restart_post_public_test.go b/internal/controller/api/node/service/service_restart_post_public_test.go index dd89ec8b4..111ba991b 100644 --- a/internal/controller/api/node/service/service_restart_post_public_test.go +++ b/internal/controller/api/node/service/service_restart_post_public_test.go @@ -30,6 +30,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -94,7 +96,7 @@ func (s *ServiceRestartPostPublicTestSuite) TestPostNodeServiceRestart() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceRestart, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) }, @@ -118,7 +120,7 @@ func (s *ServiceRestartPostPublicTestSuite) TestPostNodeServiceRestart() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceRestart, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), Data: nil, + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: nil, }, nil) }, validateFunc: func(resp gen.PostNodeServiceRestartResponseObject) { @@ -186,12 +188,12 @@ func (s *ServiceRestartPostPublicTestSuite) TestPostNodeServiceRestart() { Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ "server1": { Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, "server2": { Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, }, nil) @@ -212,7 +214,7 @@ func (s *ServiceRestartPostPublicTestSuite) TestPostNodeServiceRestart() { s.mockJobClient.EXPECT(). ModifyBroadcast(gomock.Any(), "_all", "node", job.OperationServiceRestart, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ - "server1": {Hostname: "server1", Changed: boolPtr(true), Data: nil}, + "server1": {Hostname: "server1", Changed: ptr.To(true), Data: nil}, }, nil) }, validateFunc: func(resp gen.PostNodeServiceRestartResponseObject) { @@ -305,8 +307,7 @@ func (s *ServiceRestartPostPublicTestSuite) TestPostNodeServiceRestartValidation name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -316,13 +317,16 @@ func (s *ServiceRestartPostPublicTestSuite) TestPostNodeServiceRestartValidation mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceRestart, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -330,8 +334,11 @@ func (s *ServiceRestartPostPublicTestSuite) TestPostNodeServiceRestartValidation setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -345,10 +352,7 @@ func (s *ServiceRestartPostPublicTestSuite) TestPostNodeServiceRestartValidation req := httptest.NewRequest(http.MethodPost, tc.path, nil) rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -361,13 +365,16 @@ func (s *ServiceRestartPostPublicTestSuite) TestPostNodeServiceRestartRBACHTTP() name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { - name: "when no token returns 401", setupAuth: func(_ *http.Request) {}, + name: "when no token returns 401", + setupAuth: func(_ *http.Request) {}, setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -382,7 +389,10 @@ func (s *ServiceRestartPostPublicTestSuite) TestPostNodeServiceRestartRBACHTTP() req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -401,12 +411,16 @@ func (s *ServiceRestartPostPublicTestSuite) TestPostNodeServiceRestartRBACHTTP() mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceRestart, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -438,14 +452,13 @@ func (s *ServiceRestartPostPublicTestSuite) TestPostNodeServiceRestartRBACHTTP() tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestServiceRestartPostPublicTestSuite(t *testing.T) { +func TestServiceRestartPostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServiceRestartPostPublicTestSuite)) } diff --git a/internal/controller/api/node/service/service_start_post_public_test.go b/internal/controller/api/node/service/service_start_post_public_test.go index 1a31f3f25..cc2ee8002 100644 --- a/internal/controller/api/node/service/service_start_post_public_test.go +++ b/internal/controller/api/node/service/service_start_post_public_test.go @@ -30,6 +30,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -94,7 +96,7 @@ func (s *ServiceStartPostPublicTestSuite) TestPostNodeServiceStart() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceStart, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) }, @@ -118,7 +120,7 @@ func (s *ServiceStartPostPublicTestSuite) TestPostNodeServiceStart() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceStart, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), Data: nil, + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: nil, }, nil) }, validateFunc: func(resp gen.PostNodeServiceStartResponseObject) { @@ -183,12 +185,12 @@ func (s *ServiceStartPostPublicTestSuite) TestPostNodeServiceStart() { Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ "server1": { Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, "server2": { Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, }, nil) @@ -206,7 +208,7 @@ func (s *ServiceStartPostPublicTestSuite) TestPostNodeServiceStart() { s.mockJobClient.EXPECT(). ModifyBroadcast(gomock.Any(), "_all", "node", job.OperationServiceStart, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ - "server1": {Hostname: "server1", Changed: boolPtr(true), Data: nil}, + "server1": {Hostname: "server1", Changed: ptr.To(true), Data: nil}, }, nil) }, validateFunc: func(resp gen.PostNodeServiceStartResponseObject) { @@ -290,8 +292,7 @@ func (s *ServiceStartPostPublicTestSuite) TestPostNodeServiceStartValidationHTTP name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -301,13 +302,16 @@ func (s *ServiceStartPostPublicTestSuite) TestPostNodeServiceStartValidationHTTP mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceStart, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -315,8 +319,11 @@ func (s *ServiceStartPostPublicTestSuite) TestPostNodeServiceStartValidationHTTP setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -330,10 +337,7 @@ func (s *ServiceStartPostPublicTestSuite) TestPostNodeServiceStartValidationHTTP req := httptest.NewRequest(http.MethodPost, tc.path, nil) rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -346,13 +350,16 @@ func (s *ServiceStartPostPublicTestSuite) TestPostNodeServiceStartRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { - name: "when no token returns 401", setupAuth: func(_ *http.Request) {}, + name: "when no token returns 401", + setupAuth: func(_ *http.Request) {}, setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -367,7 +374,10 @@ func (s *ServiceStartPostPublicTestSuite) TestPostNodeServiceStartRBACHTTP() { req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -386,12 +396,16 @@ func (s *ServiceStartPostPublicTestSuite) TestPostNodeServiceStartRBACHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceStart, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -421,14 +435,13 @@ func (s *ServiceStartPostPublicTestSuite) TestPostNodeServiceStartRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestServiceStartPostPublicTestSuite(t *testing.T) { +func TestServiceStartPostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServiceStartPostPublicTestSuite)) } diff --git a/internal/controller/api/node/service/service_stop_post_public_test.go b/internal/controller/api/node/service/service_stop_post_public_test.go index d91bf3c35..c50ff50c5 100644 --- a/internal/controller/api/node/service/service_stop_post_public_test.go +++ b/internal/controller/api/node/service/service_stop_post_public_test.go @@ -30,6 +30,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -94,7 +96,7 @@ func (s *ServiceStopPostPublicTestSuite) TestPostNodeServiceStop() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceStop, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) }, @@ -118,7 +120,7 @@ func (s *ServiceStopPostPublicTestSuite) TestPostNodeServiceStop() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceStop, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), Data: nil, + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: nil, }, nil) }, validateFunc: func(resp gen.PostNodeServiceStopResponseObject) { @@ -183,12 +185,12 @@ func (s *ServiceStopPostPublicTestSuite) TestPostNodeServiceStop() { Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ "server1": { Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, "server2": { Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, }, nil) @@ -206,7 +208,7 @@ func (s *ServiceStopPostPublicTestSuite) TestPostNodeServiceStop() { s.mockJobClient.EXPECT(). ModifyBroadcast(gomock.Any(), "_all", "node", job.OperationServiceStop, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ - "server1": {Hostname: "server1", Changed: boolPtr(true), Data: nil}, + "server1": {Hostname: "server1", Changed: ptr.To(true), Data: nil}, }, nil) }, validateFunc: func(resp gen.PostNodeServiceStopResponseObject) { @@ -290,8 +292,7 @@ func (s *ServiceStopPostPublicTestSuite) TestPostNodeServiceStopValidationHTTP() name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -301,13 +302,16 @@ func (s *ServiceStopPostPublicTestSuite) TestPostNodeServiceStopValidationHTTP() mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceStop, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -315,8 +319,11 @@ func (s *ServiceStopPostPublicTestSuite) TestPostNodeServiceStopValidationHTTP() setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -330,10 +337,7 @@ func (s *ServiceStopPostPublicTestSuite) TestPostNodeServiceStopValidationHTTP() req := httptest.NewRequest(http.MethodPost, tc.path, nil) rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -346,13 +350,16 @@ func (s *ServiceStopPostPublicTestSuite) TestPostNodeServiceStopRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { - name: "when no token returns 401", setupAuth: func(_ *http.Request) {}, + name: "when no token returns 401", + setupAuth: func(_ *http.Request) {}, setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -367,7 +374,10 @@ func (s *ServiceStopPostPublicTestSuite) TestPostNodeServiceStopRBACHTTP() { req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) }, setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -386,12 +396,16 @@ func (s *ServiceStopPostPublicTestSuite) TestPostNodeServiceStopRBACHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceStop, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"nginx.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -421,14 +435,13 @@ func (s *ServiceStopPostPublicTestSuite) TestPostNodeServiceStopRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestServiceStopPostPublicTestSuite(t *testing.T) { +func TestServiceStopPostPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServiceStopPostPublicTestSuite)) } diff --git a/internal/controller/api/node/service/service_update_put_public_test.go b/internal/controller/api/node/service/service_update_put_public_test.go index 139a5a751..6978ef015 100644 --- a/internal/controller/api/node/service/service_update_put_public_test.go +++ b/internal/controller/api/node/service/service_update_put_public_test.go @@ -32,6 +32,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -103,7 +105,7 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeService() { &job.Response{ JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, nil, @@ -131,7 +133,7 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeService() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceUpdate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), Data: nil, + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: nil, }, nil) }, validateFunc: func(resp gen.PutNodeServiceResponseObject) { @@ -257,12 +259,12 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeService() { Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ "server1": { Hostname: "server1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, "server2": { Hostname: "server2", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, }, nil) @@ -284,7 +286,7 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeService() { s.mockJobClient.EXPECT(). ModifyBroadcast(gomock.Any(), "_all", "node", job.OperationServiceUpdate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", map[string]*job.Response{ - "server1": {Hostname: "server1", Changed: boolPtr(true), Data: nil}, + "server1": {Hostname: "server1", Changed: ptr.To(true), Data: nil}, }, nil) }, validateFunc: func(resp gen.PutNodeServiceResponseObject) { @@ -378,8 +380,7 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeServiceValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -390,13 +391,16 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeServiceValidationHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceUpdate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -405,8 +409,11 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeServiceValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, { name: "when invalid body empty object", @@ -415,8 +422,10 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeServiceValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + }, }, } @@ -431,10 +440,7 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeServiceValidationHTTP() { req.Header.Set("Content-Type", "application/json") rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -447,8 +453,7 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeServiceRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -456,8 +461,10 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeServiceRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -474,8 +481,10 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeServiceRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -494,13 +503,16 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeServiceRBACHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "node", job.OperationServiceUpdate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: boolPtr(true), + JobID: "550e8400-e29b-41d4-a716-446655440000", Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"my-app.service","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -533,14 +545,13 @@ func (s *ServiceUpdatePutPublicTestSuite) TestPutNodeServiceRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestServiceUpdatePutPublicTestSuite(t *testing.T) { +func TestServiceUpdatePutPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServiceUpdatePutPublicTestSuite)) } diff --git a/internal/controller/api/node/service/support_public_test.go b/internal/controller/api/node/service/support_public_test.go deleted file mode 100644 index 2445d5ad6..000000000 --- a/internal/controller/api/node/service/support_public_test.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2026 John Dewey - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -package service_test - -func boolPtr( - b bool, -) *bool { - return &b -} diff --git a/internal/controller/api/node/sysctl/handler_public_test.go b/internal/controller/api/node/sysctl/handler_public_test.go index 4ab7ab14e..d688b1285 100644 --- a/internal/controller/api/node/sysctl/handler_public_test.go +++ b/internal/controller/api/node/sysctl/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/sysctl/sysctl_create_public_test.go b/internal/controller/api/node/sysctl/sysctl_create_public_test.go index 1ad4e47d0..4afb74fe9 100644 --- a/internal/controller/api/node/sysctl/sysctl_create_public_test.go +++ b/internal/controller/api/node/sysctl/sysctl_create_public_test.go @@ -406,8 +406,7 @@ func (s *SysctlCreatePublicTestSuite) TestPostNodeSysctlValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -426,8 +425,11 @@ func (s *SysctlCreatePublicTestSuite) TestPostNodeSysctlValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when missing key returns 400", @@ -436,8 +438,11 @@ func (s *SysctlCreatePublicTestSuite) TestPostNodeSysctlValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Key"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Key") + }, }, { name: "when target agent not found", @@ -446,8 +451,11 @@ func (s *SysctlCreatePublicTestSuite) TestPostNodeSysctlValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -471,10 +479,7 @@ func (s *SysctlCreatePublicTestSuite) TestPostNodeSysctlValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -489,8 +494,7 @@ func (s *SysctlCreatePublicTestSuite) TestPostNodeSysctlRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -500,8 +504,10 @@ func (s *SysctlCreatePublicTestSuite) TestPostNodeSysctlRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -518,8 +524,10 @@ func (s *SysctlCreatePublicTestSuite) TestPostNodeSysctlRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -546,8 +554,11 @@ func (s *SysctlCreatePublicTestSuite) TestPostNodeSysctlRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -585,14 +596,13 @@ func (s *SysctlCreatePublicTestSuite) TestPostNodeSysctlRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestSysctlCreatePublicTestSuite(t *testing.T) { +func TestSysctlCreatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SysctlCreatePublicTestSuite)) } diff --git a/internal/controller/api/node/sysctl/sysctl_delete_public_test.go b/internal/controller/api/node/sysctl/sysctl_delete_public_test.go index 911c115c6..e32975b59 100644 --- a/internal/controller/api/node/sysctl/sysctl_delete_public_test.go +++ b/internal/controller/api/node/sysctl/sysctl_delete_public_test.go @@ -380,8 +380,7 @@ func (s *SysctlDeletePublicTestSuite) TestDeleteNodeSysctlValidationHTTP() { path string method string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -400,8 +399,11 @@ func (s *SysctlDeletePublicTestSuite) TestDeleteNodeSysctlValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -410,8 +412,11 @@ func (s *SysctlDeletePublicTestSuite) TestDeleteNodeSysctlValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -430,10 +435,7 @@ func (s *SysctlDeletePublicTestSuite) TestDeleteNodeSysctlValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -448,8 +450,7 @@ func (s *SysctlDeletePublicTestSuite) TestDeleteNodeSysctlRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -459,8 +460,10 @@ func (s *SysctlDeletePublicTestSuite) TestDeleteNodeSysctlRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -477,8 +480,10 @@ func (s *SysctlDeletePublicTestSuite) TestDeleteNodeSysctlRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -505,8 +510,11 @@ func (s *SysctlDeletePublicTestSuite) TestDeleteNodeSysctlRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -543,14 +551,13 @@ func (s *SysctlDeletePublicTestSuite) TestDeleteNodeSysctlRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestSysctlDeletePublicTestSuite(t *testing.T) { +func TestSysctlDeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SysctlDeletePublicTestSuite)) } diff --git a/internal/controller/api/node/sysctl/sysctl_get_public_test.go b/internal/controller/api/node/sysctl/sysctl_get_public_test.go index e23359d46..a7a478ae7 100644 --- a/internal/controller/api/node/sysctl/sysctl_get_public_test.go +++ b/internal/controller/api/node/sysctl/sysctl_get_public_test.go @@ -448,8 +448,7 @@ func (s *SysctlGetPublicTestSuite) TestGetNodeSysctlByKeyValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -466,8 +465,11 @@ func (s *SysctlGetPublicTestSuite) TestGetNodeSysctlByKeyValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -475,8 +477,11 @@ func (s *SysctlGetPublicTestSuite) TestGetNodeSysctlByKeyValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -495,10 +500,7 @@ func (s *SysctlGetPublicTestSuite) TestGetNodeSysctlByKeyValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -512,8 +514,7 @@ func (s *SysctlGetPublicTestSuite) TestGetNodeSysctlByKeyRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -523,8 +524,10 @@ func (s *SysctlGetPublicTestSuite) TestGetNodeSysctlByKeyRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -541,8 +544,10 @@ func (s *SysctlGetPublicTestSuite) TestGetNodeSysctlByKeyRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -568,8 +573,11 @@ func (s *SysctlGetPublicTestSuite) TestGetNodeSysctlByKeyRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -606,14 +614,13 @@ func (s *SysctlGetPublicTestSuite) TestGetNodeSysctlByKeyRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestSysctlGetPublicTestSuite(t *testing.T) { +func TestSysctlGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SysctlGetPublicTestSuite)) } diff --git a/internal/controller/api/node/sysctl/sysctl_list_get_public_test.go b/internal/controller/api/node/sysctl/sysctl_list_get_public_test.go index 50dd2df48..796880a04 100644 --- a/internal/controller/api/node/sysctl/sysctl_list_get_public_test.go +++ b/internal/controller/api/node/sysctl/sysctl_list_get_public_test.go @@ -387,8 +387,7 @@ func (s *SysctlListGetPublicTestSuite) TestGetNodeSysctlValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -403,8 +402,11 @@ func (s *SysctlListGetPublicTestSuite) TestGetNodeSysctlValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -412,8 +414,11 @@ func (s *SysctlListGetPublicTestSuite) TestGetNodeSysctlValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -432,10 +437,7 @@ func (s *SysctlListGetPublicTestSuite) TestGetNodeSysctlValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -449,8 +451,7 @@ func (s *SysctlListGetPublicTestSuite) TestGetNodeSysctlRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -460,8 +461,10 @@ func (s *SysctlListGetPublicTestSuite) TestGetNodeSysctlRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -478,8 +481,10 @@ func (s *SysctlListGetPublicTestSuite) TestGetNodeSysctlRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -503,8 +508,11 @@ func (s *SysctlListGetPublicTestSuite) TestGetNodeSysctlRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -541,14 +549,13 @@ func (s *SysctlListGetPublicTestSuite) TestGetNodeSysctlRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestSysctlListGetPublicTestSuite(t *testing.T) { +func TestSysctlListGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SysctlListGetPublicTestSuite)) } diff --git a/internal/controller/api/node/sysctl/sysctl_update_public_test.go b/internal/controller/api/node/sysctl/sysctl_update_public_test.go index 19bcb0284..fb8c51df3 100644 --- a/internal/controller/api/node/sysctl/sysctl_update_public_test.go +++ b/internal/controller/api/node/sysctl/sysctl_update_public_test.go @@ -417,8 +417,7 @@ func (s *SysctlUpdatePublicTestSuite) TestPutNodeSysctlValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -437,8 +436,11 @@ func (s *SysctlUpdatePublicTestSuite) TestPutNodeSysctlValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when missing value returns 400", @@ -447,8 +449,11 @@ func (s *SysctlUpdatePublicTestSuite) TestPutNodeSysctlValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Value"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Value") + }, }, { name: "when target agent not found", @@ -457,8 +462,11 @@ func (s *SysctlUpdatePublicTestSuite) TestPutNodeSysctlValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -482,10 +490,7 @@ func (s *SysctlUpdatePublicTestSuite) TestPutNodeSysctlValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -500,8 +505,7 @@ func (s *SysctlUpdatePublicTestSuite) TestPutNodeSysctlRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -511,8 +515,10 @@ func (s *SysctlUpdatePublicTestSuite) TestPutNodeSysctlRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -529,8 +535,10 @@ func (s *SysctlUpdatePublicTestSuite) TestPutNodeSysctlRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -557,8 +565,11 @@ func (s *SysctlUpdatePublicTestSuite) TestPutNodeSysctlRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -596,14 +607,13 @@ func (s *SysctlUpdatePublicTestSuite) TestPutNodeSysctlRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestSysctlUpdatePublicTestSuite(t *testing.T) { +func TestSysctlUpdatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SysctlUpdatePublicTestSuite)) } diff --git a/internal/controller/api/node/timezone/timezone_get_public_test.go b/internal/controller/api/node/timezone/timezone_get_public_test.go index 750ca3b41..fae846347 100644 --- a/internal/controller/api/node/timezone/timezone_get_public_test.go +++ b/internal/controller/api/node/timezone/timezone_get_public_test.go @@ -345,8 +345,7 @@ func (s *TimezoneGetPublicTestSuite) TestGetNodeTimezoneValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -363,8 +362,11 @@ func (s *TimezoneGetPublicTestSuite) TestGetNodeTimezoneValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -372,8 +374,11 @@ func (s *TimezoneGetPublicTestSuite) TestGetNodeTimezoneValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -392,10 +397,7 @@ func (s *TimezoneGetPublicTestSuite) TestGetNodeTimezoneValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -409,8 +411,7 @@ func (s *TimezoneGetPublicTestSuite) TestGetNodeTimezoneRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -420,8 +421,10 @@ func (s *TimezoneGetPublicTestSuite) TestGetNodeTimezoneRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -438,8 +441,10 @@ func (s *TimezoneGetPublicTestSuite) TestGetNodeTimezoneRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -465,8 +470,11 @@ func (s *TimezoneGetPublicTestSuite) TestGetNodeTimezoneRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -503,14 +511,13 @@ func (s *TimezoneGetPublicTestSuite) TestGetNodeTimezoneRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestTimezoneGetPublicTestSuite(t *testing.T) { +func TestTimezoneGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(TimezoneGetPublicTestSuite)) } diff --git a/internal/controller/api/node/timezone/timezone_update_public_test.go b/internal/controller/api/node/timezone/timezone_update_public_test.go index fd1ec4ed5..cdc47765e 100644 --- a/internal/controller/api/node/timezone/timezone_update_public_test.go +++ b/internal/controller/api/node/timezone/timezone_update_public_test.go @@ -361,8 +361,7 @@ func (s *TimezoneUpdatePublicTestSuite) TestPutNodeTimezoneValidationHTTP() { path string body string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -381,8 +380,11 @@ func (s *TimezoneUpdatePublicTestSuite) TestPutNodeTimezoneValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when missing timezone returns 400", @@ -391,8 +393,11 @@ func (s *TimezoneUpdatePublicTestSuite) TestPutNodeTimezoneValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "Timezone"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "Timezone") + }, }, { name: "when target agent not found", @@ -401,8 +406,11 @@ func (s *TimezoneUpdatePublicTestSuite) TestPutNodeTimezoneValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -426,10 +434,7 @@ func (s *TimezoneUpdatePublicTestSuite) TestPutNodeTimezoneValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -444,8 +449,7 @@ func (s *TimezoneUpdatePublicTestSuite) TestPutNodeTimezoneRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -455,8 +459,10 @@ func (s *TimezoneUpdatePublicTestSuite) TestPutNodeTimezoneRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -473,8 +479,10 @@ func (s *TimezoneUpdatePublicTestSuite) TestPutNodeTimezoneRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -501,8 +509,11 @@ func (s *TimezoneUpdatePublicTestSuite) TestPutNodeTimezoneRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -540,14 +551,13 @@ func (s *TimezoneUpdatePublicTestSuite) TestPutNodeTimezoneRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestTimezoneUpdatePublicTestSuite(t *testing.T) { +func TestTimezoneUpdatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(TimezoneUpdatePublicTestSuite)) } diff --git a/internal/controller/api/node/user/group_create_public_test.go b/internal/controller/api/node/user/group_create_public_test.go index 0aa65a5a3..ba28e6aa2 100644 --- a/internal/controller/api/node/user/group_create_public_test.go +++ b/internal/controller/api/node/user/group_create_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -95,7 +97,7 @@ func (s *GroupCreatePublicTestSuite) TestPostNodeGroup() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "group", job.OperationGroupCreate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - Hostname: "agent1", Changed: boolPtr(true), + Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, nil) }, @@ -181,7 +183,7 @@ func (s *GroupCreatePublicTestSuite) TestPostNodeGroup() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, }, nil) @@ -198,15 +200,15 @@ func (s *GroupCreatePublicTestSuite) TestPostNodeGroup() { Hostname: "server1", Body: &gen.GroupCreateRequest{ Name: "devops", - Gid: intPtr(2000), - System: boolPtr(true), + Gid: ptr.To(2000), + System: ptr.To(true), }, }, setupMock: func() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "group", job.OperationGroupCreate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - Hostname: "agent1", Changed: boolPtr(true), + Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, nil) }, @@ -231,7 +233,7 @@ func (s *GroupCreatePublicTestSuite) TestPostNodeGroup() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, "server2": { @@ -292,28 +294,38 @@ func (s *GroupCreatePublicTestSuite) TestPostNodeGroup() { func (s *GroupCreatePublicTestSuite) TestPostNodeGroupValidationHTTP() { tests := []struct { - name string - path string - body string - wantCode int + name string + path string + body string + wantCode int + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", path: "/api/node/server1/group", body: `{"name":"devops"}`, wantCode: http.StatusOK, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + }, }, { name: "when missing name", path: "/api/node/server1/group", body: `{}`, wantCode: http.StatusBadRequest, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + }, }, { name: "when invalid hostname", path: "/api/node/nonexistent/group", body: `{"name":"devops"}`, wantCode: http.StatusBadRequest, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + }, }, } @@ -325,7 +337,7 @@ func (s *GroupCreatePublicTestSuite) TestPostNodeGroupValidationHTTP() { Modify(gomock.Any(), "server1", "group", job.OperationGroupCreate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, nil) } @@ -344,7 +356,7 @@ func (s *GroupCreatePublicTestSuite) TestPostNodeGroupValidationHTTP() { rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec) }) } } @@ -358,7 +370,7 @@ func (s *GroupCreatePublicTestSuite) TestPostNodeGroupRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int + validateFunc func(int) }{ { name: "when no token returns 401", @@ -366,7 +378,9 @@ func (s *GroupCreatePublicTestSuite) TestPostNodeGroupRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when valid admin token returns 200", @@ -384,12 +398,14 @@ func (s *GroupCreatePublicTestSuite) TestPostNodeGroupRBACHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "group", job.OperationGroupCreate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - Hostname: "agent1", Changed: boolPtr(true), + Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -421,11 +437,13 @@ func (s *GroupCreatePublicTestSuite) TestPostNodeGroupRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec.Code) }) } } -func TestGroupCreatePublicTestSuite(t *testing.T) { +func TestGroupCreatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(GroupCreatePublicTestSuite)) } diff --git a/internal/controller/api/node/user/group_delete_public_test.go b/internal/controller/api/node/user/group_delete_public_test.go index 92ded33c5..90d1d7218 100644 --- a/internal/controller/api/node/user/group_delete_public_test.go +++ b/internal/controller/api/node/user/group_delete_public_test.go @@ -30,6 +30,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -94,7 +96,7 @@ func (s *GroupDeletePublicTestSuite) TestDeleteNodeGroup() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "group", job.OperationGroupDelete, map[string]string{"name": "devops"}). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - Hostname: "agent1", Changed: boolPtr(true), + Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, nil) }, @@ -183,7 +185,7 @@ func (s *GroupDeletePublicTestSuite) TestDeleteNodeGroup() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, }, nil) @@ -208,7 +210,7 @@ func (s *GroupDeletePublicTestSuite) TestDeleteNodeGroup() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, "server2": { @@ -276,7 +278,7 @@ func (s *GroupDeletePublicTestSuite) TestDeleteNodeGroupRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int + validateFunc func(int) }{ { name: "when no token returns 401", @@ -284,7 +286,9 @@ func (s *GroupDeletePublicTestSuite) TestDeleteNodeGroupRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when valid admin token returns 200", @@ -302,12 +306,14 @@ func (s *GroupDeletePublicTestSuite) TestDeleteNodeGroupRBACHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "group", job.OperationGroupDelete, map[string]string{"name": "devops"}). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - Hostname: "agent1", Changed: boolPtr(true), + Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -334,11 +340,13 @@ func (s *GroupDeletePublicTestSuite) TestDeleteNodeGroupRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec.Code) }) } } -func TestGroupDeletePublicTestSuite(t *testing.T) { +func TestGroupDeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(GroupDeletePublicTestSuite)) } diff --git a/internal/controller/api/node/user/group_get_public_test.go b/internal/controller/api/node/user/group_get_public_test.go index 7abd24833..5e468d44b 100644 --- a/internal/controller/api/node/user/group_get_public_test.go +++ b/internal/controller/api/node/user/group_get_public_test.go @@ -288,7 +288,7 @@ func (s *GroupGetPublicTestSuite) TestGetNodeGroupByNameRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int + validateFunc func(int) }{ { name: "when no token returns 401", @@ -296,7 +296,9 @@ func (s *GroupGetPublicTestSuite) TestGetNodeGroupByNameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when valid admin token returns 200", @@ -318,7 +320,9 @@ func (s *GroupGetPublicTestSuite) TestGetNodeGroupByNameRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -345,11 +349,13 @@ func (s *GroupGetPublicTestSuite) TestGetNodeGroupByNameRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec.Code) }) } } -func TestGroupGetPublicTestSuite(t *testing.T) { +func TestGroupGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(GroupGetPublicTestSuite)) } diff --git a/internal/controller/api/node/user/group_list_get_public_test.go b/internal/controller/api/node/user/group_list_get_public_test.go index f298a9687..a473e241b 100644 --- a/internal/controller/api/node/user/group_list_get_public_test.go +++ b/internal/controller/api/node/user/group_list_get_public_test.go @@ -259,7 +259,7 @@ func (s *GroupListGetPublicTestSuite) TestGetNodeGroupRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int + validateFunc func(int) }{ { name: "when no token returns 401", @@ -267,7 +267,9 @@ func (s *GroupListGetPublicTestSuite) TestGetNodeGroupRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when insufficient permissions returns 403", @@ -283,7 +285,9 @@ func (s *GroupListGetPublicTestSuite) TestGetNodeGroupRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, + validateFunc: func(got int) { + s.Equal(http.StatusForbidden, got) + }, }, { name: "when valid admin token returns 200", @@ -305,7 +309,9 @@ func (s *GroupListGetPublicTestSuite) TestGetNodeGroupRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -332,11 +338,13 @@ func (s *GroupListGetPublicTestSuite) TestGetNodeGroupRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec.Code) }) } } -func TestGroupListGetPublicTestSuite(t *testing.T) { +func TestGroupListGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(GroupListGetPublicTestSuite)) } diff --git a/internal/controller/api/node/user/group_update_public_test.go b/internal/controller/api/node/user/group_update_public_test.go index e5b80743e..f49ff8d14 100644 --- a/internal/controller/api/node/user/group_update_public_test.go +++ b/internal/controller/api/node/user/group_update_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -97,7 +99,7 @@ func (s *GroupUpdatePublicTestSuite) TestPutNodeGroup() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "group", job.OperationGroupUpdate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - Hostname: "agent1", Changed: boolPtr(true), + Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, nil) }, @@ -206,7 +208,7 @@ func (s *GroupUpdatePublicTestSuite) TestPutNodeGroup() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, }, nil) @@ -232,7 +234,7 @@ func (s *GroupUpdatePublicTestSuite) TestPutNodeGroup() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, "server2": { @@ -294,28 +296,38 @@ func (s *GroupUpdatePublicTestSuite) TestPutNodeGroup() { func (s *GroupUpdatePublicTestSuite) TestPutNodeGroupValidationHTTP() { tests := []struct { - name string - path string - body string - wantCode int + name string + path string + body string + wantCode int + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", path: "/api/node/server1/group/devops", body: `{"members":["user1"]}`, wantCode: http.StatusOK, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + }, }, { name: "when empty body returns 400", path: "/api/node/server1/group/devops", body: `{}`, wantCode: http.StatusBadRequest, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + }, }, { name: "when invalid hostname", path: "/api/node/nonexistent/group/devops", body: `{"members":["user1"]}`, wantCode: http.StatusBadRequest, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + }, }, } @@ -327,7 +339,7 @@ func (s *GroupUpdatePublicTestSuite) TestPutNodeGroupValidationHTTP() { Modify(gomock.Any(), "server1", "group", job.OperationGroupUpdate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, nil) } @@ -346,7 +358,7 @@ func (s *GroupUpdatePublicTestSuite) TestPutNodeGroupValidationHTTP() { rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec) }) } } @@ -360,7 +372,7 @@ func (s *GroupUpdatePublicTestSuite) TestPutNodeGroupRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int + validateFunc func(int) }{ { name: "when no token returns 401", @@ -368,7 +380,9 @@ func (s *GroupUpdatePublicTestSuite) TestPutNodeGroupRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when valid admin token returns 200", @@ -386,12 +400,14 @@ func (s *GroupUpdatePublicTestSuite) TestPutNodeGroupRBACHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "group", job.OperationGroupUpdate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - Hostname: "agent1", Changed: boolPtr(true), + Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"devops","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -423,11 +439,13 @@ func (s *GroupUpdatePublicTestSuite) TestPutNodeGroupRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec.Code) }) } } -func TestGroupUpdatePublicTestSuite(t *testing.T) { +func TestGroupUpdatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(GroupUpdatePublicTestSuite)) } diff --git a/internal/controller/api/node/user/handler_public_test.go b/internal/controller/api/node/user/handler_public_test.go index a08a6fce9..bf020c5ba 100644 --- a/internal/controller/api/node/user/handler_public_test.go +++ b/internal/controller/api/node/user/handler_public_test.go @@ -52,18 +52,18 @@ func (s *HandlerPublicTestSuite) TearDownTest() { func (s *HandlerPublicTestSuite) TestHandler() { tests := []struct { - name string - validate func([]func(e *echo.Echo)) + name string + validateFunc func([]func(e *echo.Echo)) }{ { name: "returns handler functions", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { s.NotEmpty(handlers) }, }, { name: "closure registers routes and middleware executes", - validate: func(handlers []func(e *echo.Echo)) { + validateFunc: func(handlers []func(e *echo.Echo)) { e := echo.New() for _, h := range handlers { h(e) @@ -86,11 +86,13 @@ func (s *HandlerPublicTestSuite) TestHandler() { nil, ) - tt.validate(handlers) + tt.validateFunc(handlers) }) } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/api/node/user/ssh_key_create_public_test.go b/internal/controller/api/node/user/ssh_key_create_public_test.go index e0474e45c..5f22f6680 100644 --- a/internal/controller/api/node/user/ssh_key_create_public_test.go +++ b/internal/controller/api/node/user/ssh_key_create_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -108,7 +110,7 @@ func (s *SSHKeyCreatePublicTestSuite) TestPostNodeUserSSHKey() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"changed":true}`), }, nil) }, @@ -229,7 +231,7 @@ func (s *SSHKeyCreatePublicTestSuite) TestPostNodeUserSSHKey() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"changed":true}`), }, }, nil) @@ -263,7 +265,7 @@ func (s *SSHKeyCreatePublicTestSuite) TestPostNodeUserSSHKey() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"changed":true}`), }, "server2": { @@ -333,19 +335,26 @@ func (s *SSHKeyCreatePublicTestSuite) TestPostNodeUserSSHKey() { func (s *SSHKeyCreatePublicTestSuite) TestPostNodeUserSSHKeyValidationHTTP() { tests := []struct { - name string - body string - wantCode int + name string + body string + wantCode int + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", body: `{"key":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAITest user@host"}`, wantCode: http.StatusOK, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + }, }, { name: "when missing key", body: `{}`, wantCode: http.StatusBadRequest, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + }, }, } @@ -363,7 +372,7 @@ func (s *SSHKeyCreatePublicTestSuite) TestPostNodeUserSSHKeyValidationHTTP() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"changed":true}`), }, nil) } @@ -382,7 +391,7 @@ func (s *SSHKeyCreatePublicTestSuite) TestPostNodeUserSSHKeyValidationHTTP() { rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec) }) } } @@ -396,7 +405,7 @@ func (s *SSHKeyCreatePublicTestSuite) TestPostNodeUserSSHKeyRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int + validateFunc func(int) }{ { name: "when no token returns 401", @@ -404,7 +413,9 @@ func (s *SSHKeyCreatePublicTestSuite) TestPostNodeUserSSHKeyRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when insufficient permissions returns 403", @@ -420,7 +431,9 @@ func (s *SSHKeyCreatePublicTestSuite) TestPostNodeUserSSHKeyRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, + validateFunc: func(got int) { + s.Equal(http.StatusForbidden, got) + }, }, { name: "when valid admin token returns 200", @@ -445,12 +458,14 @@ func (s *SSHKeyCreatePublicTestSuite) TestPostNodeUserSSHKeyRBACHTTP() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -483,11 +498,13 @@ func (s *SSHKeyCreatePublicTestSuite) TestPostNodeUserSSHKeyRBACHTTP() { rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec.Code) }) } } -func TestSSHKeyCreatePublicTestSuite(t *testing.T) { +func TestSSHKeyCreatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SSHKeyCreatePublicTestSuite)) } diff --git a/internal/controller/api/node/user/ssh_key_delete_public_test.go b/internal/controller/api/node/user/ssh_key_delete_public_test.go index 807e986f3..8919cd973 100644 --- a/internal/controller/api/node/user/ssh_key_delete_public_test.go +++ b/internal/controller/api/node/user/ssh_key_delete_public_test.go @@ -29,6 +29,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -104,7 +106,7 @@ func (s *SSHKeyDeletePublicTestSuite) TestDeleteNodeUserSSHKey() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) }, validateFunc: func(resp gen.DeleteNodeUserSSHKeyResponseObject) { @@ -203,7 +205,7 @@ func (s *SSHKeyDeletePublicTestSuite) TestDeleteNodeUserSSHKey() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), }, }, nil) }, @@ -234,7 +236,7 @@ func (s *SSHKeyDeletePublicTestSuite) TestDeleteNodeUserSSHKey() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), }, "server2": { Hostname: "server2", @@ -304,8 +306,7 @@ func (s *SSHKeyDeletePublicTestSuite) TestDeleteNodeUserSSHKeyValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -325,12 +326,15 @@ func (s *SSHKeyDeletePublicTestSuite) TestDeleteNodeUserSSHKeyValidationHTTP() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -338,8 +342,11 @@ func (s *SSHKeyDeletePublicTestSuite) TestDeleteNodeUserSSHKeyValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -358,10 +365,7 @@ func (s *SSHKeyDeletePublicTestSuite) TestDeleteNodeUserSSHKeyValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -375,7 +379,7 @@ func (s *SSHKeyDeletePublicTestSuite) TestDeleteNodeUserSSHKeyRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int + validateFunc func(int) }{ { name: "when no token returns 401", @@ -383,7 +387,9 @@ func (s *SSHKeyDeletePublicTestSuite) TestDeleteNodeUserSSHKeyRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when insufficient permissions returns 403", @@ -399,7 +405,9 @@ func (s *SSHKeyDeletePublicTestSuite) TestDeleteNodeUserSSHKeyRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, + validateFunc: func(got int) { + s.Equal(http.StatusForbidden, got) + }, }, { name: "when valid admin token returns 200", @@ -427,11 +435,13 @@ func (s *SSHKeyDeletePublicTestSuite) TestDeleteNodeUserSSHKeyRBACHTTP() { ). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), }, nil) return mock }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -463,11 +473,13 @@ func (s *SSHKeyDeletePublicTestSuite) TestDeleteNodeUserSSHKeyRBACHTTP() { rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec.Code) }) } } -func TestSSHKeyDeletePublicTestSuite(t *testing.T) { +func TestSSHKeyDeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SSHKeyDeletePublicTestSuite)) } diff --git a/internal/controller/api/node/user/ssh_key_list_get_public_test.go b/internal/controller/api/node/user/ssh_key_list_get_public_test.go index 67cbca777..6a21a64e7 100644 --- a/internal/controller/api/node/user/ssh_key_list_get_public_test.go +++ b/internal/controller/api/node/user/ssh_key_list_get_public_test.go @@ -363,8 +363,7 @@ func (s *SSHKeyListGetPublicTestSuite) TestGetNodeUserSSHKeyValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -385,8 +384,11 @@ func (s *SSHKeyListGetPublicTestSuite) TestGetNodeUserSSHKeyValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -394,8 +396,11 @@ func (s *SSHKeyListGetPublicTestSuite) TestGetNodeUserSSHKeyValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -414,10 +419,7 @@ func (s *SSHKeyListGetPublicTestSuite) TestGetNodeUserSSHKeyValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -431,8 +433,7 @@ func (s *SSHKeyListGetPublicTestSuite) TestGetNodeUserSSHKeyRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -441,8 +442,10 @@ func (s *SSHKeyListGetPublicTestSuite) TestGetNodeUserSSHKeyRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -459,8 +462,10 @@ func (s *SSHKeyListGetPublicTestSuite) TestGetNodeUserSSHKeyRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -490,8 +495,11 @@ func (s *SSHKeyListGetPublicTestSuite) TestGetNodeUserSSHKeyRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -528,14 +536,13 @@ func (s *SSHKeyListGetPublicTestSuite) TestGetNodeUserSSHKeyRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestSSHKeyListGetPublicTestSuite(t *testing.T) { +func TestSSHKeyListGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SSHKeyListGetPublicTestSuite)) } diff --git a/internal/controller/api/node/user/support_public_test.go b/internal/controller/api/node/user/support_public_test.go deleted file mode 100644 index 87ecf23cd..000000000 --- a/internal/controller/api/node/user/support_public_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2026 John Dewey - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -package user_test - -func boolPtr( - b bool, -) *bool { - return &b -} - -func intPtr( - i int, -) *int { - return &i -} - -func strPtr( - s string, -) *string { - return &s -} diff --git a/internal/controller/api/node/user/user_create_public_test.go b/internal/controller/api/node/user/user_create_public_test.go index 5caca6224..7c91109a5 100644 --- a/internal/controller/api/node/user/user_create_public_test.go +++ b/internal/controller/api/node/user/user_create_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -98,7 +100,7 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUser() { Modify(gomock.Any(), "server1", "user", job.OperationUserCreate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"newuser","changed":true}`), }, nil) }, @@ -190,7 +192,7 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUser() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"newuser","changed":true}`), }, }, nil) @@ -207,13 +209,13 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUser() { Hostname: "server1", Body: &gen.UserCreateRequest{ Name: "newuser", - Uid: intPtr(1001), - Gid: intPtr(1001), - Home: strPtr("/home/newuser"), - Shell: strPtr("/bin/zsh"), + Uid: ptr.To(1001), + Gid: ptr.To(1001), + Home: ptr.To("/home/newuser"), + Shell: ptr.To("/bin/zsh"), Groups: &[]string{"sudo", "docker"}, - Password: strPtr("secret123"), - System: boolPtr(false), + Password: ptr.To("secret123"), + System: ptr.To(false), }, }, setupMock: func() { @@ -221,7 +223,7 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUser() { Modify(gomock.Any(), "server1", "user", job.OperationUserCreate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"newuser","changed":true}`), }, nil) }, @@ -246,7 +248,7 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUser() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"newuser","changed":true}`), }, "server2": { @@ -307,19 +309,26 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUser() { func (s *UserCreatePublicTestSuite) TestPostNodeUserValidationHTTP() { tests := []struct { - name string - body string - wantCode int + name string + body string + wantCode int + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", body: `{"name":"newuser"}`, wantCode: http.StatusOK, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + }, }, { name: "when missing name", body: `{}`, wantCode: http.StatusBadRequest, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + }, }, } @@ -331,7 +340,7 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUserValidationHTTP() { Modify(gomock.Any(), "server1", "user", job.OperationUserCreate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"newuser","changed":true}`), }, nil) } @@ -350,7 +359,7 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUserValidationHTTP() { rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec) }) } } @@ -364,7 +373,7 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUserRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int + validateFunc func(int) }{ { name: "when no token returns 401", @@ -372,7 +381,9 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUserRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when insufficient permissions returns 403", @@ -388,7 +399,9 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUserRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, + validateFunc: func(got int) { + s.Equal(http.StatusForbidden, got) + }, }, { name: "when valid admin token returns 200", @@ -407,12 +420,14 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUserRBACHTTP() { Modify(gomock.Any(), "server1", "user", job.OperationUserCreate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"newuser","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -445,11 +460,13 @@ func (s *UserCreatePublicTestSuite) TestPostNodeUserRBACHTTP() { rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec.Code) }) } } -func TestUserCreatePublicTestSuite(t *testing.T) { +func TestUserCreatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(UserCreatePublicTestSuite)) } diff --git a/internal/controller/api/node/user/user_delete_public_test.go b/internal/controller/api/node/user/user_delete_public_test.go index 4ca8a27fb..4caeebc9a 100644 --- a/internal/controller/api/node/user/user_delete_public_test.go +++ b/internal/controller/api/node/user/user_delete_public_test.go @@ -30,6 +30,8 @@ import ( "os" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -94,7 +96,7 @@ func (s *UserDeletePublicTestSuite) TestDeleteNodeUser() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "user", job.OperationUserDelete, map[string]string{"name": "testuser"}). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - Hostname: "agent1", Changed: boolPtr(true), + Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, nil) }, @@ -183,7 +185,7 @@ func (s *UserDeletePublicTestSuite) TestDeleteNodeUser() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, }, nil) @@ -208,7 +210,7 @@ func (s *UserDeletePublicTestSuite) TestDeleteNodeUser() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, "server2": { @@ -276,7 +278,7 @@ func (s *UserDeletePublicTestSuite) TestDeleteNodeUserRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int + validateFunc func(int) }{ { name: "when no token returns 401", @@ -284,7 +286,9 @@ func (s *UserDeletePublicTestSuite) TestDeleteNodeUserRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when valid admin token returns 200", @@ -302,12 +306,14 @@ func (s *UserDeletePublicTestSuite) TestDeleteNodeUserRBACHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "user", job.OperationUserDelete, map[string]string{"name": "testuser"}). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - Hostname: "agent1", Changed: boolPtr(true), + Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -334,11 +340,13 @@ func (s *UserDeletePublicTestSuite) TestDeleteNodeUserRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec.Code) }) } } -func TestUserDeletePublicTestSuite(t *testing.T) { +func TestUserDeletePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(UserDeletePublicTestSuite)) } diff --git a/internal/controller/api/node/user/user_get_public_test.go b/internal/controller/api/node/user/user_get_public_test.go index 91e7caa2c..38cc900b5 100644 --- a/internal/controller/api/node/user/user_get_public_test.go +++ b/internal/controller/api/node/user/user_get_public_test.go @@ -299,7 +299,7 @@ func (s *UserGetPublicTestSuite) TestGetNodeUserByNameRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int + validateFunc func(int) }{ { name: "when no token returns 401", @@ -307,7 +307,9 @@ func (s *UserGetPublicTestSuite) TestGetNodeUserByNameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when insufficient permissions returns 403", @@ -323,7 +325,9 @@ func (s *UserGetPublicTestSuite) TestGetNodeUserByNameRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, + validateFunc: func(got int) { + s.Equal(http.StatusForbidden, got) + }, }, { name: "when valid admin token returns 200", @@ -348,7 +352,9 @@ func (s *UserGetPublicTestSuite) TestGetNodeUserByNameRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -376,11 +382,13 @@ func (s *UserGetPublicTestSuite) TestGetNodeUserByNameRBACHTTP() { rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec.Code) }) } } -func TestUserGetPublicTestSuite(t *testing.T) { +func TestUserGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(UserGetPublicTestSuite)) } diff --git a/internal/controller/api/node/user/user_list_get_public_test.go b/internal/controller/api/node/user/user_list_get_public_test.go index ba033a098..749b42a0b 100644 --- a/internal/controller/api/node/user/user_list_get_public_test.go +++ b/internal/controller/api/node/user/user_list_get_public_test.go @@ -313,8 +313,7 @@ func (s *UserListGetPublicTestSuite) TestGetNodeUserValidationHTTP() { name string path string setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", @@ -329,8 +328,11 @@ func (s *UserListGetPublicTestSuite) TestGetNodeUserValidationHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, { name: "when target agent not found", @@ -338,8 +340,11 @@ func (s *UserListGetPublicTestSuite) TestGetNodeUserValidationHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusBadRequest, - wantContains: []string{`"error"`, "valid_target"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + s.Contains(rec.Body.String(), `"error"`) + s.Contains(rec.Body.String(), "valid_target") + }, }, } @@ -358,10 +363,7 @@ func (s *UserListGetPublicTestSuite) TestGetNodeUserValidationHTTP() { a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } @@ -375,8 +377,7 @@ func (s *UserListGetPublicTestSuite) TestGetNodeUserRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int - wantContains []string + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when no token returns 401", @@ -385,8 +386,10 @@ func (s *UserListGetPublicTestSuite) TestGetNodeUserRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, - wantContains: []string{"Bearer token required"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusUnauthorized, rec.Code) + s.Contains(rec.Body.String(), "Bearer token required") + }, }, { name: "when insufficient permissions returns 403", @@ -403,8 +406,10 @@ func (s *UserListGetPublicTestSuite) TestGetNodeUserRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusForbidden, - wantContains: []string{"Insufficient permissions"}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusForbidden, rec.Code) + s.Contains(rec.Body.String(), "Insufficient permissions") + }, }, { name: "when valid admin token returns 200", @@ -428,8 +433,11 @@ func (s *UserListGetPublicTestSuite) TestGetNodeUserRBACHTTP() { }, nil) return mock }, - wantCode: http.StatusOK, - wantContains: []string{`"job_id"`, `"results"`}, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + s.Contains(rec.Body.String(), `"job_id"`) + s.Contains(rec.Body.String(), `"results"`) + }, }, } @@ -466,14 +474,13 @@ func (s *UserListGetPublicTestSuite) TestGetNodeUserRBACHTTP() { server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) - for _, str := range tc.wantContains { - s.Contains(rec.Body.String(), str) - } + tc.validateFunc(rec) }) } } -func TestUserListGetPublicTestSuite(t *testing.T) { +func TestUserListGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(UserListGetPublicTestSuite)) } diff --git a/internal/controller/api/node/user/user_password_public_test.go b/internal/controller/api/node/user/user_password_public_test.go index 834e6451b..a6e5fa832 100644 --- a/internal/controller/api/node/user/user_password_public_test.go +++ b/internal/controller/api/node/user/user_password_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -96,7 +98,7 @@ func (s *UserPasswordPublicTestSuite) TestPostNodeUserPassword() { s.mockJobClient.EXPECT(). Modify(gomock.Any(), "server1", "user", job.OperationUserChangePassword, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - Hostname: "agent1", Changed: boolPtr(true), + Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, nil) }, @@ -203,7 +205,7 @@ func (s *UserPasswordPublicTestSuite) TestPostNodeUserPassword() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, }, nil) @@ -229,7 +231,7 @@ func (s *UserPasswordPublicTestSuite) TestPostNodeUserPassword() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, "server2": { @@ -291,28 +293,38 @@ func (s *UserPasswordPublicTestSuite) TestPostNodeUserPassword() { func (s *UserPasswordPublicTestSuite) TestPostNodeUserPasswordValidationHTTP() { tests := []struct { - name string - path string - body string - wantCode int + name string + path string + body string + wantCode int + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", path: "/api/node/server1/user/testuser/password", body: `{"password":"newpass123"}`, wantCode: http.StatusOK, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + }, }, { name: "when missing password", path: "/api/node/server1/user/testuser/password", body: `{}`, wantCode: http.StatusBadRequest, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + }, }, { name: "when invalid hostname", path: "/api/node/nonexistent/user/testuser/password", body: `{"password":"newpass123"}`, wantCode: http.StatusBadRequest, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + }, }, } @@ -324,7 +336,7 @@ func (s *UserPasswordPublicTestSuite) TestPostNodeUserPasswordValidationHTTP() { Modify(gomock.Any(), "server1", "user", job.OperationUserChangePassword, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, nil) } @@ -343,7 +355,7 @@ func (s *UserPasswordPublicTestSuite) TestPostNodeUserPasswordValidationHTTP() { rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec) }) } } @@ -357,7 +369,7 @@ func (s *UserPasswordPublicTestSuite) TestPostNodeUserPasswordRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int + validateFunc func(int) }{ { name: "when no token returns 401", @@ -365,7 +377,9 @@ func (s *UserPasswordPublicTestSuite) TestPostNodeUserPasswordRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when valid admin token returns 200", @@ -383,12 +397,14 @@ func (s *UserPasswordPublicTestSuite) TestPostNodeUserPasswordRBACHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "user", job.OperationUserChangePassword, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - Hostname: "agent1", Changed: boolPtr(true), + Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -420,11 +436,13 @@ func (s *UserPasswordPublicTestSuite) TestPostNodeUserPasswordRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec.Code) }) } } -func TestUserPasswordPublicTestSuite(t *testing.T) { +func TestUserPasswordPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(UserPasswordPublicTestSuite)) } diff --git a/internal/controller/api/node/user/user_update_public_test.go b/internal/controller/api/node/user/user_update_public_test.go index ef91abbc2..a0767533f 100644 --- a/internal/controller/api/node/user/user_update_public_test.go +++ b/internal/controller/api/node/user/user_update_public_test.go @@ -31,6 +31,8 @@ import ( "strings" "testing" + "k8s.io/utils/ptr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -98,7 +100,7 @@ func (s *UserUpdatePublicTestSuite) TestPutNodeUser() { Modify(gomock.Any(), "server1", "user", job.OperationUserUpdate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, nil) }, @@ -207,7 +209,7 @@ func (s *UserUpdatePublicTestSuite) TestPutNodeUser() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, }, nil) @@ -225,9 +227,9 @@ func (s *UserUpdatePublicTestSuite) TestPutNodeUser() { Name: "testuser", Body: &gen.UserUpdateRequest{ Shell: &shell, - Home: strPtr("/home/newdir"), + Home: ptr.To("/home/newdir"), Groups: &[]string{"sudo", "docker"}, - Lock: boolPtr(true), + Lock: ptr.To(true), }, }, setupMock: func() { @@ -235,7 +237,7 @@ func (s *UserUpdatePublicTestSuite) TestPutNodeUser() { Modify(gomock.Any(), "server1", "user", job.OperationUserUpdate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, nil) }, @@ -262,7 +264,7 @@ func (s *UserUpdatePublicTestSuite) TestPutNodeUser() { "server1": { Hostname: "server1", Status: job.StatusCompleted, - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, "server2": { @@ -324,28 +326,38 @@ func (s *UserUpdatePublicTestSuite) TestPutNodeUser() { func (s *UserUpdatePublicTestSuite) TestPutNodeUserValidationHTTP() { tests := []struct { - name string - path string - body string - wantCode int + name string + path string + body string + wantCode int + validateFunc func(*httptest.ResponseRecorder) }{ { name: "when valid request", path: "/api/node/server1/user/testuser", body: `{"shell":"/bin/zsh"}`, wantCode: http.StatusOK, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusOK, rec.Code) + }, }, { name: "when empty body returns 400", path: "/api/node/server1/user/testuser", body: `{}`, wantCode: http.StatusBadRequest, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + }, }, { name: "when invalid hostname", path: "/api/node/nonexistent/user/testuser", body: `{"shell":"/bin/zsh"}`, wantCode: http.StatusBadRequest, + validateFunc: func(rec *httptest.ResponseRecorder) { + s.Equal(http.StatusBadRequest, rec.Code) + }, }, } @@ -357,7 +369,7 @@ func (s *UserUpdatePublicTestSuite) TestPutNodeUserValidationHTTP() { Modify(gomock.Any(), "server1", "user", job.OperationUserUpdate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ Hostname: "agent1", - Changed: boolPtr(true), + Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, nil) } @@ -376,7 +388,7 @@ func (s *UserUpdatePublicTestSuite) TestPutNodeUserValidationHTTP() { rec := httptest.NewRecorder() a.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec) }) } } @@ -390,7 +402,7 @@ func (s *UserUpdatePublicTestSuite) TestPutNodeUserRBACHTTP() { name string setupAuth func(req *http.Request) setupJobMock func() *jobmocks.MockJobClient - wantCode int + validateFunc func(int) }{ { name: "when no token returns 401", @@ -398,7 +410,9 @@ func (s *UserUpdatePublicTestSuite) TestPutNodeUserRBACHTTP() { setupJobMock: func() *jobmocks.MockJobClient { return jobmocks.NewMockJobClient(s.mockCtrl) }, - wantCode: http.StatusUnauthorized, + validateFunc: func(got int) { + s.Equal(http.StatusUnauthorized, got) + }, }, { name: "when valid admin token returns 200", @@ -416,12 +430,14 @@ func (s *UserUpdatePublicTestSuite) TestPutNodeUserRBACHTTP() { mock.EXPECT(). Modify(gomock.Any(), "server1", "user", job.OperationUserUpdate, gomock.Any()). Return("550e8400-e29b-41d4-a716-446655440000", &job.Response{ - Hostname: "agent1", Changed: boolPtr(true), + Hostname: "agent1", Changed: ptr.To(true), Data: json.RawMessage(`{"name":"testuser","changed":true}`), }, nil) return mock }, - wantCode: http.StatusOK, + validateFunc: func(got int) { + s.Equal(http.StatusOK, got) + }, }, } @@ -453,11 +469,13 @@ func (s *UserUpdatePublicTestSuite) TestPutNodeUserRBACHTTP() { tc.setupAuth(req) rec := httptest.NewRecorder() server.Echo.ServeHTTP(rec, req) - s.Equal(tc.wantCode, rec.Code) + tc.validateFunc(rec.Code) }) } } -func TestUserUpdatePublicTestSuite(t *testing.T) { +func TestUserUpdatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(UserUpdatePublicTestSuite)) } diff --git a/internal/controller/api/server_public_test.go b/internal/controller/api/server_public_test.go index ee5120a34..f50475766 100644 --- a/internal/controller/api/server_public_test.go +++ b/internal/controller/api/server_public_test.go @@ -55,9 +55,10 @@ func (s *ServerPublicTestSuite) TearDownTest() { func (s *ServerPublicTestSuite) TestNew() { tests := []struct { - name string - appConfig config.Config - opts []api.Option + name string + appConfig config.Config + opts []api.Option + validateFunc func(*api.Server) }{ { name: "creates server with default config", @@ -70,6 +71,10 @@ func (s *ServerPublicTestSuite) TestNew() { }, }, }, + validateFunc: func(server *api.Server) { + s.NotNil(server) + s.NotNil(server.Echo) + }, }, { name: "creates server with custom roles", @@ -87,6 +92,10 @@ func (s *ServerPublicTestSuite) TestNew() { }, }, }, + validateFunc: func(server *api.Server) { + s.NotNil(server) + s.NotNil(server.Echo) + }, }, { name: "creates server with audit store option", @@ -102,6 +111,10 @@ func (s *ServerPublicTestSuite) TestNew() { opts: []api.Option{ api.WithAuditStore(auditmocks.NewMockStore(s.mockCtrl)), }, + validateFunc: func(server *api.Server) { + s.NotNil(server) + s.NotNil(server.Echo) + }, }, { name: "creates server with meter provider option", @@ -117,6 +130,10 @@ func (s *ServerPublicTestSuite) TestNew() { opts: []api.Option{ api.WithMeterProvider(sdkmetric.NewMeterProvider()), }, + validateFunc: func(server *api.Server) { + s.NotNil(server) + s.NotNil(server.Echo) + }, }, { name: "creates server with CORS origins", @@ -135,15 +152,16 @@ func (s *ServerPublicTestSuite) TestNew() { }, }, }, + validateFunc: func(server *api.Server) { + s.NotNil(server) + s.NotNil(server.Echo) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - server := api.New(tt.appConfig, slog.Default(), tt.opts...) - - s.NotNil(server) - s.NotNil(server.Echo) + tt.validateFunc(api.New(tt.appConfig, slog.Default(), tt.opts...)) }) } } @@ -270,6 +288,8 @@ func (s *ServerPublicTestSuite) TestStopErrorPath() { } } -func TestServerPublicTestSuite(t *testing.T) { +func TestServerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServerPublicTestSuite)) } diff --git a/internal/controller/api/ui/handler.go b/internal/controller/api/ui/handler.go index ed70d40ff..fe7d803ac 100644 --- a/internal/controller/api/ui/handler.go +++ b/internal/controller/api/ui/handler.go @@ -33,7 +33,9 @@ import ( // the same pattern as other domain handlers in this package. distFS must // be rooted at the directory containing index.html (the caller is // responsible for any fs.Sub calls). -func Handler(distFS fs.FS) []func(e *echo.Echo) { +func Handler( + distFS fs.FS, +) []func(e *echo.Echo) { return []func(e *echo.Echo){ func(e *echo.Echo) { Register(e, distFS) @@ -44,7 +46,10 @@ func Handler(distFS fs.FS) []func(e *echo.Echo) { // Register mounts the UI assets on the Echo router. Static files are served // directly; all other non-/api paths fall back to index.html so React Router // can handle client-side routing. -func Register(e *echo.Echo, distFS fs.FS) { +func Register( + e *echo.Echo, + distFS fs.FS, +) { fileServer := http.FileServer(http.FS(distFS)) serveIndex := func(w http.ResponseWriter, _ *http.Request) { diff --git a/internal/controller/api/ui/handler_public_test.go b/internal/controller/api/ui/handler_public_test.go index df2abb4ea..3a31f2cc2 100644 --- a/internal/controller/api/ui/handler_public_test.go +++ b/internal/controller/api/ui/handler_public_test.go @@ -211,6 +211,8 @@ func (s *HandlerPublicTestSuite) TestRegister() { } } -func TestHandlerPublicTestSuite(t *testing.T) { +func TestHandlerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HandlerPublicTestSuite)) } diff --git a/internal/controller/enrollment/rotation_public_test.go b/internal/controller/enrollment/rotation_public_test.go index 182c9566c..d5eb7f27c 100644 --- a/internal/controller/enrollment/rotation_public_test.go +++ b/internal/controller/enrollment/rotation_public_test.go @@ -76,8 +76,7 @@ func (s *RotationPublicTestSuite) TestRotateControllerKey() { tests := []struct { name string setupMock func() - wantErr bool - wantContains string + validateFunc func(error) }{ { name: "when rotation succeeds publishes new key", @@ -87,6 +86,9 @@ func (s *RotationPublicTestSuite) TestRotateControllerKey() { PublishCore("osapi.pki.rotate", gomock.Any()). Return(nil) }, + validateFunc: func(err error) { + require.NoError(s.T(), err) + }, }, { name: "when marshal fails returns error", @@ -96,8 +98,10 @@ func (s *RotationPublicTestSuite) TestRotateControllerKey() { return nil, errors.New("marshal error") }) }, - wantErr: true, - wantContains: "marshal rotation message", + validateFunc: func(err error) { + require.Error(s.T(), err) + assert.Contains(s.T(), err.Error(), "marshal rotation message") + }, }, { name: "when publish fails returns error", @@ -107,8 +111,10 @@ func (s *RotationPublicTestSuite) TestRotateControllerKey() { PublishCore("osapi.pki.rotate", gomock.Any()). Return(errors.New("publish error")) }, - wantErr: true, - wantContains: "publish key rotation", + validateFunc: func(err error) { + require.Error(s.T(), err) + assert.Contains(s.T(), err.Error(), "publish key rotation") + }, }, { name: "when namespace is empty uses bare subject", @@ -126,6 +132,9 @@ func (s *RotationPublicTestSuite) TestRotateControllerKey() { PublishCore("pki.rotate", gomock.Any()). Return(nil) }, + validateFunc: func(err error) { + require.NoError(s.T(), err) + }, }, } @@ -133,19 +142,14 @@ func (s *RotationPublicTestSuite) TestRotateControllerKey() { s.Run(tc.name, func() { tc.setupMock() - err := s.watcher.RotateControllerKey() - - if tc.wantErr { - require.Error(s.T(), err) - assert.Contains(s.T(), err.Error(), tc.wantContains) - } else { - require.NoError(s.T(), err) - } + tc.validateFunc(s.watcher.RotateControllerKey()) }) } } -func TestRotationPublicTestSuite(t *testing.T) { +func TestRotationPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(RotationPublicTestSuite)) } diff --git a/internal/controller/enrollment/watcher_public_test.go b/internal/controller/enrollment/watcher_public_test.go index 9c9fb2d06..2147958c5 100644 --- a/internal/controller/enrollment/watcher_public_test.go +++ b/internal/controller/enrollment/watcher_public_test.go @@ -86,10 +86,10 @@ func (s *WatcherPublicTestSuite) TearDownSubTest() { func (s *WatcherPublicTestSuite) TestHandleEnrollmentRequest() { tests := []struct { - name string - setupMock func() - msg *nats.Msg - validateFn func() + name string + setupMock func() + msg *nats.Msg + validateFunc func() }{ { name: "stores pending agent in KV", @@ -239,11 +239,10 @@ func (s *WatcherPublicTestSuite) TestHandleEnrollmentRequestAutoAccept() { func (s *WatcherPublicTestSuite) TestAcceptAgent() { tests := []struct { - name string - machineID string - setupMock func() - wantErr bool - wantErrMsg string + name string + machineID string + setupMock func() + validateFunc func(error) }{ { name: "accepts pending agent and publishes response", @@ -266,6 +265,9 @@ func (s *WatcherPublicTestSuite) TestAcceptAgent() { Delete(gomock.Any(), "enrollment.machine-001"). Return(nil) }, + validateFunc: func(err error) { + s.Require().NoError(err) + }, }, { name: "returns error when pending agent not found", @@ -275,8 +277,10 @@ func (s *WatcherPublicTestSuite) TestAcceptAgent() { Get(gomock.Any(), "enrollment.missing"). Return(nil, jetstream.ErrKeyNotFound) }, - wantErr: true, - wantErrMsg: "get pending agent missing", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "get pending agent missing") + }, }, { name: "returns error on unmarshal failure", @@ -288,8 +292,10 @@ func (s *WatcherPublicTestSuite) TestAcceptAgent() { Get(gomock.Any(), "enrollment.machine-001"). Return(mockEntry, nil) }, - wantErr: true, - wantErrMsg: "unmarshal pending agent machine-001", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "unmarshal pending agent machine-001") + }, }, { name: "returns error on marshal failure", @@ -309,8 +315,10 @@ func (s *WatcherPublicTestSuite) TestAcceptAgent() { return nil, errors.New("marshal error") }) }, - wantErr: true, - wantErrMsg: "marshal acceptance response", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "marshal acceptance response") + }, }, { name: "returns error on publish failure", @@ -329,8 +337,10 @@ func (s *WatcherPublicTestSuite) TestAcceptAgent() { PublishCore("osapi.enroll.response.machine-001", gomock.Any()). Return(errors.New("publish error")) }, - wantErr: true, - wantErrMsg: "publish acceptance for machine-001", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "publish acceptance for machine-001") + }, }, { name: "returns error on delete failure", @@ -353,33 +363,28 @@ func (s *WatcherPublicTestSuite) TestAcceptAgent() { Delete(gomock.Any(), "enrollment.machine-001"). Return(errors.New("delete error")) }, - wantErr: true, - wantErrMsg: "delete pending agent machine-001", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "delete pending agent machine-001") + }, }, } for _, tc := range tests { s.Run(tc.name, func() { tc.setupMock() - err := s.watcher.AcceptAgent(s.ctx, tc.machineID) - if tc.wantErr { - s.Require().Error(err) - s.Contains(err.Error(), tc.wantErrMsg) - } else { - s.Require().NoError(err) - } + tc.validateFunc(s.watcher.AcceptAgent(s.ctx, tc.machineID)) }) } } func (s *WatcherPublicTestSuite) TestRejectAgent() { tests := []struct { - name string - machineID string - reason string - setupMock func() - wantErr bool - wantErrMsg string + name string + machineID string + reason string + setupMock func() + validateFunc func(error) }{ { name: "rejects pending agent and publishes response", @@ -408,6 +413,9 @@ func (s *WatcherPublicTestSuite) TestRejectAgent() { Delete(gomock.Any(), "enrollment.machine-001"). Return(nil) }, + validateFunc: func(err error) { + s.Require().NoError(err) + }, }, { name: "returns error when pending agent not found", @@ -418,8 +426,10 @@ func (s *WatcherPublicTestSuite) TestRejectAgent() { Get(gomock.Any(), "enrollment.missing"). Return(nil, jetstream.ErrKeyNotFound) }, - wantErr: true, - wantErrMsg: "get pending agent missing", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "get pending agent missing") + }, }, { name: "returns error on unmarshal failure", @@ -432,8 +442,10 @@ func (s *WatcherPublicTestSuite) TestRejectAgent() { Get(gomock.Any(), "enrollment.machine-001"). Return(mockEntry, nil) }, - wantErr: true, - wantErrMsg: "unmarshal pending agent machine-001", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "unmarshal pending agent machine-001") + }, }, { name: "returns error on marshal failure", @@ -452,8 +464,10 @@ func (s *WatcherPublicTestSuite) TestRejectAgent() { return nil, errors.New("marshal error") }) }, - wantErr: true, - wantErrMsg: "marshal rejection response", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "marshal rejection response") + }, }, { name: "returns error on publish failure", @@ -472,8 +486,10 @@ func (s *WatcherPublicTestSuite) TestRejectAgent() { PublishCore("osapi.enroll.response.machine-001", gomock.Any()). Return(errors.New("publish error")) }, - wantErr: true, - wantErrMsg: "publish rejection for machine-001", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "publish rejection for machine-001") + }, }, { name: "returns error on delete failure", @@ -496,32 +512,26 @@ func (s *WatcherPublicTestSuite) TestRejectAgent() { Delete(gomock.Any(), "enrollment.machine-001"). Return(errors.New("delete error")) }, - wantErr: true, - wantErrMsg: "delete pending agent machine-001", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "delete pending agent machine-001") + }, }, } for _, tc := range tests { s.Run(tc.name, func() { tc.setupMock() - err := s.watcher.RejectAgent(s.ctx, tc.machineID, tc.reason) - if tc.wantErr { - s.Require().Error(err) - s.Contains(err.Error(), tc.wantErrMsg) - } else { - s.Require().NoError(err) - } + tc.validateFunc(s.watcher.RejectAgent(s.ctx, tc.machineID, tc.reason)) }) } } func (s *WatcherPublicTestSuite) TestListPending() { tests := []struct { - name string - setupMock func() - wantLen int - wantErr bool - wantErrMsg string + name string + setupMock func() + validateFunc func([]enrollment.PendingAgent, error) }{ { name: "returns all pending agents", @@ -554,7 +564,10 @@ func (s *WatcherPublicTestSuite) TestListPending() { Get(gomock.Any(), "enrollment.machine-002"). Return(entry2, nil) }, - wantLen: 2, + validateFunc: func(pending []enrollment.PendingAgent, err error) { + s.Require().NoError(err) + s.Len(pending, 2) + }, }, { name: "returns nil when bucket is empty", @@ -563,7 +576,10 @@ func (s *WatcherPublicTestSuite) TestListPending() { ListKeys(gomock.Any()). Return(nil, jetstream.ErrNoKeysFound) }, - wantLen: 0, + validateFunc: func(pending []enrollment.PendingAgent, err error) { + s.Require().NoError(err) + s.Len(pending, 0) + }, }, { name: "returns error on list failure", @@ -572,8 +588,10 @@ func (s *WatcherPublicTestSuite) TestListPending() { ListKeys(gomock.Any()). Return(nil, errors.New("list error")) }, - wantErr: true, - wantErrMsg: "list enrollment keys", + validateFunc: func(_ []enrollment.PendingAgent, err error) { + s.Require().Error(err) + s.Contains(err.Error(), "list enrollment keys") + }, }, { name: "skips entries with get errors", @@ -602,7 +620,10 @@ func (s *WatcherPublicTestSuite) TestListPending() { Get(gomock.Any(), "enrollment.machine-002"). Return(entry2, nil) }, - wantLen: 1, + validateFunc: func(pending []enrollment.PendingAgent, err error) { + s.Require().NoError(err) + s.Len(pending, 1) + }, }, { name: "skips entries with unmarshal errors", @@ -624,32 +645,27 @@ func (s *WatcherPublicTestSuite) TestListPending() { Get(gomock.Any(), "enrollment.machine-001"). Return(entry, nil) }, - wantLen: 0, + validateFunc: func(pending []enrollment.PendingAgent, err error) { + s.Require().NoError(err) + s.Len(pending, 0) + }, }, } for _, tc := range tests { s.Run(tc.name, func() { tc.setupMock() - pending, err := s.watcher.ListPending(s.ctx) - if tc.wantErr { - s.Require().Error(err) - s.Contains(err.Error(), tc.wantErrMsg) - } else { - s.Require().NoError(err) - s.Len(pending, tc.wantLen) - } + tc.validateFunc(s.watcher.ListPending(s.ctx)) }) } } func (s *WatcherPublicTestSuite) TestAcceptByHostname() { tests := []struct { - name string - hostname string - setupMock func() - wantErr bool - wantErrMsg string + name string + hostname string + setupMock func() + validateFunc func(error) }{ { name: "finds and accepts agent by hostname", @@ -691,6 +707,9 @@ func (s *WatcherPublicTestSuite) TestAcceptByHostname() { Delete(gomock.Any(), "enrollment.machine-001"). Return(nil) }, + validateFunc: func(err error) { + s.Require().NoError(err) + }, }, { name: "returns error when no matching hostname found", @@ -714,8 +733,10 @@ func (s *WatcherPublicTestSuite) TestAcceptByHostname() { Get(gomock.Any(), "enrollment.machine-001"). Return(entry, nil) }, - wantErr: true, - wantErrMsg: `no pending agent with hostname "nonexistent"`, + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), `no pending agent with hostname "nonexistent"`) + }, }, { name: "returns error when bucket is empty", @@ -725,8 +746,10 @@ func (s *WatcherPublicTestSuite) TestAcceptByHostname() { ListKeys(gomock.Any()). Return(nil, jetstream.ErrNoKeysFound) }, - wantErr: true, - wantErrMsg: `no pending agent with hostname "web-01"`, + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), `no pending agent with hostname "web-01"`) + }, }, { name: "returns error on list failure", @@ -736,32 +759,27 @@ func (s *WatcherPublicTestSuite) TestAcceptByHostname() { ListKeys(gomock.Any()). Return(nil, errors.New("list error")) }, - wantErr: true, - wantErrMsg: "list enrollment keys", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "list enrollment keys") + }, }, } for _, tc := range tests { s.Run(tc.name, func() { tc.setupMock() - err := s.watcher.AcceptByHostname(s.ctx, tc.hostname) - if tc.wantErr { - s.Require().Error(err) - s.Contains(err.Error(), tc.wantErrMsg) - } else { - s.Require().NoError(err) - } + tc.validateFunc(s.watcher.AcceptByHostname(s.ctx, tc.hostname)) }) } } func (s *WatcherPublicTestSuite) TestAcceptByFingerprint() { tests := []struct { - name string - fingerprint string - setupMock func() - wantErr bool - wantErrMsg string + name string + fingerprint string + setupMock func() + validateFunc func(error) }{ { name: "finds and accepts agent by fingerprint", @@ -803,6 +821,9 @@ func (s *WatcherPublicTestSuite) TestAcceptByFingerprint() { Delete(gomock.Any(), "enrollment.machine-001"). Return(nil) }, + validateFunc: func(err error) { + s.Require().NoError(err) + }, }, { name: "returns error when no matching fingerprint found", @@ -826,8 +847,10 @@ func (s *WatcherPublicTestSuite) TestAcceptByFingerprint() { Get(gomock.Any(), "enrollment.machine-001"). Return(entry, nil) }, - wantErr: true, - wantErrMsg: `no pending agent with fingerprint "SHA256:unknown"`, + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), `no pending agent with fingerprint "SHA256:unknown"`) + }, }, { name: "returns error when bucket is empty", @@ -837,8 +860,10 @@ func (s *WatcherPublicTestSuite) TestAcceptByFingerprint() { ListKeys(gomock.Any()). Return(nil, jetstream.ErrNoKeysFound) }, - wantErr: true, - wantErrMsg: `no pending agent with fingerprint "SHA256:abc123"`, + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), `no pending agent with fingerprint "SHA256:abc123"`) + }, }, { name: "returns error on list failure", @@ -848,8 +873,10 @@ func (s *WatcherPublicTestSuite) TestAcceptByFingerprint() { ListKeys(gomock.Any()). Return(nil, errors.New("list error")) }, - wantErr: true, - wantErrMsg: "list enrollment keys", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "list enrollment keys") + }, }, { name: "skips entries with get errors during scan", @@ -896,6 +923,9 @@ func (s *WatcherPublicTestSuite) TestAcceptByFingerprint() { Delete(gomock.Any(), "enrollment.machine-002"). Return(nil) }, + validateFunc: func(err error) { + s.Require().NoError(err) + }, }, { name: "skips entries with unmarshal errors during scan", @@ -944,29 +974,26 @@ func (s *WatcherPublicTestSuite) TestAcceptByFingerprint() { Delete(gomock.Any(), "enrollment.machine-002"). Return(nil) }, + validateFunc: func(err error) { + s.Require().NoError(err) + }, }, } for _, tc := range tests { s.Run(tc.name, func() { tc.setupMock() - err := s.watcher.AcceptByFingerprint(s.ctx, tc.fingerprint) - if tc.wantErr { - s.Require().Error(err) - s.Contains(err.Error(), tc.wantErrMsg) - } else { - s.Require().NoError(err) - } + tc.validateFunc(s.watcher.AcceptByFingerprint(s.ctx, tc.fingerprint)) }) } } func (s *WatcherPublicTestSuite) TestStart() { tests := []struct { - name string - setupMock func() - wantErr bool - wantErrMsg string + name string + setupMock func() + wantErr bool + validateFunc func(error) }{ { name: "subscribes and blocks until context cancelled", @@ -981,6 +1008,9 @@ func (s *WatcherPublicTestSuite) TestStart() { return &nats.Subscription{}, nil }) }, + validateFunc: func(err error) { + s.Require().NoError(err) + }, }, { name: "returns error on subscribe failure", @@ -989,8 +1019,11 @@ func (s *WatcherPublicTestSuite) TestStart() { Subscribe("osapi.enroll.request", gomock.Any()). Return(nil, errors.New("subscribe error")) }, - wantErr: true, - wantErrMsg: "subscribe to enrollment requests", + wantErr: true, + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "subscribe to enrollment requests") + }, }, } @@ -999,9 +1032,7 @@ func (s *WatcherPublicTestSuite) TestStart() { tc.setupMock() if tc.wantErr { - err := s.watcher.Start(s.ctx) - s.Require().Error(err) - s.Contains(err.Error(), tc.wantErrMsg) + tc.validateFunc(s.watcher.Start(s.ctx)) } else { ctx, cancel := context.WithCancel(s.ctx) errCh := make(chan error, 1) @@ -1012,8 +1043,7 @@ func (s *WatcherPublicTestSuite) TestStart() { cancel() - err := <-errCh - s.Require().NoError(err) + tc.validateFunc(<-errCh) } }) } @@ -1021,35 +1051,41 @@ func (s *WatcherPublicTestSuite) TestStart() { func (s *WatcherPublicTestSuite) TestEnrollSubject() { tests := []struct { - name string - namespace string - suffix string - want string + name string + namespace string + suffix string + validateFunc func(string) }{ { name: "with namespace", namespace: "osapi", suffix: "enroll.request", - want: "osapi.enroll.request", + validateFunc: func(got string) { + s.Equal("osapi.enroll.request", got) + }, }, { name: "without namespace", namespace: "", suffix: "enroll.request", - want: "enroll.request", + validateFunc: func(got string) { + s.Equal("enroll.request", got) + }, }, { name: "response subject with namespace", namespace: "osapi", suffix: "enroll.response.machine-001", - want: "osapi.enroll.response.machine-001", + validateFunc: func(got string) { + s.Equal("osapi.enroll.response.machine-001", got) + }, }, } for _, tc := range tests { s.Run(tc.name, func() { got := enrollment.EnrollSubject(tc.namespace, tc.suffix) - s.Equal(tc.want, got) + tc.validateFunc(got) }) } } @@ -1081,11 +1117,10 @@ func (s *WatcherPublicTestSuite) makeEnrollmentMsg( func (s *WatcherPublicTestSuite) TestRejectByHostname() { tests := []struct { - name string - hostname string - setupMock func() - wantErr bool - wantErrMsg string + name string + hostname string + setupMock func() + validateFunc func(error) }{ { name: "finds and rejects agent by hostname", @@ -1126,6 +1161,9 @@ func (s *WatcherPublicTestSuite) TestRejectByHostname() { Delete(gomock.Any(), "enrollment.machine-001"). Return(nil) }, + validateFunc: func(err error) { + s.Require().NoError(err) + }, }, { name: "returns error when no matching hostname found", @@ -1149,8 +1187,10 @@ func (s *WatcherPublicTestSuite) TestRejectByHostname() { Get(gomock.Any(), "enrollment.machine-001"). Return(entry, nil) }, - wantErr: true, - wantErrMsg: `no pending agent with hostname "nonexistent"`, + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), `no pending agent with hostname "nonexistent"`) + }, }, { name: "returns error when bucket is empty", @@ -1160,8 +1200,10 @@ func (s *WatcherPublicTestSuite) TestRejectByHostname() { ListKeys(gomock.Any()). Return(nil, jetstream.ErrNoKeysFound) }, - wantErr: true, - wantErrMsg: `no pending agent with hostname "web-01"`, + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), `no pending agent with hostname "web-01"`) + }, }, { name: "returns error on list failure", @@ -1171,21 +1213,17 @@ func (s *WatcherPublicTestSuite) TestRejectByHostname() { ListKeys(gomock.Any()). Return(nil, errors.New("list error")) }, - wantErr: true, - wantErrMsg: "list enrollment keys", + validateFunc: func(err error) { + s.Require().Error(err) + s.Contains(err.Error(), "list enrollment keys") + }, }, } for _, tc := range tests { s.Run(tc.name, func() { tc.setupMock() - err := s.watcher.RejectByHostname(s.ctx, tc.hostname, "rejected via API") - if tc.wantErr { - s.Require().Error(err) - s.Contains(err.Error(), tc.wantErrMsg) - } else { - s.Require().NoError(err) - } + tc.validateFunc(s.watcher.RejectByHostname(s.ctx, tc.hostname, "rejected via API")) }) } } @@ -1212,6 +1250,8 @@ func (s *WatcherPublicTestSuite) makePendingJSON( return data } -func TestWatcherPublicTestSuite(t *testing.T) { +func TestWatcherPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(WatcherPublicTestSuite)) } diff --git a/internal/controller/heartbeat_public_test.go b/internal/controller/heartbeat_public_test.go index dfd46083e..437339790 100644 --- a/internal/controller/heartbeat_public_test.go +++ b/internal/controller/heartbeat_public_test.go @@ -366,6 +366,8 @@ func (s *HeartbeatPublicTestSuite) TestStart() { } } -func TestHeartbeatPublicTestSuite(t *testing.T) { +func TestHeartbeatPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HeartbeatPublicTestSuite)) } diff --git a/internal/controller/notify/log_public_test.go b/internal/controller/notify/log_public_test.go index f98602658..a0c86d343 100644 --- a/internal/controller/notify/log_public_test.go +++ b/internal/controller/notify/log_public_test.go @@ -43,8 +43,9 @@ func (s *LogNotifierPublicTestSuite) SetupTest() { func (s *LogNotifierPublicTestSuite) TestNotify() { tests := []struct { - name string - event notify.ConditionEvent + name string + event notify.ConditionEvent + validateFunc func(error) }{ { name: "logs fired event", @@ -56,6 +57,9 @@ func (s *LogNotifierPublicTestSuite) TestNotify() { Reason: "memory usage above threshold", Timestamp: time.Now(), }, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "logs resolved event", @@ -67,17 +71,21 @@ func (s *LogNotifierPublicTestSuite) TestNotify() { Reason: "memory usage returned to normal", Timestamp: time.Now(), }, + validateFunc: func(err error) { + s.NoError(err) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - err := s.notifier.Notify(context.Background(), tt.event) - s.NoError(err) + tt.validateFunc(s.notifier.Notify(context.Background(), tt.event)) }) } } -func TestLogNotifierPublicTestSuite(t *testing.T) { +func TestLogNotifierPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LogNotifierPublicTestSuite)) } diff --git a/internal/controller/notify/watcher_public_test.go b/internal/controller/notify/watcher_public_test.go index d64c9a0aa..825a51474 100644 --- a/internal/controller/notify/watcher_public_test.go +++ b/internal/controller/notify/watcher_public_test.go @@ -247,49 +247,61 @@ func (s *WatcherPublicTestSuite) TestParseRegistryKey() { key string wantComponentType string wantHostname string - wantOK bool + validateFunc func(bool) }{ { name: "agents prefix returns agent type", key: "agents.web-01", wantComponentType: "agent", wantHostname: "web-01", - wantOK: true, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { name: "api prefix returns api type", key: "api.api-server-01", wantComponentType: "api", wantHostname: "api-server-01", - wantOK: true, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { name: "nats prefix returns nats type", key: "nats.nats-01", wantComponentType: "nats", wantHostname: "nats-01", - wantOK: true, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { name: "controller prefix returns controller type", key: "controller.ctrl-01", wantComponentType: "controller", wantHostname: "ctrl-01", - wantOK: true, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { name: "unknown prefix returns false", key: "unknown.host-01", wantComponentType: "", wantHostname: "", - wantOK: false, + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { name: "key without dot returns false", key: "invalid", wantComponentType: "", wantHostname: "", - wantOK: false, + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, } @@ -299,7 +311,7 @@ func (s *WatcherPublicTestSuite) TestParseRegistryKey() { s.Equal(tt.wantComponentType, componentType) s.Equal(tt.wantHostname, hostname) - s.Equal(tt.wantOK, ok) + tt.validateFunc(ok) }) } } @@ -310,35 +322,43 @@ func (s *WatcherPublicTestSuite) TestResolveDisplayName() { componentType string identifier string value []byte - want string + validateFunc func(string) }{ { name: "non-agent returns identifier as-is", componentType: "controller", identifier: "ctrl-01", value: nil, - want: "ctrl-01", + validateFunc: func(got string) { + s.Equal("ctrl-01", got) + }, }, { name: "agent with valid hostname returns hostname", componentType: "agent", identifier: "abc123", value: []byte(`{"hostname":"web-01"}`), - want: "web-01", + validateFunc: func(got string) { + s.Equal("web-01", got) + }, }, { name: "agent with invalid JSON returns identifier", componentType: "agent", identifier: "abc123", value: []byte("invalid"), - want: "abc123", + validateFunc: func(got string) { + s.Equal("abc123", got) + }, }, { name: "agent with empty hostname returns identifier", componentType: "agent", identifier: "abc123", value: []byte(`{"hostname":""}`), - want: "abc123", + validateFunc: func(got string) { + s.Equal("abc123", got) + }, }, } @@ -349,7 +369,7 @@ func (s *WatcherPublicTestSuite) TestResolveDisplayName() { tt.identifier, tt.value, ) - s.Equal(tt.want, got) + tt.validateFunc(got) }) } } @@ -852,6 +872,8 @@ func (s *WatcherPublicTestSuite) TestStart() { } } -func TestWatcherPublicTestSuite(t *testing.T) { +func TestWatcherPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(WatcherPublicTestSuite)) } diff --git a/internal/exec/export_test.go b/internal/exec/export_test.go index 44104966c..06cede400 100644 --- a/internal/exec/export_test.go +++ b/internal/exec/export_test.go @@ -22,6 +22,9 @@ package exec // SetExecutor replaces the CommandExecutor on an Exec instance. // Used by tests to inject a mock executor. -func SetExecutor(e *Exec, executor CommandExecutor) { +func SetExecutor( + e *Exec, + executor CommandExecutor, +) { e.executor = executor } diff --git a/internal/exec/mocks/dns.go b/internal/exec/mocks/dns.go index 7e4fe34e8..f3725a65d 100644 --- a/internal/exec/mocks/dns.go +++ b/internal/exec/mocks/dns.go @@ -37,12 +37,16 @@ const ( ) // NewPlainMockManager creates a Mock without defaults. -func NewPlainMockManager(ctrl *gomock.Controller) *MockManager { +func NewPlainMockManager( + ctrl *gomock.Controller, +) *MockManager { return NewMockManager(ctrl) } // NewDefaultMockManager creates a Mock with defaults. -func NewDefaultMockManager(ctrl *gomock.Controller) *MockManager { +func NewDefaultMockManager( + ctrl *gomock.Controller, +) *MockManager { mock := NewPlainMockManager(ctrl) // Add common expectations here if needed @@ -50,7 +54,9 @@ func NewDefaultMockManager(ctrl *gomock.Controller) *MockManager { } // NewGetResolvConfMockManager creates a DNS Mock for GetResolvConf. -func NewGetResolvConfMockManager(ctrl *gomock.Controller) *MockManager { +func NewGetResolvConfMockManager( + ctrl *gomock.Controller, +) *MockManager { output := ` Current Scopes: DNS Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported @@ -68,7 +74,9 @@ DNS Domain: example.com local.lan // NewGetResolvConfNoDNSDomainMockManager creates a DNS Mock for GetResolvConf with no // DNS Domain. -func NewGetResolvConfNoDNSDomainMockManager(ctrl *gomock.Controller) *MockManager { +func NewGetResolvConfNoDNSDomainMockManager( + ctrl *gomock.Controller, +) *MockManager { output := ` Current Scopes: DNS Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported @@ -85,7 +93,9 @@ DNS Servers: 192.168.1.1 8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::88 // NewSetResolvConfMockManager creates a DNS Mock for UpdateResolvConfByInterface // with new servers and domains that differ from the existing config. -func NewSetResolvConfMockManager(ctrl *gomock.Controller) *MockManager { +func NewSetResolvConfMockManager( + ctrl *gomock.Controller, +) *MockManager { output := ` Current Scopes: DNS Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported @@ -105,7 +115,9 @@ DNS Domain: old.local // NewSetResolvConfPreserveDNSServersMockManager creates a DNS Mock for // UpdateResolvConfByInterface with existing DNS Servers preserved. -func NewSetResolvConfPreserveDNSServersMockManager(ctrl *gomock.Controller) *MockManager { +func NewSetResolvConfPreserveDNSServersMockManager( + ctrl *gomock.Controller, +) *MockManager { output := ` Current Scopes: DNS Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported @@ -125,7 +137,9 @@ DNS Domain: example.com local.lan // NewSetResolvConfPreserveDNSDomainMockManager creates a DNS Mock for // UpdateResolvConfByInterface with existing DNS Domain preserved. -func NewSetResolvConfPreserveDNSDomainMockManager(ctrl *gomock.Controller) *MockManager { +func NewSetResolvConfPreserveDNSDomainMockManager( + ctrl *gomock.Controller, +) *MockManager { output := ` Current Scopes: DNS Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported @@ -145,7 +159,9 @@ DNS Domain: foo.example.com bar.example.com // NewSetResolvConfFiltersRootDNSDomainMockManager creates a DNS Mock for // UpdateResolvConfByInterface with no DNS Domain (only root "."). -func NewSetResolvConfFiltersRootDNSDomainMockManager(ctrl *gomock.Controller) *MockManager { +func NewSetResolvConfFiltersRootDNSDomainMockManager( + ctrl *gomock.Controller, +) *MockManager { output := ` Current Scopes: DNS Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported @@ -164,7 +180,9 @@ DNS Servers: 1.1.1.1 2.2.2.2 // NewSetResolvConfNetplanGenerateErrorMockManager creates a DNS Mock for // UpdateResolvConfByInterface when `netplan generate` fails. -func NewSetResolvConfNetplanGenerateErrorMockManager(ctrl *gomock.Controller) *MockManager { +func NewSetResolvConfNetplanGenerateErrorMockManager( + ctrl *gomock.Controller, +) *MockManager { // Initial state must differ from desired so the update proceeds. output := ` Current Scopes: DNS @@ -185,19 +203,26 @@ DNS Domain: old.local // NewSetResolvConfSetDNSDomainErrorMockManager creates a DNS Mock for // UpdateResolvConfByInterface when the write path fails. Kept for // backwards compatibility with existing test names. -func NewSetResolvConfSetDNSDomainErrorMockManager(ctrl *gomock.Controller) *MockManager { +func NewSetResolvConfSetDNSDomainErrorMockManager( + ctrl *gomock.Controller, +) *MockManager { return NewSetResolvConfNetplanGenerateErrorMockManager(ctrl) } // NewSetResolvConfSetDNSServersErrorMockManager creates a DNS Mock for // UpdateResolvConfByInterface when the write path fails. Kept for // backwards compatibility with existing test names. -func NewSetResolvConfSetDNSServersErrorMockManager(ctrl *gomock.Controller) *MockManager { +func NewSetResolvConfSetDNSServersErrorMockManager( + ctrl *gomock.Controller, +) *MockManager { return NewSetResolvConfNetplanGenerateErrorMockManager(ctrl) } // mockRunCmdStatus sets up a mock for the "status" RunCmd call. -func mockRunCmdStatus(mock *MockManager, output string) { +func mockRunCmdStatus( + mock *MockManager, + output string, +) { mock.EXPECT(). RunCmd(ResolveCommand, []string{"status", NetworkInterfaceName}). Return(output, nil). @@ -205,7 +230,9 @@ func mockRunCmdStatus(mock *MockManager, output string) { } // mockNetplanStatus sets up a mock for `netplan status --format json`. -func mockNetplanStatus(mock *MockManager) { +func mockNetplanStatus( + mock *MockManager, +) { statusJSON := `{"` + NetworkInterfaceName + `": {"type": "wifi", "macaddress": "b0:a4:60:17:cb:90"}}` mock.EXPECT(). RunCmd(NetplanCommand, []string{"status", "--format", "json"}). @@ -214,7 +241,11 @@ func mockNetplanStatus(mock *MockManager) { } // mockNetplanApply sets up mocks for `netplan generate` and `netplan apply`. -func mockNetplanApply(mock *MockManager, genErr error, applyErr error) { +func mockNetplanApply( + mock *MockManager, + genErr error, + applyErr error, +) { mock.EXPECT(). RunPrivilegedCmd(NetplanCommand, []string{"generate"}). Return("", genErr). diff --git a/internal/exec/run_cmd_dir_public_test.go b/internal/exec/run_cmd_dir_public_test.go index dc3095e4d..68b057a25 100644 --- a/internal/exec/run_cmd_dir_public_test.go +++ b/internal/exec/run_cmd_dir_public_test.go @@ -44,40 +44,50 @@ func (suite *RunCmdDirPublicTestSuite) TearDownTest() {} func (suite *RunCmdDirPublicTestSuite) TestRunCmd() { tests := []struct { - name string - command string - args []string - cwd string - expectError bool - errorContains string + name string + command string + args []string + cwd string + validateFunc func(string, error) }{ { - name: "Valid command with no arguments", - command: "ls", - args: []string{}, - expectError: false, + name: "Valid command with no arguments", + command: "ls", + args: []string{}, + validateFunc: func(output string, err error) { + suite.Require().NoError(err) + suite.Require().NotEmpty(output) + }, }, { - name: "Valid command with no arguments and working dir", - command: "ls", - args: []string{}, - cwd: "/tmp", - expectError: false, + name: "Valid command with no arguments and working dir", + command: "ls", + args: []string{}, + cwd: "/tmp", + validateFunc: func(output string, err error) { + suite.Require().NoError(err) + suite.Require().NotEmpty(output) + }, }, { - name: "Valid command with output", - command: "echo", - args: []string{"-n", "foo"}, - cwd: "/tmp", - expectError: false, + name: "Valid command with output", + command: "echo", + args: []string{"-n", "foo"}, + cwd: "/tmp", + validateFunc: func(output string, err error) { + suite.Require().NoError(err) + suite.Require().NotEmpty(output) + }, }, { - name: "Invalid command", - command: "invalid", - args: []string{"foo"}, - cwd: "/tmp", - expectError: true, - errorContains: "not found", + name: "Invalid command", + command: "invalid", + args: []string{"foo"}, + cwd: "/tmp", + validateFunc: func(_ string, err error) { + suite.Require().Error(err) + suite.Require().Contains(err.Error(), "not found") + }, }, } @@ -85,21 +95,15 @@ func (suite *RunCmdDirPublicTestSuite) TestRunCmd() { suite.Run(tc.name, func() { em := exec.New(suite.logger, false) - output, err := em.RunCmdInDir(tc.command, tc.args, tc.cwd) - - if tc.expectError { - suite.Require().Error(err) - suite.Require().Contains(err.Error(), tc.errorContains) - } else { - suite.Require().NoError(err) - suite.Require().NotEmpty(output) - } + tc.validateFunc(em.RunCmdInDir(tc.command, tc.args, tc.cwd)) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestRunCmdDirPublicTestSuite(t *testing.T) { +func TestRunCmdDirPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(RunCmdDirPublicTestSuite)) } diff --git a/internal/exec/run_cmd_full_public_test.go b/internal/exec/run_cmd_full_public_test.go index 6d121d152..37afe65ed 100644 --- a/internal/exec/run_cmd_full_public_test.go +++ b/internal/exec/run_cmd_full_public_test.go @@ -42,21 +42,21 @@ func (suite *RunCmdFullPublicTestSuite) SetupTest() { func (suite *RunCmdFullPublicTestSuite) TestRunCmdFull() { tests := []struct { - name string - command string - args []string - cwd string - timeout int - expectError bool - errorContains string - validateResult func(*exec.CmdResult) + name string + command string + args []string + cwd string + timeout int + expectError bool + errorContains string + validateFunc func(*exec.CmdResult) }{ { name: "successful command with stdout", command: "echo", args: []string{"hello"}, timeout: 5, - validateResult: func(r *exec.CmdResult) { + validateFunc: func(r *exec.CmdResult) { suite.Equal("hello\n", r.Stdout) suite.Empty(r.Stderr) suite.Equal(0, r.ExitCode) @@ -68,7 +68,7 @@ func (suite *RunCmdFullPublicTestSuite) TestRunCmdFull() { command: "/bin/sh", args: []string{"-c", "echo error >&2"}, timeout: 5, - validateResult: func(r *exec.CmdResult) { + validateFunc: func(r *exec.CmdResult) { suite.Equal("error\n", r.Stderr) suite.Equal(0, r.ExitCode) }, @@ -78,7 +78,7 @@ func (suite *RunCmdFullPublicTestSuite) TestRunCmdFull() { command: "/bin/sh", args: []string{"-c", "exit 42"}, timeout: 5, - validateResult: func(r *exec.CmdResult) { + validateFunc: func(r *exec.CmdResult) { suite.Equal(42, r.ExitCode) }, }, @@ -88,7 +88,7 @@ func (suite *RunCmdFullPublicTestSuite) TestRunCmdFull() { args: []string{}, cwd: "/tmp", timeout: 5, - validateResult: func(r *exec.CmdResult) { + validateFunc: func(r *exec.CmdResult) { suite.Contains(r.Stdout, "tmp") suite.Equal(0, r.ExitCode) }, @@ -98,7 +98,7 @@ func (suite *RunCmdFullPublicTestSuite) TestRunCmdFull() { command: "echo", args: []string{"ok"}, timeout: 0, - validateResult: func(r *exec.CmdResult) { + validateFunc: func(r *exec.CmdResult) { suite.Equal("ok\n", r.Stdout) suite.Equal(0, r.ExitCode) }, @@ -133,14 +133,16 @@ func (suite *RunCmdFullPublicTestSuite) TestRunCmdFull() { } else { suite.Require().NoError(err) suite.Require().NotNil(result) - if tc.validateResult != nil { - tc.validateResult(result) + if tc.validateFunc != nil { + tc.validateFunc(result) } } }) } } -func TestRunCmdFullPublicTestSuite(t *testing.T) { +func TestRunCmdFullPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(RunCmdFullPublicTestSuite)) } diff --git a/internal/exec/run_cmd_public_test.go b/internal/exec/run_cmd_public_test.go index f2f1a1f21..95cfdc581 100644 --- a/internal/exec/run_cmd_public_test.go +++ b/internal/exec/run_cmd_public_test.go @@ -44,36 +44,46 @@ func (suite *RunCmdPublicTestSuite) TearDownTest() {} func (suite *RunCmdPublicTestSuite) TestRunCmd() { tests := []struct { - name string - command string - args []string - expectError bool - errorContains string + name string + command string + args []string + validateFunc func(string, error) }{ { - name: "Valid command with no arguments", - command: "ls", - args: []string{}, - expectError: false, + name: "Valid command with no arguments", + command: "ls", + args: []string{}, + validateFunc: func(output string, err error) { + suite.Require().NoError(err) + suite.Require().NotEmpty(output) + }, }, { - name: "Valid command with no arguments and working dir", - command: "ls", - args: []string{}, - expectError: false, + name: "Valid command with no arguments and working dir", + command: "ls", + args: []string{}, + validateFunc: func(output string, err error) { + suite.Require().NoError(err) + suite.Require().NotEmpty(output) + }, }, { - name: "Valid command with output", - command: "echo", - args: []string{"-n", "foo"}, - expectError: false, + name: "Valid command with output", + command: "echo", + args: []string{"-n", "foo"}, + validateFunc: func(output string, err error) { + suite.Require().NoError(err) + suite.Require().NotEmpty(output) + }, }, { - name: "Invalid command", - command: "invalid", - args: []string{"foo"}, - expectError: true, - errorContains: "not found", + name: "Invalid command", + command: "invalid", + args: []string{"foo"}, + validateFunc: func(_ string, err error) { + suite.Require().Error(err) + suite.Require().Contains(err.Error(), "not found") + }, }, } @@ -81,21 +91,15 @@ func (suite *RunCmdPublicTestSuite) TestRunCmd() { suite.Run(tc.name, func() { em := exec.New(suite.logger, false) - output, err := em.RunCmd(tc.command, tc.args) - - if tc.expectError { - suite.Require().Error(err) - suite.Require().Contains(err.Error(), tc.errorContains) - } else { - suite.Require().NoError(err) - suite.Require().NotEmpty(output) - } + tc.validateFunc(em.RunCmd(tc.command, tc.args)) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestRunCmdPublicTestSuite(t *testing.T) { +func TestRunCmdPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(RunCmdPublicTestSuite)) } diff --git a/internal/exec/run_privileged_cmd_public_test.go b/internal/exec/run_privileged_cmd_public_test.go index af34202b3..383e68f04 100644 --- a/internal/exec/run_privileged_cmd_public_test.go +++ b/internal/exec/run_privileged_cmd_public_test.go @@ -141,6 +141,8 @@ func (s *RunPrivilegedCmdPublicTestSuite) TestRunPrivilegedCmd() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestRunPrivilegedCmdPublicTestSuite(t *testing.T) { +func TestRunPrivilegedCmdPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(RunPrivilegedCmdPublicTestSuite)) } diff --git a/internal/facts/keys.go b/internal/facts/keys.go index 5c956b2fb..f62f16096 100644 --- a/internal/facts/keys.go +++ b/internal/facts/keys.go @@ -56,7 +56,9 @@ func BuiltInKeys() []string { // IsKnownKey reports whether key is a recognized fact key. // Known keys are the built-in keys plus any key with the "custom." // prefix followed by at least one character. -func IsKnownKey(key string) bool { +func IsKnownKey( + key string, +) bool { switch key { case KeyInterfacePrimary, KeyHostname, KeyArch, KeyKernel, KeyFQDN, KeyContainerized: return true @@ -67,6 +69,8 @@ func IsKnownKey(key string) bool { // IsCustomKey reports whether key is a valid custom fact key // (starts with "custom." and has at least one character after the prefix). -func IsCustomKey(key string) bool { +func IsCustomKey( + key string, +) bool { return strings.HasPrefix(key, CustomPrefix) && len(key) > len(CustomPrefix) } diff --git a/internal/facts/keys_public_test.go b/internal/facts/keys_public_test.go index a00ce08eb..6ae849567 100644 --- a/internal/facts/keys_public_test.go +++ b/internal/facts/keys_public_test.go @@ -70,129 +70,169 @@ func (s *KeysPublicTestSuite) TestBuiltInKeys() { func (s *KeysPublicTestSuite) TestIsKnownKey() { tests := []struct { - name string - key string - wantOK bool + name string + key string + validateFunc func(bool) }{ { - name: "when interface.primary", - key: facts.KeyInterfacePrimary, - wantOK: true, + name: "when interface.primary", + key: facts.KeyInterfacePrimary, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when hostname", - key: facts.KeyHostname, - wantOK: true, + name: "when hostname", + key: facts.KeyHostname, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when arch", - key: facts.KeyArch, - wantOK: true, + name: "when arch", + key: facts.KeyArch, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when kernel", - key: facts.KeyKernel, - wantOK: true, + name: "when kernel", + key: facts.KeyKernel, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when fqdn", - key: facts.KeyFQDN, - wantOK: true, + name: "when fqdn", + key: facts.KeyFQDN, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when containerized", - key: facts.KeyContainerized, - wantOK: true, + name: "when containerized", + key: facts.KeyContainerized, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when valid custom key", - key: "custom.gateway", - wantOK: true, + name: "when valid custom key", + key: "custom.gateway", + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when valid custom key with dots", - key: "custom.network.gateway", - wantOK: true, + name: "when valid custom key with dots", + key: "custom.network.gateway", + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when custom prefix only", - key: "custom.", - wantOK: false, + name: "when custom prefix only", + key: "custom.", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when empty string", - key: "", - wantOK: false, + name: "when empty string", + key: "", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when unknown key", - key: "unknown", - wantOK: false, + name: "when unknown key", + key: "unknown", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when partial match", - key: "host", - wantOK: false, + name: "when partial match", + key: "host", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when not fact prefix", - key: "@notfact.x", - wantOK: false, + name: "when not fact prefix", + key: "@notfact.x", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - s.Equal(tt.wantOK, facts.IsKnownKey(tt.key)) + tt.validateFunc(facts.IsKnownKey(tt.key)) }) } } func (s *KeysPublicTestSuite) TestIsCustomKey() { tests := []struct { - name string - key string - wantOK bool + name string + key string + validateFunc func(bool) }{ { - name: "when valid custom key", - key: "custom.gateway", - wantOK: true, + name: "when valid custom key", + key: "custom.gateway", + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when valid custom key with nested dots", - key: "custom.network.primary.gateway", - wantOK: true, + name: "when valid custom key with nested dots", + key: "custom.network.primary.gateway", + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when custom prefix only", - key: "custom.", - wantOK: false, + name: "when custom prefix only", + key: "custom.", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when empty string", - key: "", - wantOK: false, + name: "when empty string", + key: "", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when built-in key", - key: "hostname", - wantOK: false, + name: "when built-in key", + key: "hostname", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when partial custom prefix", - key: "custo", - wantOK: false, + name: "when partial custom prefix", + key: "custo", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - s.Equal(tt.wantOK, facts.IsCustomKey(tt.key)) + tt.validateFunc(facts.IsCustomKey(tt.key)) }) } } -func TestKeysPublicTestSuite(t *testing.T) { +func TestKeysPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(KeysPublicTestSuite)) } diff --git a/internal/job/client/agent_drain_public_test.go b/internal/job/client/agent_drain_public_test.go index cf7229ce1..63328bc1a 100644 --- a/internal/job/client/agent_drain_public_test.go +++ b/internal/job/client/agent_drain_public_test.go @@ -82,11 +82,11 @@ func (s *AgentDrainPublicTestSuite) newClientWithoutState() *client.Client { func (s *AgentDrainPublicTestSuite) TestCheckDrainFlag() { tests := []struct { - name string - hostname string - useState bool - setupMocks func(*jobmocks.MockKeyValue) - expected bool + name string + hostname string + useState bool + setupMocks func(*jobmocks.MockKeyValue) + validateFunc func(bool) }{ { name: "when drain flag exists returns true", @@ -98,7 +98,9 @@ func (s *AgentDrainPublicTestSuite) TestCheckDrainFlag() { Get(gomock.Any(), "drain.server1"). Return(entry, nil) }, - expected: true, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { name: "when drain flag missing returns false", @@ -109,13 +111,17 @@ func (s *AgentDrainPublicTestSuite) TestCheckDrainFlag() { Get(gomock.Any(), "drain.server1"). Return(nil, errors.New("key not found")) }, - expected: false, + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { name: "when stateKV is nil returns false", hostname: "server1", useState: false, - expected: false, + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, } @@ -133,19 +139,18 @@ func (s *AgentDrainPublicTestSuite) TestCheckDrainFlag() { } result := jobsClient.CheckDrainFlag(s.ctx, tt.hostname) - s.Equal(tt.expected, result) + tt.validateFunc(result) }) } } func (s *AgentDrainPublicTestSuite) TestSetDrainFlag() { tests := []struct { - name string - hostname string - useState bool - setupMocks func(*jobmocks.MockKeyValue) - expectError bool - errorMsg string + name string + hostname string + useState bool + setupMocks func(*jobmocks.MockKeyValue) + validateFunc func(error) }{ { name: "when write succeeds sets drain flag", @@ -156,6 +161,9 @@ func (s *AgentDrainPublicTestSuite) TestSetDrainFlag() { Put(gomock.Any(), "drain.server1", []byte("1")). Return(uint64(1), nil) }, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when KV put fails returns error", @@ -166,15 +174,19 @@ func (s *AgentDrainPublicTestSuite) TestSetDrainFlag() { Put(gomock.Any(), "drain.server1", []byte("1")). Return(uint64(0), errors.New("kv connection failed")) }, - expectError: true, - errorMsg: "set drain flag", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "set drain flag") + }, }, { - name: "when stateKV is nil returns error", - hostname: "server1", - useState: false, - expectError: true, - errorMsg: "agent state bucket not configured", + name: "when stateKV is nil returns error", + hostname: "server1", + useState: false, + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "agent state bucket not configured") + }, }, } @@ -191,26 +203,18 @@ func (s *AgentDrainPublicTestSuite) TestSetDrainFlag() { jobsClient = s.newClientWithoutState() } - err := jobsClient.SetDrainFlag(s.ctx, tt.hostname) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - } else { - s.NoError(err) - } + tt.validateFunc(jobsClient.SetDrainFlag(s.ctx, tt.hostname)) }) } } func (s *AgentDrainPublicTestSuite) TestDeleteDrainFlag() { tests := []struct { - name string - hostname string - useState bool - setupMocks func(*jobmocks.MockKeyValue) - expectError bool - errorMsg string + name string + hostname string + useState bool + setupMocks func(*jobmocks.MockKeyValue) + validateFunc func(error) }{ { name: "when delete succeeds removes drain flag", @@ -221,6 +225,9 @@ func (s *AgentDrainPublicTestSuite) TestDeleteDrainFlag() { Delete(gomock.Any(), "drain.server1"). Return(nil) }, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when KV delete fails returns error", @@ -231,15 +238,19 @@ func (s *AgentDrainPublicTestSuite) TestDeleteDrainFlag() { Delete(gomock.Any(), "drain.server1"). Return(errors.New("kv connection failed")) }, - expectError: true, - errorMsg: "delete drain flag", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "delete drain flag") + }, }, { - name: "when stateKV is nil returns error", - hostname: "server1", - useState: false, - expectError: true, - errorMsg: "agent state bucket not configured", + name: "when stateKV is nil returns error", + hostname: "server1", + useState: false, + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "agent state bucket not configured") + }, }, } @@ -256,24 +267,17 @@ func (s *AgentDrainPublicTestSuite) TestDeleteDrainFlag() { jobsClient = s.newClientWithoutState() } - err := jobsClient.DeleteDrainFlag(s.ctx, tt.hostname) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - } else { - s.NoError(err) - } + tt.validateFunc(jobsClient.DeleteDrainFlag(s.ctx, tt.hostname)) }) } } func (s *AgentDrainPublicTestSuite) TestOverlayDrainState() { tests := []struct { - name string - useState bool - setupMocks func(*jobmocks.MockKeyValue) - expectedState string + name string + useState bool + setupMocks func(*jobmocks.MockKeyValue) + validateFunc func(string) }{ { name: "when drain flag exists sets state to Cordoned", @@ -284,7 +288,9 @@ func (s *AgentDrainPublicTestSuite) TestOverlayDrainState() { Get(gomock.Any(), "drain.abc123"). Return(entry, nil) }, - expectedState: job.AgentStateCordoned, + validateFunc: func(got string) { + s.Equal(job.AgentStateCordoned, got) + }, }, { name: "when drain flag missing keeps original state", @@ -294,12 +300,16 @@ func (s *AgentDrainPublicTestSuite) TestOverlayDrainState() { Get(gomock.Any(), "drain.abc123"). Return(nil, errors.New("key not found")) }, - expectedState: "", + validateFunc: func(got string) { + s.Equal("", got) + }, }, { - name: "when stateKV is nil keeps original state", - useState: false, - expectedState: "", + name: "when stateKV is nil keeps original state", + useState: false, + validateFunc: func(got string) { + s.Equal("", got) + }, }, } @@ -341,11 +351,13 @@ func (s *AgentDrainPublicTestSuite) TestOverlayDrainState() { info, err := jobsClient.GetAgent(s.ctx, "abc123") s.NoError(err) - s.Equal(tt.expectedState, info.State) + tt.validateFunc(info.State) }) } } -func TestAgentDrainPublicTestSuite(t *testing.T) { +func TestAgentDrainPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentDrainPublicTestSuite)) } diff --git a/internal/job/client/agent_public_test.go b/internal/job/client/agent_public_test.go index 487d86d2b..7bdab5f6c 100644 --- a/internal/job/client/agent_public_test.go +++ b/internal/job/client/agent_public_test.go @@ -71,15 +71,14 @@ func (s *AgentPublicTestSuite) TearDownTest() { func (s *AgentPublicTestSuite) TestWriteStatusEvent() { tests := []struct { - name string - jobID string - event string - hostname string - data map[string]interface{} - kvError error - expectError bool - errorMsg string - setupMocks func() + name string + jobID string + event string + hostname string + data map[string]interface{} + kvError error + setupMocks func() + validateFunc func(error) }{ { name: "successful status event with data", @@ -93,6 +92,9 @@ func (s *AgentPublicTestSuite) TestWriteStatusEvent() { KVPut("test-bucket", gomock.Any(), gomock.Any()). Return(nil) }, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "successful status event without data", @@ -106,6 +108,9 @@ func (s *AgentPublicTestSuite) TestWriteStatusEvent() { KVPut("test-bucket", gomock.Any(), gomock.Any()). Return(nil) }, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "hostname with special characters", @@ -119,21 +124,26 @@ func (s *AgentPublicTestSuite) TestWriteStatusEvent() { KVPut("test-bucket", gomock.Any(), gomock.Any()). Return(nil) }, + validateFunc: func(err error) { + s.NoError(err) + }, }, { - name: "KV put error", - jobID: "job-error", - event: "started", - hostname: "agent-1", - data: map[string]interface{}{"key": "value"}, - expectError: true, - errorMsg: "failed to write status event", + name: "KV put error", + jobID: "job-error", + event: "started", + hostname: "agent-1", + data: map[string]interface{}{"key": "value"}, setupMocks: func() { s.mockKV.EXPECT().Bucket().Return("test-bucket") s.mockNATSClient.EXPECT(). KVPut("test-bucket", gomock.Any(), gomock.Any()). Return(errors.New("kv connection failed")) }, + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "failed to write status event") + }, }, { name: "empty job ID", @@ -147,16 +157,21 @@ func (s *AgentPublicTestSuite) TestWriteStatusEvent() { KVPut("test-bucket", gomock.Any(), gomock.Any()). Return(nil) }, + validateFunc: func(err error) { + s.NoError(err) + }, }, { - name: "unmarshalable data", - jobID: "job-marshal", - event: "started", - hostname: "agent-1", - data: map[string]interface{}{"fn": make(chan int)}, - expectError: true, - errorMsg: "failed to marshal status event", - setupMocks: func() {}, + name: "unmarshalable data", + jobID: "job-marshal", + event: "started", + hostname: "agent-1", + data: map[string]interface{}{"fn": make(chan int)}, + setupMocks: func() {}, + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "failed to marshal status event") + }, }, } @@ -164,14 +179,9 @@ func (s *AgentPublicTestSuite) TestWriteStatusEvent() { s.Run(tt.name, func() { tt.setupMocks() - err := s.jobsClient.WriteStatusEvent(s.ctx, tt.jobID, tt.event, tt.hostname, tt.data) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - } else { - s.NoError(err) - } + tt.validateFunc( + s.jobsClient.WriteStatusEvent(s.ctx, tt.jobID, tt.event, tt.hostname, tt.data), + ) }) } } @@ -186,8 +196,7 @@ func (s *AgentPublicTestSuite) TestWriteJobResponse() { errorMsg string changed *bool kvError error - expectError bool - errorText string + validateFunc func(error) }{ { name: "successful job response completed", @@ -195,6 +204,9 @@ func (s *AgentPublicTestSuite) TestWriteJobResponse() { hostname: "agent-1", responseData: []byte(`{"result": "success", "count": 42}`), status: "completed", + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "successful job response with error", @@ -203,6 +215,9 @@ func (s *AgentPublicTestSuite) TestWriteJobResponse() { responseData: []byte(`{"error": "processing failed"}`), status: "failed", errorMsg: "job execution failed", + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "empty response data", @@ -210,6 +225,9 @@ func (s *AgentPublicTestSuite) TestWriteJobResponse() { hostname: "agent-3", responseData: []byte{}, status: "completed", + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "hostname with special characters", @@ -217,6 +235,9 @@ func (s *AgentPublicTestSuite) TestWriteJobResponse() { hostname: "agent.host-name@domain.com", responseData: []byte(`{"data": "test"}`), status: "completed", + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "KV put error", @@ -225,8 +246,10 @@ func (s *AgentPublicTestSuite) TestWriteJobResponse() { responseData: []byte(`{"result": "success"}`), status: "completed", kvError: errors.New("storage failure"), - expectError: true, - errorText: "failed to store job response", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "failed to store job response") + }, }, { name: "large response data", @@ -239,6 +262,9 @@ func (s *AgentPublicTestSuite) TestWriteJobResponse() { ) + `"}`, ), status: "completed", + validateFunc: func(err error) { + s.NoError(err) + }, }, } @@ -249,7 +275,7 @@ func (s *AgentPublicTestSuite) TestWriteJobResponse() { KVPut("test-bucket", gomock.Any(), gomock.Any()). Return(tt.kvError) - err := s.jobsClient.WriteJobResponse( + tt.validateFunc(s.jobsClient.WriteJobResponse( s.ctx, tt.jobID, tt.hostname, @@ -257,14 +283,7 @@ func (s *AgentPublicTestSuite) TestWriteJobResponse() { tt.status, tt.errorMsg, tt.changed, - ) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorText) - } else { - s.NoError(err) - } + )) }) } } @@ -281,8 +300,7 @@ func (s *AgentPublicTestSuite) TestWriteJobResponseWithPKISigner() { errorMsg string changed *bool kvError error - expectError bool - errorText string + validateFunc func(error) }{ { name: "when PKI signer signs response before KV write", @@ -290,6 +308,9 @@ func (s *AgentPublicTestSuite) TestWriteJobResponseWithPKISigner() { hostname: "agent-1", responseData: []byte(`{"result": "signed"}`), status: "completed", + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when PKI signer and KV write fails", @@ -298,8 +319,10 @@ func (s *AgentPublicTestSuite) TestWriteJobResponseWithPKISigner() { responseData: []byte(`{"result": "fail"}`), status: "completed", kvError: errors.New("storage failure"), - expectError: true, - errorText: "failed to store job response", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "failed to store job response") + }, }, } @@ -321,7 +344,7 @@ func (s *AgentPublicTestSuite) TestWriteJobResponseWithPKISigner() { KVPut("test-bucket", gomock.Any(), gomock.Any()). Return(tt.kvError) - err = pkiClient.WriteJobResponse( + tt.validateFunc(pkiClient.WriteJobResponse( s.ctx, tt.jobID, tt.hostname, @@ -329,14 +352,7 @@ func (s *AgentPublicTestSuite) TestWriteJobResponseWithPKISigner() { tt.status, tt.errorMsg, tt.changed, - ) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorText) - } else { - s.NoError(err) - } + )) }) } } @@ -383,9 +399,8 @@ func (s *AgentPublicTestSuite) TestConsumeJobs() { handler func(jetstream.Msg) error opts *natsclient.ConsumeOptions consumeError error - expectError bool - errorMsg string invokeHandler bool + validateFunc func(error) }{ { name: "handler invoked per message", @@ -395,6 +410,9 @@ func (s *AgentPublicTestSuite) TestConsumeJobs() { return nil }, invokeHandler: true, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "successful job consumption with options", @@ -407,6 +425,9 @@ func (s *AgentPublicTestSuite) TestConsumeJobs() { QueueGroup: "test-queue", MaxInFlight: 5, }, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "NATS consume error", @@ -416,8 +437,10 @@ func (s *AgentPublicTestSuite) TestConsumeJobs() { return nil }, consumeError: errors.New("stream not found"), - expectError: true, - errorMsg: "stream not found", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "stream not found") + }, }, } @@ -441,20 +464,13 @@ func (s *AgentPublicTestSuite) TestConsumeJobs() { Return(tt.consumeError) } - err := s.jobsClient.ConsumeJobs( + tt.validateFunc(s.jobsClient.ConsumeJobs( s.ctx, tt.streamName, tt.consumerName, tt.handler, tt.opts, - ) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - } else { - s.NoError(err) - } + )) }) } } @@ -463,9 +479,8 @@ func (s *AgentPublicTestSuite) TestGetJobData() { tests := []struct { name string jobKey string - expectedErr string setupMocks func() - expectedData []byte + validateFunc func([]byte, error) }{ { name: "successful get job data", @@ -475,17 +490,23 @@ func (s *AgentPublicTestSuite) TestGetJobData() { mockEntry.EXPECT().Value().Return([]byte(`{"test": "data"}`)) s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-123").Return(mockEntry, nil) }, - expectedData: []byte(`{"test": "data"}`), + validateFunc: func(data []byte, err error) { + s.NoError(err) + s.Equal([]byte(`{"test": "data"}`), data) + }, }, { - name: "job not found error", - jobKey: "jobs.nonexistent", - expectedErr: "failed to get job data for key jobs.nonexistent", + name: "job not found error", + jobKey: "jobs.nonexistent", setupMocks: func() { s.mockKV.EXPECT(). Get(gomock.Any(), "jobs.nonexistent"). Return(nil, errors.New("key not found")) }, + validateFunc: func(_ []byte, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to get job data for key jobs.nonexistent") + }, }, } @@ -493,15 +514,7 @@ func (s *AgentPublicTestSuite) TestGetJobData() { s.Run(tt.name, func() { tt.setupMocks() - data, err := s.jobsClient.GetJobData(s.ctx, tt.jobKey) - - if tt.expectedErr != "" { - s.Error(err) - s.Contains(err.Error(), tt.expectedErr) - } else { - s.NoError(err) - s.Equal(tt.expectedData, data) - } + tt.validateFunc(s.jobsClient.GetJobData(s.ctx, tt.jobKey)) }) } } @@ -511,8 +524,8 @@ func (s *AgentPublicTestSuite) TestCreateOrUpdateConsumer() { name string streamName string consumerConfig jetstream.ConsumerConfig - expectedErr string setupMocks func() + validateFunc func(error) }{ { name: "successful consumer creation", @@ -523,17 +536,23 @@ func (s *AgentPublicTestSuite) TestCreateOrUpdateConsumer() { CreateOrUpdateConsumerWithConfig(gomock.Any(), "test-stream", jetstream.ConsumerConfig{Name: "test-consumer"}). Return(nil) }, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "consumer creation error", streamName: "test-stream", consumerConfig: jetstream.ConsumerConfig{Name: "test-consumer"}, - expectedErr: "consumer creation failed", setupMocks: func() { s.mockNATSClient.EXPECT(). CreateOrUpdateConsumerWithConfig(gomock.Any(), "test-stream", jetstream.ConsumerConfig{Name: "test-consumer"}). Return(errors.New("consumer creation failed")) }, + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "consumer creation failed") + }, }, } @@ -541,80 +560,95 @@ func (s *AgentPublicTestSuite) TestCreateOrUpdateConsumer() { s.Run(tt.name, func() { tt.setupMocks() - err := s.jobsClient.CreateOrUpdateConsumer(s.ctx, tt.streamName, tt.consumerConfig) - - if tt.expectedErr != "" { - s.Error(err) - s.Contains(err.Error(), tt.expectedErr) - } else { - s.NoError(err) - } + tt.validateFunc( + s.jobsClient.CreateOrUpdateConsumer(s.ctx, tt.streamName, tt.consumerConfig), + ) }) } } func (s *AgentPublicTestSuite) TestSanitizeKeyForNATS() { tests := []struct { - name string - input string - expected string + name string + input string + validateFunc func(string) }{ { - name: "valid characters only", - input: "validKey123", - expected: "validKey123", + name: "valid characters only", + input: "validKey123", + validateFunc: func(got string) { + s.Equal("validKey123", got) + }, }, { - name: "alphanumeric with underscores and hyphens", - input: "valid_key-123", - expected: "valid_key-123", + name: "alphanumeric with underscores and hyphens", + input: "valid_key-123", + validateFunc: func(got string) { + s.Equal("valid_key-123", got) + }, }, { - name: "hostname with dots", - input: "server.example.com", - expected: "server_example_com", + name: "hostname with dots", + input: "server.example.com", + validateFunc: func(got string) { + s.Equal("server_example_com", got) + }, }, { - name: "hostname with special characters", - input: "agent.host-name@domain.com", - expected: "agent_host-name_domain_com", + name: "hostname with special characters", + input: "agent.host-name@domain.com", + validateFunc: func(got string) { + s.Equal("agent_host-name_domain_com", got) + }, }, { - name: "email-like string", - input: "user@domain.com", - expected: "user_domain_com", + name: "email-like string", + input: "user@domain.com", + validateFunc: func(got string) { + s.Equal("user_domain_com", got) + }, }, { - name: "string with spaces", - input: "agent node 1", - expected: "agent_node_1", + name: "string with spaces", + input: "agent node 1", + validateFunc: func(got string) { + s.Equal("agent_node_1", got) + }, }, { - name: "string with mixed special characters", - input: "agent#1!@#$%^&*()", - expected: "agent_1__________", + name: "string with mixed special characters", + input: "agent#1!@#$%^&*()", + validateFunc: func(got string) { + s.Equal("agent_1__________", got) + }, }, { - name: "empty string", - input: "", - expected: "", + name: "empty string", + input: "", + validateFunc: func(got string) { + s.Equal("", got) + }, }, { - name: "only special characters", - input: "!@#$%^&*()", - expected: "__________", + name: "only special characters", + input: "!@#$%^&*()", + validateFunc: func(got string) { + s.Equal("__________", got) + }, }, { - name: "path-like string", - input: "/path/to/resource", - expected: "_path_to_resource", + name: "path-like string", + input: "/path/to/resource", + validateFunc: func(got string) { + s.Equal("_path_to_resource", got) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { got := client.ExportSanitizeKeyForNATS(tt.input) - s.Equal(tt.expected, got) + tt.validateFunc(got) }) } } @@ -638,7 +672,9 @@ func (s *AgentPublicTestSuite) newClientWithAllKVs( } // agentRegistrationJSON returns valid agent registration JSON for the given hostname. -func agentRegistrationJSON(hostname string) []byte { +func agentRegistrationJSON( + hostname string, +) []byte { return agentRegistrationJSONWithMachineID(hostname, "abc123") } @@ -1284,6 +1320,8 @@ func (s *AgentPublicTestSuite) TestMergeFacts() { } } -func TestAgentPublicTestSuite(t *testing.T) { +func TestAgentPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentPublicTestSuite)) } diff --git a/internal/job/client/agent_timeline_public_test.go b/internal/job/client/agent_timeline_public_test.go index df787e01a..335a7444c 100644 --- a/internal/job/client/agent_timeline_public_test.go +++ b/internal/job/client/agent_timeline_public_test.go @@ -83,15 +83,14 @@ func (s *AgentTimelinePublicTestSuite) newClientWithoutState() *client.Client { func (s *AgentTimelinePublicTestSuite) TestWriteAgentTimelineEvent() { tests := []struct { - name string - hostname string - event string - message string - useState bool - marshalErr bool - setupMocks func(*jobmocks.MockKeyValue) - expectError bool - errorMsg string + name string + hostname string + event string + message string + useState bool + marshalErr bool + setupMocks func(*jobmocks.MockKeyValue) + validateFunc func(error) }{ { name: "when write succeeds stores timeline event", @@ -120,6 +119,9 @@ func (s *AgentTimelinePublicTestSuite) TestWriteAgentTimelineEvent() { return 1, nil }) }, + validateFunc: func(err error) { + s.NoError(err) + }, }, { name: "when KV put fails returns error", @@ -132,17 +134,21 @@ func (s *AgentTimelinePublicTestSuite) TestWriteAgentTimelineEvent() { Put(gomock.Any(), gomock.Any(), gomock.Any()). Return(uint64(0), errors.New("kv connection failed")) }, - expectError: true, - errorMsg: "write timeline event", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "write timeline event") + }, }, { - name: "when stateKV is nil returns error", - hostname: "server1", - event: "drain", - message: "drain requested", - useState: false, - expectError: true, - errorMsg: "agent state bucket not configured", + name: "when stateKV is nil returns error", + hostname: "server1", + event: "drain", + message: "drain requested", + useState: false, + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "agent state bucket not configured") + }, }, { name: "when json marshal fails returns error", @@ -154,8 +160,10 @@ func (s *AgentTimelinePublicTestSuite) TestWriteAgentTimelineEvent() { setupMocks: func(_ *jobmocks.MockKeyValue) { // No KV expectations — marshal fails before Put }, - expectError: true, - errorMsg: "marshal timeline event", + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "marshal timeline event") + }, }, } @@ -178,19 +186,12 @@ func (s *AgentTimelinePublicTestSuite) TestWriteAgentTimelineEvent() { } } - err := jobsClient.WriteAgentTimelineEvent( + tt.validateFunc(jobsClient.WriteAgentTimelineEvent( s.ctx, tt.hostname, tt.event, tt.message, - ) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorMsg) - } else { - s.NoError(err) - } + )) }) } } @@ -403,19 +404,23 @@ func (s *AgentTimelinePublicTestSuite) TestGetAgentTimeline() { func (s *AgentTimelinePublicTestSuite) TestComputeAgentState() { tests := []struct { - name string - events []job.TimelineEvent - expectedState string + name string + events []job.TimelineEvent + validateFunc func(string) }{ { - name: "when no events returns Ready", - events: []job.TimelineEvent{}, - expectedState: job.AgentStateReady, + name: "when no events returns Ready", + events: []job.TimelineEvent{}, + validateFunc: func(got string) { + s.Equal(job.AgentStateReady, got) + }, }, { - name: "when nil events returns Ready", - events: nil, - expectedState: job.AgentStateReady, + name: "when nil events returns Ready", + events: nil, + validateFunc: func(got string) { + s.Equal(job.AgentStateReady, got) + }, }, { name: "when latest event is drain returns Draining", @@ -427,7 +432,9 @@ func (s *AgentTimelinePublicTestSuite) TestComputeAgentState() { Message: "drain requested", }, }, - expectedState: job.AgentStateDraining, + validateFunc: func(got string) { + s.Equal(job.AgentStateDraining, got) + }, }, { name: "when latest event is cordoned returns Cordoned", @@ -439,7 +446,9 @@ func (s *AgentTimelinePublicTestSuite) TestComputeAgentState() { Message: "node cordoned", }, }, - expectedState: job.AgentStateCordoned, + validateFunc: func(got string) { + s.Equal(job.AgentStateCordoned, got) + }, }, { name: "when latest event is undrain returns Ready", @@ -457,7 +466,9 @@ func (s *AgentTimelinePublicTestSuite) TestComputeAgentState() { Message: "undrain requested", }, }, - expectedState: job.AgentStateReady, + validateFunc: func(got string) { + s.Equal(job.AgentStateReady, got) + }, }, { name: "when latest event is ready returns Ready", @@ -475,7 +486,9 @@ func (s *AgentTimelinePublicTestSuite) TestComputeAgentState() { Message: "agent ready", }, }, - expectedState: job.AgentStateReady, + validateFunc: func(got string) { + s.Equal(job.AgentStateReady, got) + }, }, { name: "when latest event is unknown returns Ready", @@ -487,18 +500,22 @@ func (s *AgentTimelinePublicTestSuite) TestComputeAgentState() { Message: "unknown event", }, }, - expectedState: job.AgentStateReady, + validateFunc: func(got string) { + s.Equal(job.AgentStateReady, got) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { state := client.ComputeAgentState(tt.events) - s.Equal(tt.expectedState, state) + tt.validateFunc(state) }) } } -func TestAgentTimelinePublicTestSuite(t *testing.T) { +func TestAgentTimelinePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentTimelinePublicTestSuite)) } diff --git a/internal/job/client/client_public_test.go b/internal/job/client/client_public_test.go index 5aa6ab0f4..54fbdcd1e 100644 --- a/internal/job/client/client_public_test.go +++ b/internal/job/client/client_public_test.go @@ -40,7 +40,9 @@ import ( ) // registrationJSON returns a minimal agent registration JSON for the given hostname. -func registrationJSON(hostname string) []byte { +func registrationJSON( + hostname string, +) []byte { return []byte(fmt.Sprintf( `{"hostname":%q,"registered_at":"2026-01-01T00:00:00Z"}`, hostname, @@ -1274,9 +1276,9 @@ func (s *ClientPublicTestSuite) TestQueryWithPKISignerSignError() { signer, _ := newSigner(gomock.NewController(s.T())) tests := []struct { - name string - setupFn func() - expectedErr string + name string + setupFn func() + validateFunc func(string, *job.Response, error) }{ { name: "when signing marshal fails returns sign error", @@ -1285,7 +1287,10 @@ func (s *ClientPublicTestSuite) TestQueryWithPKISignerSignError() { return nil, errors.New("marshal boom") }) }, - expectedErr: "failed to sign job data", + validateFunc: func(_ string, _ *job.Response, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to sign job data") + }, }, } @@ -1302,9 +1307,7 @@ func (s *ClientPublicTestSuite) TestQueryWithPKISignerSignError() { c, err := client.New(slog.Default(), s.mockNATSClient, opts) s.Require().NoError(err) - _, _, err = c.Query(s.ctx, target, category, operation, nil) - s.Error(err) - s.Contains(err.Error(), tt.expectedErr) + tt.validateFunc(c.Query(s.ctx, target, category, operation, nil)) }) } } @@ -1621,6 +1624,249 @@ func (s *ClientPublicTestSuite) TestQueryWithTargetResolver() { s.Equal(job.StatusCompleted, resp.Status) } -func TestClientPublicTestSuite(t *testing.T) { +func TestClientPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ClientPublicTestSuite)) } + +// publishAndWaitErrorMode controls which step of the publishAndWait flow fails. +type publishAndWaitErrorMode int + +const ( + // errorOnKVPut makes kv.Put return the error. + errorOnKVPut publishAndWaitErrorMode = iota + // errorOnPublish makes natsClient.Publish return the error. + errorOnPublish + // errorOnWatch makes kv.Watch return the error. + errorOnWatch + // errorOnTimeout simulates a timeout by providing a channel that never sends. + errorOnTimeout + // errorOnTimeoutWithPartialResponse sends one valid response then blocks, + // simulating a timeout after partial collection. Only valid for + // publishAndCollect (broadcast) flows. + errorOnTimeoutWithPartialResponse +) + +// publishAndWaitMockOpts configures the mock behavior for publishAndWait tests. +type publishAndWaitMockOpts struct { + // responseData is the JSON response to return from the watcher entry. + responseData string + // mockError is the error to inject (used with errorMode). + mockError error + // errorMode controls which step fails when mockError is set. + errorMode publishAndWaitErrorMode + // sendNilFirst sends a nil entry before the real entry on the watcher channel. + sendNilFirst bool +} + +// setupPublishAndWaitMocks configures mocks for the publishAndWait flow. +func setupPublishAndWaitMocks( + ctrl *gomock.Controller, + mockKV *jobmocks.MockKeyValue, + mockNATSClient *jobmocks.MockNATSClient, + subject string, + responseData string, + mockError error, +) { + setupPublishAndWaitMocksWithOpts(ctrl, mockKV, mockNATSClient, subject, &publishAndWaitMockOpts{ + responseData: responseData, + mockError: mockError, + errorMode: errorOnKVPut, + }) +} + +// publishAndCollectMockOpts configures mock behavior for publishAndCollect tests. +type publishAndCollectMockOpts struct { + // responseEntries is a list of JSON response strings to send on the watcher. + responseEntries []string + // mockError is the error to inject (used with errorMode). + mockError error + // errorMode controls which step fails when mockError is set. + errorMode publishAndWaitErrorMode + // sendNilFirst sends a nil entry before the response entries on the watcher channel. + sendNilFirst bool +} + +// setupPublishAndCollectMocks configures mocks for the publishAndCollect flow. +func setupPublishAndCollectMocks( + ctrl *gomock.Controller, + mockKV *jobmocks.MockKeyValue, + mockNATSClient *jobmocks.MockNATSClient, + subject string, + opts *publishAndCollectMockOpts, +) { + if opts.mockError != nil && opts.errorMode == errorOnKVPut { + mockKV.EXPECT(). + Put(gomock.Any(), gomock.Any(), gomock.Any()). + Return(uint64(0), opts.mockError) + return + } + + // kv.Put succeeds + mockKV.EXPECT(). + Put(gomock.Any(), gomock.Any(), gomock.Any()). + Return(uint64(1), nil) + + if opts.mockError != nil && opts.errorMode == errorOnPublish { + mockNATSClient.EXPECT(). + Publish(gomock.Any(), subject, gomock.Any()). + Return(opts.mockError) + return + } + + // natsClient.Publish succeeds + mockNATSClient.EXPECT(). + Publish(gomock.Any(), subject, gomock.Any()). + Return(nil) + + if opts.mockError != nil && opts.errorMode == errorOnWatch { + mockKV.EXPECT(). + Watch(gomock.Any(), gomock.Any()). + Return(nil, opts.mockError) + return + } + + if opts.mockError != nil && opts.errorMode == errorOnTimeout { + // Return a channel that never sends anything, causing timeout with 0 responses + ch := make(chan jetstream.KeyValueEntry) + + mockWatcher := jobmocks.NewMockKeyWatcher(ctrl) + mockWatcher.EXPECT().Updates().Return(ch).AnyTimes() + mockWatcher.EXPECT().Stop().Return(nil) + + mockKV.EXPECT(). + Watch(gomock.Any(), gomock.Any()). + Return(mockWatcher, nil) + return + } + + if opts.mockError != nil && opts.errorMode == errorOnTimeoutWithPartialResponse { + // Send one valid response then block so the timeout fires with partial results. + // The first responseEntry provides the partial response data. + ch := make(chan jetstream.KeyValueEntry, 1) + mockEntry := jobmocks.NewMockKeyValueEntry(ctrl) + responseData := "" + if len(opts.responseEntries) > 0 { + responseData = opts.responseEntries[0] + } + mockEntry.EXPECT().Value().Return([]byte(responseData)) + ch <- mockEntry + + mockWatcher := jobmocks.NewMockKeyWatcher(ctrl) + mockWatcher.EXPECT().Updates().Return(ch).AnyTimes() + mockWatcher.EXPECT().Stop().Return(nil) + + mockKV.EXPECT(). + Watch(gomock.Any(), gomock.Any()). + Return(mockWatcher, nil) + return + } + + // Create buffered channel with all response entries + bufSize := len(opts.responseEntries) + if opts.sendNilFirst { + bufSize++ + } + ch := make(chan jetstream.KeyValueEntry, bufSize) + if opts.sendNilFirst { + ch <- nil + } + for _, data := range opts.responseEntries { + if data == "" { + continue + } + mockEntry := jobmocks.NewMockKeyValueEntry(ctrl) + mockEntry.EXPECT().Value().Return([]byte(data)) + ch <- mockEntry + } + + // Create mock watcher + mockWatcher := jobmocks.NewMockKeyWatcher(ctrl) + mockWatcher.EXPECT().Updates().Return(ch).AnyTimes() + mockWatcher.EXPECT().Stop().Return(nil) + + // kv.Watch returns the mock watcher + mockKV.EXPECT(). + Watch(gomock.Any(), gomock.Any()). + Return(mockWatcher, nil) +} + +// setupPublishAndWaitMocksWithOpts configures mocks with fine-grained control. +func setupPublishAndWaitMocksWithOpts( + ctrl *gomock.Controller, + mockKV *jobmocks.MockKeyValue, + mockNATSClient *jobmocks.MockNATSClient, + subject string, + opts *publishAndWaitMockOpts, +) { + if opts.mockError != nil && opts.errorMode == errorOnKVPut { + mockKV.EXPECT(). + Put(gomock.Any(), gomock.Any(), gomock.Any()). + Return(uint64(0), opts.mockError) + return + } + + // kv.Put succeeds + mockKV.EXPECT(). + Put(gomock.Any(), gomock.Any(), gomock.Any()). + Return(uint64(1), nil) + + if opts.mockError != nil && opts.errorMode == errorOnPublish { + mockNATSClient.EXPECT(). + Publish(gomock.Any(), subject, gomock.Any()). + Return(opts.mockError) + return + } + + // natsClient.Publish succeeds + mockNATSClient.EXPECT(). + Publish(gomock.Any(), subject, gomock.Any()). + Return(nil) + + if opts.mockError != nil && opts.errorMode == errorOnWatch { + mockKV.EXPECT(). + Watch(gomock.Any(), gomock.Any()). + Return(nil, opts.mockError) + return + } + + if opts.mockError != nil && opts.errorMode == errorOnTimeout { + // Return a channel that never sends anything, causing timeout + ch := make(chan jetstream.KeyValueEntry) + + mockWatcher := jobmocks.NewMockKeyWatcher(ctrl) + mockWatcher.EXPECT().Updates().Return(ch).AnyTimes() + mockWatcher.EXPECT().Stop().Return(nil) + + mockKV.EXPECT(). + Watch(gomock.Any(), gomock.Any()). + Return(mockWatcher, nil) + return + } + + // Create mock entry with response data + mockEntry := jobmocks.NewMockKeyValueEntry(ctrl) + mockEntry.EXPECT().Value().Return([]byte(opts.responseData)) + + // Create buffered channel and optionally send nil first + bufSize := 1 + if opts.sendNilFirst { + bufSize = 2 + } + ch := make(chan jetstream.KeyValueEntry, bufSize) + if opts.sendNilFirst { + ch <- nil + } + ch <- mockEntry + + // Create mock watcher + mockWatcher := jobmocks.NewMockKeyWatcher(ctrl) + mockWatcher.EXPECT().Updates().Return(ch).AnyTimes() + mockWatcher.EXPECT().Stop().Return(nil) + + // kv.Watch returns the mock watcher + mockKV.EXPECT(). + Watch(gomock.Any(), gomock.Any()). + Return(mockWatcher, nil) +} diff --git a/internal/job/client/jobs_public_test.go b/internal/job/client/jobs_public_test.go index b37b24afe..3480cf654 100644 --- a/internal/job/client/jobs_public_test.go +++ b/internal/job/client/jobs_public_test.go @@ -90,19 +90,27 @@ func (s *JobsPublicTestSuite) TearDownSubTest() { func (s *JobsPublicTestSuite) TestNew() { tests := []struct { - name string - opts *client.Options - expectedErr string + name string + opts *client.Options + validateFunc func(*client.Client, error) }{ { - name: "nil options", - opts: nil, - expectedErr: "options cannot be nil", + name: "nil options", + opts: nil, + validateFunc: func(c *client.Client, err error) { + s.Error(err) + s.Contains(err.Error(), "options cannot be nil") + s.Nil(c) + }, }, { - name: "nil KV bucket", - opts: &client.Options{}, - expectedErr: "kvBucket cannot be nil", + name: "nil KV bucket", + opts: &client.Options{}, + validateFunc: func(c *client.Client, err error) { + s.Error(err) + s.Contains(err.Error(), "kvBucket cannot be nil") + s.Nil(c) + }, }, { name: "valid options", @@ -110,21 +118,16 @@ func (s *JobsPublicTestSuite) TestNew() { KVBucket: s.mockKV, Timeout: 30 * time.Second, }, + validateFunc: func(c *client.Client, err error) { + s.NoError(err) + s.NotNil(c) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - c, err := client.New(slog.Default(), s.mockNATSClient, tt.opts) - - if tt.expectedErr != "" { - s.Error(err) - s.Contains(err.Error(), tt.expectedErr) - s.Nil(c) - } else { - s.NoError(err) - s.NotNil(c) - } + tt.validateFunc(client.New(slog.Default(), s.mockNATSClient, tt.opts)) }) } } @@ -968,14 +971,12 @@ func (s *JobsPublicTestSuite) TestGetJobStatus() { func (s *JobsPublicTestSuite) TestListJobs() { tests := []struct { - name string - statusFilter string - limit int - offset int - expectedErr string - setupMocks func() - expectedJobs int - expectedTotalCount int + name string + statusFilter string + limit int + offset int + setupMocks func() + validateFunc func(*client.ListJobsResult, error) }{ { name: "no jobs found", @@ -983,15 +984,22 @@ func (s *JobsPublicTestSuite) TestListJobs() { setupMocks: func() { s.mockKV.EXPECT().Keys(gomock.Any()).Return(nil, jetstream.ErrNoKeysFound) }, - expectedJobs: 0, - expectedTotalCount: 0, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 0) + s.Equal(0, result.TotalCount) + }, }, { - name: "kv error", - expectedErr: "error fetching jobs", + name: "kv error", setupMocks: func() { s.mockKV.EXPECT().Keys(gomock.Any()).Return(nil, errors.New("connection failed")) }, + validateFunc: func(_ *client.ListJobsResult, err error) { + s.Error(err) + s.Contains(err.Error(), "error fetching jobs") + }, }, { name: "returns all jobs default limit", @@ -1012,8 +1020,12 @@ func (s *JobsPublicTestSuite) TestListJobs() { )) s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-2").Return(mockEntry2, nil) }, - expectedJobs: 2, - expectedTotalCount: 2, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 2) + s.Equal(2, result.TotalCount) + }, }, { name: "filters out non matching status", @@ -1023,16 +1035,24 @@ func (s *JobsPublicTestSuite) TestListJobs() { // Two-pass: no kv.Get needed for filtering s.mockKV.EXPECT().Keys(gomock.Any()).Return([]string{"jobs.job-1"}, nil) }, - expectedJobs: 0, - expectedTotalCount: 0, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 0) + s.Equal(0, result.TotalCount) + }, }, { name: "empty job ID after trim skipped", setupMocks: func() { s.mockKV.EXPECT().Keys(gomock.Any()).Return([]string{"jobs."}, nil) }, - expectedJobs: 0, - expectedTotalCount: 0, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 0) + s.Equal(0, result.TotalCount) + }, }, { name: "getJobStatusFromKeys error skipped", @@ -1045,8 +1065,12 @@ func (s *JobsPublicTestSuite) TestListJobs() { Get(gomock.Any(), "jobs.job-bad"). Return(nil, errors.New("kv error")) }, - expectedJobs: 0, - expectedTotalCount: 1, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 0) + s.Equal(1, result.TotalCount) + }, }, { name: "only processes jobs prefix keys", @@ -1082,8 +1106,12 @@ func (s *JobsPublicTestSuite) TestListJobs() { Get(gomock.Any(), "responses.job-1.host.123"). Return(mockRespEntry, nil) }, - expectedJobs: 1, - expectedTotalCount: 1, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 1) + s.Equal(1, result.TotalCount) + }, }, { name: "limit restricts returned jobs", @@ -1100,8 +1128,12 @@ func (s *JobsPublicTestSuite) TestListJobs() { )) s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-2").Return(mockEntry, nil) }, - expectedJobs: 1, - expectedTotalCount: 2, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 1) + s.Equal(2, result.TotalCount) + }, }, { name: "offset skips jobs", @@ -1118,8 +1150,12 @@ func (s *JobsPublicTestSuite) TestListJobs() { )) s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-1").Return(mockEntry, nil) }, - expectedJobs: 1, - expectedTotalCount: 2, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 1) + s.Equal(2, result.TotalCount) + }, }, { name: "offset beyond total returns empty", @@ -1129,8 +1165,12 @@ func (s *JobsPublicTestSuite) TestListJobs() { Keys(gomock.Any()). Return([]string{"jobs.job-1", "jobs.job-2"}, nil) }, - expectedJobs: 0, - expectedTotalCount: 2, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 0) + s.Equal(2, result.TotalCount) + }, }, { name: "filter with offset skips matching jobs", @@ -1156,8 +1196,12 @@ func (s *JobsPublicTestSuite) TestListJobs() { )) s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-1").Return(mockEntry1, nil) }, - expectedJobs: 2, - expectedTotalCount: 3, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 2) + s.Equal(3, result.TotalCount) + }, }, { name: "filter with limit restricts results", @@ -1177,8 +1221,12 @@ func (s *JobsPublicTestSuite) TestListJobs() { )) s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-2").Return(mockEntry2, nil) }, - expectedJobs: 1, - expectedTotalCount: 2, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 1) + s.Equal(2, result.TotalCount) + }, }, { name: "filter skips jobs with get error", @@ -1201,10 +1249,12 @@ func (s *JobsPublicTestSuite) TestListJobs() { )) s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-bad").Return(mockEntry, nil) }, - expectedJobs: 1, - // totalCount is 2 because key-name-based counting finds - // both jobs matching the filter before Pass 2 Get errors - expectedTotalCount: 2, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 1) + s.Equal(2, result.TotalCount) + }, }, { name: "getJobStatusFromKeys with invalid JSON", @@ -1217,8 +1267,12 @@ func (s *JobsPublicTestSuite) TestListJobs() { mockEntry.EXPECT().Value().Return([]byte(`not valid json`)) s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-1").Return(mockEntry, nil) }, - expectedJobs: 0, - expectedTotalCount: 1, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 0) + s.Equal(1, result.TotalCount) + }, }, { name: "limit exceeding max capped to default", @@ -1242,8 +1296,12 @@ func (s *JobsPublicTestSuite) TestListJobs() { )) s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-1").Return(mockEntry1, nil) }, - expectedJobs: 2, - expectedTotalCount: 2, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 2) + s.Equal(2, result.TotalCount) + }, }, { name: "newest first ordering", @@ -1271,8 +1329,12 @@ func (s *JobsPublicTestSuite) TestListJobs() { )) s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-1").Return(mockEntry1, nil) }, - expectedJobs: 3, - expectedTotalCount: 3, + validateFunc: func(result *client.ListJobsResult, err error) { + s.NoError(err) + s.NotNil(result) + s.Len(result.Jobs, 3) + s.Equal(3, result.TotalCount) + }, }, } @@ -1280,32 +1342,22 @@ func (s *JobsPublicTestSuite) TestListJobs() { s.Run(tt.name, func() { tt.setupMocks() - result, err := s.jobsClient.ListJobs( + tt.validateFunc(s.jobsClient.ListJobs( s.ctx, tt.statusFilter, tt.limit, tt.offset, - ) - - if tt.expectedErr != "" { - s.Error(err) - s.Contains(err.Error(), tt.expectedErr) - } else { - s.NoError(err) - s.NotNil(result) - s.Len(result.Jobs, tt.expectedJobs) - s.Equal(tt.expectedTotalCount, result.TotalCount) - } + )) }) } } func (s *JobsPublicTestSuite) TestDeleteJob() { tests := []struct { - name string - jobID string - expectedErr string - setupMocks func() + name string + jobID string + setupMocks func() + validateFunc func(error) }{ { name: "successful deletion", @@ -1316,21 +1368,26 @@ func (s *JobsPublicTestSuite) TestDeleteJob() { s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-123").Return(mockEntry, nil) s.mockKV.EXPECT().Delete(gomock.Any(), "jobs.job-123").Return(nil) }, + validateFunc: func(err error) { + s.NoError(err) + }, }, { - name: "job not found", - jobID: "nonexistent", - expectedErr: "job not found: nonexistent", + name: "job not found", + jobID: "nonexistent", setupMocks: func() { s.mockKV.EXPECT(). Get(gomock.Any(), "jobs.nonexistent"). Return(nil, errors.New("key not found")) }, + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "job not found: nonexistent") + }, }, { - name: "delete error", - jobID: "job-456", - expectedErr: "failed to delete job", + name: "delete error", + jobID: "job-456", setupMocks: func() { mockEntry := jobmocks.NewMockKeyValueEntry(s.mockCtrl) mockEntry.EXPECT().Value().Return([]byte(`{"id":"job-456"}`)).AnyTimes() @@ -1339,6 +1396,10 @@ func (s *JobsPublicTestSuite) TestDeleteJob() { Delete(gomock.Any(), "jobs.job-456"). Return(errors.New("storage failure")) }, + validateFunc: func(err error) { + s.Error(err) + s.Contains(err.Error(), "failed to delete job") + }, }, } @@ -1346,14 +1407,7 @@ func (s *JobsPublicTestSuite) TestDeleteJob() { s.Run(tt.name, func() { tt.setupMocks() - err := s.jobsClient.DeleteJob(s.ctx, tt.jobID) - - if tt.expectedErr != "" { - s.Error(err) - s.Contains(err.Error(), tt.expectedErr) - } else { - s.NoError(err) - } + tt.validateFunc(s.jobsClient.DeleteJob(s.ctx, tt.jobID)) }) } } @@ -1480,20 +1534,23 @@ func (s *JobsPublicTestSuite) TestRetriedEventInTimeline() { func (s *JobsPublicTestSuite) TestCreateJob() { tests := []struct { - name string - opData map[string]interface{} - target string - expectedErr string - setupMocks func() + name string + opData map[string]interface{} + target string + setupMocks func() + validateFunc func(*client.CreateJobResult, error) }{ { name: "missing type field returns error", opData: map[string]interface{}{ "data": "no-type", }, - target: "_any", - expectedErr: "invalid operation format: missing type field", - setupMocks: func() {}, + target: "_any", + setupMocks: func() {}, + validateFunc: func(_ *client.CreateJobResult, err error) { + s.Error(err) + s.Contains(err.Error(), "invalid operation format: missing type field") + }, }, { name: "marshal failure returns error", @@ -1501,11 +1558,14 @@ func (s *JobsPublicTestSuite) TestCreateJob() { "type": "node.hostname.get", "unmarshalable": make(chan int), }, - target: "_any", - expectedErr: "failed to marshal job with status", + target: "_any", setupMocks: func() { s.mockKV.EXPECT().Bucket().Return("test-bucket").AnyTimes() }, + validateFunc: func(_ *client.CreateJobResult, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to marshal job with status") + }, }, { name: "modify operation uses modify prefix", @@ -1524,6 +1584,11 @@ func (s *JobsPublicTestSuite) TestCreateJob() { Publish(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil) }, + validateFunc: func(result *client.CreateJobResult, err error) { + s.NoError(err) + s.NotEmpty(result.JobID) + s.Equal("created", result.Status) + }, }, { name: "status event put failure is logged not returned", @@ -1546,6 +1611,11 @@ func (s *JobsPublicTestSuite) TestCreateJob() { Publish(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil) }, + validateFunc: func(result *client.CreateJobResult, err error) { + s.NoError(err) + s.NotEmpty(result.JobID) + s.Equal("created", result.Status) + }, }, { name: "publish failure returns error", @@ -1564,7 +1634,10 @@ func (s *JobsPublicTestSuite) TestCreateJob() { Publish(gomock.Any(), gomock.Any(), gomock.Any()). Return(errors.New("publish failed")) }, - expectedErr: "failed to send notification", + validateFunc: func(_ *client.CreateJobResult, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to send notification") + }, }, } @@ -1572,27 +1645,18 @@ func (s *JobsPublicTestSuite) TestCreateJob() { s.Run(tt.name, func() { tt.setupMocks() - result, err := s.jobsClient.CreateJob(s.ctx, tt.opData, tt.target) - - if tt.expectedErr != "" { - s.Error(err) - s.Contains(err.Error(), tt.expectedErr) - } else { - s.NoError(err) - s.NotEmpty(result.JobID) - s.Equal("created", result.Status) - } + tt.validateFunc(s.jobsClient.CreateJob(s.ctx, tt.opData, tt.target)) }) } } func (s *JobsPublicTestSuite) TestRetryJob() { tests := []struct { - name string - jobID string - target string - expectedErr string - setupMocks func() + name string + jobID string + target string + setupMocks func() + validateFunc func(*client.CreateJobResult, error) }{ { name: "successful retry", @@ -1621,34 +1685,44 @@ func (s *JobsPublicTestSuite) TestRetryJob() { Put(gomock.Any(), gomock.Any(), gomock.Any()). Return(uint64(2), nil) }, + validateFunc: func(result *client.CreateJobResult, err error) { + s.NoError(err) + s.NotEmpty(result.JobID) + s.Equal("created", result.Status) + }, }, { - name: "job not found", - jobID: "nonexistent", - target: "_any", - expectedErr: "job not found: nonexistent", + name: "job not found", + jobID: "nonexistent", + target: "_any", setupMocks: func() { s.mockKV.EXPECT(). Get(gomock.Any(), "jobs.nonexistent"). Return(nil, errors.New("key not found")) }, + validateFunc: func(_ *client.CreateJobResult, err error) { + s.Error(err) + s.Contains(err.Error(), "job not found: nonexistent") + }, }, { - name: "invalid job JSON", - jobID: "job-bad", - target: "_any", - expectedErr: "failed to parse job data", + name: "invalid job JSON", + jobID: "job-bad", + target: "_any", setupMocks: func() { mockEntry := jobmocks.NewMockKeyValueEntry(s.mockCtrl) mockEntry.EXPECT().Value().Return([]byte(`not json`)) s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-bad").Return(mockEntry, nil) }, + validateFunc: func(_ *client.CreateJobResult, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to parse job data") + }, }, { - name: "missing operation field", - jobID: "job-no-op", - target: "_any", - expectedErr: "job has no operation data", + name: "missing operation field", + jobID: "job-no-op", + target: "_any", setupMocks: func() { mockEntry := jobmocks.NewMockKeyValueEntry(s.mockCtrl) mockEntry.EXPECT().Value().Return([]byte( @@ -1656,12 +1730,15 @@ func (s *JobsPublicTestSuite) TestRetryJob() { )) s.mockKV.EXPECT().Get(gomock.Any(), "jobs.job-no-op").Return(mockEntry, nil) }, + validateFunc: func(_ *client.CreateJobResult, err error) { + s.Error(err) + s.Contains(err.Error(), "job has no operation data") + }, }, { - name: "create job fails", - jobID: "job-456", - target: "_any", - expectedErr: "failed to create retry job", + name: "create job fails", + jobID: "job-456", + target: "_any", setupMocks: func() { mockEntry := jobmocks.NewMockKeyValueEntry(s.mockCtrl) mockEntry.EXPECT().Value().Return([]byte( @@ -1675,6 +1752,10 @@ func (s *JobsPublicTestSuite) TestRetryJob() { Return(uint64(0), errors.New("kv error")) s.mockKV.EXPECT().Bucket().Return("test-bucket").AnyTimes() }, + validateFunc: func(_ *client.CreateJobResult, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to create retry job") + }, }, { name: "retried event put error is logged not returned", @@ -1702,6 +1783,11 @@ func (s *JobsPublicTestSuite) TestRetryJob() { Put(gomock.Any(), gomock.Any(), gomock.Any()). Return(uint64(0), errors.New("event put failed")) }, + validateFunc: func(result *client.CreateJobResult, err error) { + s.NoError(err) + s.NotEmpty(result.JobID) + s.Equal("created", result.Status) + }, }, { name: "empty target defaults to any", @@ -1728,6 +1814,11 @@ func (s *JobsPublicTestSuite) TestRetryJob() { Put(gomock.Any(), gomock.Any(), gomock.Any()). Return(uint64(2), nil) }, + validateFunc: func(result *client.CreateJobResult, err error) { + s.NoError(err) + s.NotEmpty(result.JobID) + s.Equal("created", result.Status) + }, }, } @@ -1735,31 +1826,16 @@ func (s *JobsPublicTestSuite) TestRetryJob() { s.Run(tt.name, func() { tt.setupMocks() - result, err := s.jobsClient.RetryJob(s.ctx, tt.jobID, tt.target) - - if tt.expectedErr != "" { - s.Error(err) - s.Contains(err.Error(), tt.expectedErr) - } else { - s.NoError(err) - s.NotEmpty(result.JobID) - s.Equal("created", result.Status) - } + tt.validateFunc(s.jobsClient.RetryJob(s.ctx, tt.jobID, tt.target)) }) } } func (s *JobsPublicTestSuite) TestGetQueueSummary() { tests := []struct { - name string - expectedErr string - setupMocks func() - expectedTotalJobs int - expectedSubmitted int - expectedProcessing int - expectedCompleted int - expectedFailed int - expectedDLQ int + name string + setupMocks func() + validateFunc func(*job.QueueStats, error) }{ { name: "when no keys found returns empty stats", @@ -1768,21 +1844,28 @@ func (s *JobsPublicTestSuite) TestGetQueueSummary() { Keys(gomock.Any()). Return(nil, jetstream.ErrNoKeysFound) }, - expectedTotalJobs: 0, - expectedSubmitted: 0, - expectedProcessing: 0, - expectedCompleted: 0, - expectedFailed: 0, - expectedDLQ: 0, + validateFunc: func(stats *job.QueueStats, err error) { + s.NoError(err) + s.NotNil(stats) + s.Equal(0, stats.TotalJobs) + s.Equal(0, stats.StatusCounts["submitted"]) + s.Equal(0, stats.StatusCounts["processing"]) + s.Equal(0, stats.StatusCounts["completed"]) + s.Equal(0, stats.StatusCounts["failed"]) + s.Equal(0, stats.DLQCount) + }, }, { - name: "when keys error returns error", - expectedErr: "error fetching keys", + name: "when keys error returns error", setupMocks: func() { s.mockKV.EXPECT(). Keys(gomock.Any()). Return(nil, errors.New("connection failed")) }, + validateFunc: func(_ *job.QueueStats, err error) { + s.Error(err) + s.Contains(err.Error(), "error fetching keys") + }, }, { name: "when jobs exist returns correct status counts", @@ -1816,12 +1899,16 @@ func (s *JobsPublicTestSuite) TestGetQueueSummary() { GetStreamInfo(gomock.Any(), "JOBS-DLQ"). Return(nil, errors.New("no stream")) }, - expectedTotalJobs: 5, - expectedSubmitted: 1, - expectedProcessing: 1, - expectedCompleted: 2, - expectedFailed: 1, - expectedDLQ: 0, + validateFunc: func(stats *job.QueueStats, err error) { + s.NoError(err) + s.NotNil(stats) + s.Equal(5, stats.TotalJobs) + s.Equal(1, stats.StatusCounts["submitted"]) + s.Equal(1, stats.StatusCounts["processing"]) + s.Equal(2, stats.StatusCounts["completed"]) + s.Equal(1, stats.StatusCounts["failed"]) + s.Equal(0, stats.DLQCount) + }, }, { name: "when DLQ has messages includes DLQ count", @@ -1838,12 +1925,16 @@ func (s *JobsPublicTestSuite) TestGetQueueSummary() { State: jetstream.StreamState{Msgs: 3}, }, nil) }, - expectedTotalJobs: 1, - expectedSubmitted: 1, - expectedProcessing: 0, - expectedCompleted: 0, - expectedFailed: 0, - expectedDLQ: 3, + validateFunc: func(stats *job.QueueStats, err error) { + s.NoError(err) + s.NotNil(stats) + s.Equal(1, stats.TotalJobs) + s.Equal(1, stats.StatusCounts["submitted"]) + s.Equal(0, stats.StatusCounts["processing"]) + s.Equal(0, stats.StatusCounts["completed"]) + s.Equal(0, stats.StatusCounts["failed"]) + s.Equal(3, stats.DLQCount) + }, }, { name: "when malformed status key is skipped", @@ -1860,12 +1951,16 @@ func (s *JobsPublicTestSuite) TestGetQueueSummary() { GetStreamInfo(gomock.Any(), "JOBS-DLQ"). Return(nil, errors.New("no stream")) }, - expectedTotalJobs: 1, - expectedSubmitted: 0, - expectedProcessing: 0, - expectedCompleted: 1, - expectedFailed: 0, - expectedDLQ: 0, + validateFunc: func(stats *job.QueueStats, err error) { + s.NoError(err) + s.NotNil(stats) + s.Equal(1, stats.TotalJobs) + s.Equal(0, stats.StatusCounts["submitted"]) + s.Equal(0, stats.StatusCounts["processing"]) + s.Equal(1, stats.StatusCounts["completed"]) + s.Equal(0, stats.StatusCounts["failed"]) + s.Equal(0, stats.DLQCount) + }, }, { name: "when DLQ error returns zero DLQ count", @@ -1881,12 +1976,16 @@ func (s *JobsPublicTestSuite) TestGetQueueSummary() { GetStreamInfo(gomock.Any(), "JOBS-DLQ"). Return(nil, errors.New("stream not found")) }, - expectedTotalJobs: 1, - expectedSubmitted: 0, - expectedProcessing: 0, - expectedCompleted: 1, - expectedFailed: 0, - expectedDLQ: 0, + validateFunc: func(stats *job.QueueStats, err error) { + s.NoError(err) + s.NotNil(stats) + s.Equal(1, stats.TotalJobs) + s.Equal(0, stats.StatusCounts["submitted"]) + s.Equal(0, stats.StatusCounts["processing"]) + s.Equal(1, stats.StatusCounts["completed"]) + s.Equal(0, stats.StatusCounts["failed"]) + s.Equal(0, stats.DLQCount) + }, }, } @@ -1894,21 +1993,7 @@ func (s *JobsPublicTestSuite) TestGetQueueSummary() { s.Run(tt.name, func() { tt.setupMocks() - stats, err := s.jobsClient.GetQueueSummary(s.ctx) - - if tt.expectedErr != "" { - s.Error(err) - s.Contains(err.Error(), tt.expectedErr) - } else { - s.NoError(err) - s.NotNil(stats) - s.Equal(tt.expectedTotalJobs, stats.TotalJobs) - s.Equal(tt.expectedSubmitted, stats.StatusCounts["submitted"]) - s.Equal(tt.expectedProcessing, stats.StatusCounts["processing"]) - s.Equal(tt.expectedCompleted, stats.StatusCounts["completed"]) - s.Equal(tt.expectedFailed, stats.StatusCounts["failed"]) - s.Equal(tt.expectedDLQ, stats.DLQCount) - } + tt.validateFunc(s.jobsClient.GetQueueSummary(s.ctx)) }) } } @@ -1918,19 +2003,23 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { name string keys []string expectedOrderIDs []string - expectedStatuses map[string]string + validateFunc func(map[string]string) }{ { name: "empty keys", keys: []string{}, expectedOrderIDs: nil, - expectedStatuses: map[string]string{}, + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{}, got) + }, }, { name: "only jobs keys no status events", keys: []string{"jobs.job-1", "jobs.job-2"}, expectedOrderIDs: []string{"job-2", "job-1"}, - expectedStatuses: map[string]string{}, + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{}, got) + }, }, { name: "single agent completed", @@ -1942,8 +2031,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.completed.agent1.103", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "completed", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "completed", + }, got) }, }, { @@ -1956,8 +2047,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.failed.agent1.103", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "failed", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "failed", + }, got) }, }, { @@ -1969,8 +2062,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.started.agent1.102", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "processing", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "processing", + }, got) }, }, { @@ -1980,8 +2075,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.submitted._api.100", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "submitted", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "submitted", + }, got) }, }, { @@ -1992,8 +2089,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.acknowledged.agent1.101", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "processing", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "processing", + }, got) }, }, { @@ -2005,8 +2104,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.failed.agent2.102", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "partial_failure", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "partial_failure", + }, got) }, }, { @@ -2017,8 +2118,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.completed.agent2.102", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "completed", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "completed", + }, got) }, }, { @@ -2029,8 +2132,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.started.agent2.102", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "processing", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "processing", + }, got) }, }, { @@ -2041,8 +2146,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.retried.agent1.101", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "completed", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "completed", + }, got) }, }, { @@ -2056,10 +2163,12 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-3.failed.agent1.301", }, expectedOrderIDs: []string{"job-3", "job-2", "job-1"}, - expectedStatuses: map[string]string{ - "job-1": "completed", - "job-2": "processing", - "job-3": "failed", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "completed", + "job-2": "processing", + "job-3": "failed", + }, got) }, }, { @@ -2070,8 +2179,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.completed.agent1.101", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "completed", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "completed", + }, got) }, }, { @@ -2082,15 +2193,19 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.completed.agent1.101", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "completed", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "completed", + }, got) }, }, { name: "empty job ID after trim skipped", keys: []string{"jobs."}, expectedOrderIDs: nil, - expectedStatuses: map[string]string{}, + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{}, got) + }, }, { name: "single agent skipped", @@ -2102,8 +2217,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.skipped.agent1.103", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "skipped", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "skipped", + }, got) }, }, { @@ -2114,8 +2231,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.skipped.agent2.102", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "skipped", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "skipped", + }, got) }, }, { @@ -2126,8 +2245,10 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { "status.job-1.completed.agent2.102", }, expectedOrderIDs: []string{"job-1"}, - expectedStatuses: map[string]string{ - "job-1": "completed", + validateFunc: func(got map[string]string) { + s.Equal(map[string]string{ + "job-1": "completed", + }, got) }, }, } @@ -2137,7 +2258,7 @@ func (s *JobsPublicTestSuite) TestComputeStatusFromKeyNames() { orderedIDs, statuses := client.ExportComputeStatusFromKeyNames(tt.keys) s.Equal(tt.expectedOrderIDs, orderedIDs) - s.Equal(tt.expectedStatuses, statuses) + tt.validateFunc(statuses) }) } } @@ -2146,12 +2267,12 @@ func (s *JobsPublicTestSuite) TestCreateJobWithPKISigner() { signer, _ := newSigner(gomock.NewController(s.T())) tests := []struct { - name string - opData map[string]interface{} - target string - setupFn func() - setupMocks func() - expectedErr string + name string + opData map[string]interface{} + target string + setupFn func() + setupMocks func() + validateFunc func(*client.CreateJobResult, error) }{ { name: "when PKI signs job data successfully", @@ -2171,6 +2292,11 @@ func (s *JobsPublicTestSuite) TestCreateJobWithPKISigner() { Publish(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil) }, + validateFunc: func(result *client.CreateJobResult, err error) { + s.NoError(err) + s.NotEmpty(result.JobID) + s.Equal("created", result.Status) + }, }, { name: "when PKI signing marshal fails returns error", @@ -2187,7 +2313,10 @@ func (s *JobsPublicTestSuite) TestCreateJobWithPKISigner() { setupMocks: func() { s.mockKV.EXPECT().Bucket().Return("test-bucket").AnyTimes() }, - expectedErr: "failed to sign job data", + validateFunc: func(_ *client.CreateJobResult, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to sign job data") + }, }, } @@ -2205,16 +2334,7 @@ func (s *JobsPublicTestSuite) TestCreateJobWithPKISigner() { c, err := client.New(slog.Default(), s.mockNATSClient, opts) s.Require().NoError(err) - result, err := c.CreateJob(s.ctx, tt.opData, tt.target) - - if tt.expectedErr != "" { - s.Error(err) - s.Contains(err.Error(), tt.expectedErr) - } else { - s.NoError(err) - s.NotEmpty(result.JobID) - s.Equal("created", result.Status) - } + tt.validateFunc(c.CreateJob(s.ctx, tt.opData, tt.target)) }) } } @@ -2343,6 +2463,8 @@ func (s *JobsPublicTestSuite) TestGetJobStatusWithPKISigner() { } } -func TestJobsPublicTestSuite(t *testing.T) { +func TestJobsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(JobsPublicTestSuite)) } diff --git a/internal/job/client/meter_public_test.go b/internal/job/client/meter_public_test.go index 9a13944e2..80f20e35f 100644 --- a/internal/job/client/meter_public_test.go +++ b/internal/job/client/meter_public_test.go @@ -74,10 +74,18 @@ func (s *MeterPublicTestSuite) TearDownTest() { func (s *MeterPublicTestSuite) TestSetMeterProvider() { tests := []struct { - name string + name string + validateFunc func(*metrics.Server) }{ { name: "creates OTEL instruments without panic", + validateFunc: func(srv *metrics.Server) { + s.Require().NotNil(srv) + + s.NotPanics(func() { + s.jobsClient.SetMeterProvider(srv.MeterProvider()) + }) + }, }, } @@ -85,11 +93,7 @@ func (s *MeterPublicTestSuite) TestSetMeterProvider() { s.Run(tt.name, func() { port := s.getFreePort() srv := metrics.New("127.0.0.1", port, slog.Default()) - s.Require().NotNil(srv) - - s.NotPanics(func() { - s.jobsClient.SetMeterProvider(srv.MeterProvider()) - }) + tt.validateFunc(srv) ctx, cancel := context.WithTimeout( context.Background(), @@ -102,7 +106,9 @@ func (s *MeterPublicTestSuite) TestSetMeterProvider() { } } -func TestMeterPublicTestSuite(t *testing.T) { +func TestMeterPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(MeterPublicTestSuite)) } diff --git a/internal/job/client/mock_support_public_test.go b/internal/job/client/mock_support_public_test.go deleted file mode 100644 index 92cdec5b8..000000000 --- a/internal/job/client/mock_support_public_test.go +++ /dev/null @@ -1,269 +0,0 @@ -// Copyright (c) 2025 John Dewey - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -package client_test - -import ( - "github.com/nats-io/nats.go/jetstream" - "go.uber.org/mock/gomock" - - jobmocks "github.com/osapi-io/osapi/internal/job/mocks" -) - -// publishAndWaitErrorMode controls which step of the publishAndWait flow fails. -type publishAndWaitErrorMode int - -const ( - // errorOnKVPut makes kv.Put return the error. - errorOnKVPut publishAndWaitErrorMode = iota - // errorOnPublish makes natsClient.Publish return the error. - errorOnPublish - // errorOnWatch makes kv.Watch return the error. - errorOnWatch - // errorOnTimeout simulates a timeout by providing a channel that never sends. - errorOnTimeout - // errorOnTimeoutWithPartialResponse sends one valid response then blocks, - // simulating a timeout after partial collection. Only valid for - // publishAndCollect (broadcast) flows. - errorOnTimeoutWithPartialResponse -) - -// publishAndWaitMockOpts configures the mock behavior for publishAndWait tests. -type publishAndWaitMockOpts struct { - // responseData is the JSON response to return from the watcher entry. - responseData string - // mockError is the error to inject (used with errorMode). - mockError error - // errorMode controls which step fails when mockError is set. - errorMode publishAndWaitErrorMode - // sendNilFirst sends a nil entry before the real entry on the watcher channel. - sendNilFirst bool -} - -// setupPublishAndWaitMocks configures mocks for the publishAndWait flow. -func setupPublishAndWaitMocks( - ctrl *gomock.Controller, - mockKV *jobmocks.MockKeyValue, - mockNATSClient *jobmocks.MockNATSClient, - subject string, - responseData string, - mockError error, -) { - setupPublishAndWaitMocksWithOpts(ctrl, mockKV, mockNATSClient, subject, &publishAndWaitMockOpts{ - responseData: responseData, - mockError: mockError, - errorMode: errorOnKVPut, - }) -} - -// publishAndCollectMockOpts configures mock behavior for publishAndCollect tests. -type publishAndCollectMockOpts struct { - // responseEntries is a list of JSON response strings to send on the watcher. - responseEntries []string - // mockError is the error to inject (used with errorMode). - mockError error - // errorMode controls which step fails when mockError is set. - errorMode publishAndWaitErrorMode - // sendNilFirst sends a nil entry before the response entries on the watcher channel. - sendNilFirst bool -} - -// setupPublishAndCollectMocks configures mocks for the publishAndCollect flow. -func setupPublishAndCollectMocks( - ctrl *gomock.Controller, - mockKV *jobmocks.MockKeyValue, - mockNATSClient *jobmocks.MockNATSClient, - subject string, - opts *publishAndCollectMockOpts, -) { - if opts.mockError != nil && opts.errorMode == errorOnKVPut { - mockKV.EXPECT(). - Put(gomock.Any(), gomock.Any(), gomock.Any()). - Return(uint64(0), opts.mockError) - return - } - - // kv.Put succeeds - mockKV.EXPECT(). - Put(gomock.Any(), gomock.Any(), gomock.Any()). - Return(uint64(1), nil) - - if opts.mockError != nil && opts.errorMode == errorOnPublish { - mockNATSClient.EXPECT(). - Publish(gomock.Any(), subject, gomock.Any()). - Return(opts.mockError) - return - } - - // natsClient.Publish succeeds - mockNATSClient.EXPECT(). - Publish(gomock.Any(), subject, gomock.Any()). - Return(nil) - - if opts.mockError != nil && opts.errorMode == errorOnWatch { - mockKV.EXPECT(). - Watch(gomock.Any(), gomock.Any()). - Return(nil, opts.mockError) - return - } - - if opts.mockError != nil && opts.errorMode == errorOnTimeout { - // Return a channel that never sends anything, causing timeout with 0 responses - ch := make(chan jetstream.KeyValueEntry) - - mockWatcher := jobmocks.NewMockKeyWatcher(ctrl) - mockWatcher.EXPECT().Updates().Return(ch).AnyTimes() - mockWatcher.EXPECT().Stop().Return(nil) - - mockKV.EXPECT(). - Watch(gomock.Any(), gomock.Any()). - Return(mockWatcher, nil) - return - } - - if opts.mockError != nil && opts.errorMode == errorOnTimeoutWithPartialResponse { - // Send one valid response then block so the timeout fires with partial results. - // The first responseEntry provides the partial response data. - ch := make(chan jetstream.KeyValueEntry, 1) - mockEntry := jobmocks.NewMockKeyValueEntry(ctrl) - responseData := "" - if len(opts.responseEntries) > 0 { - responseData = opts.responseEntries[0] - } - mockEntry.EXPECT().Value().Return([]byte(responseData)) - ch <- mockEntry - - mockWatcher := jobmocks.NewMockKeyWatcher(ctrl) - mockWatcher.EXPECT().Updates().Return(ch).AnyTimes() - mockWatcher.EXPECT().Stop().Return(nil) - - mockKV.EXPECT(). - Watch(gomock.Any(), gomock.Any()). - Return(mockWatcher, nil) - return - } - - // Create buffered channel with all response entries - bufSize := len(opts.responseEntries) - if opts.sendNilFirst { - bufSize++ - } - ch := make(chan jetstream.KeyValueEntry, bufSize) - if opts.sendNilFirst { - ch <- nil - } - for _, data := range opts.responseEntries { - if data == "" { - continue - } - mockEntry := jobmocks.NewMockKeyValueEntry(ctrl) - mockEntry.EXPECT().Value().Return([]byte(data)) - ch <- mockEntry - } - - // Create mock watcher - mockWatcher := jobmocks.NewMockKeyWatcher(ctrl) - mockWatcher.EXPECT().Updates().Return(ch).AnyTimes() - mockWatcher.EXPECT().Stop().Return(nil) - - // kv.Watch returns the mock watcher - mockKV.EXPECT(). - Watch(gomock.Any(), gomock.Any()). - Return(mockWatcher, nil) -} - -// setupPublishAndWaitMocksWithOpts configures mocks with fine-grained control. -func setupPublishAndWaitMocksWithOpts( - ctrl *gomock.Controller, - mockKV *jobmocks.MockKeyValue, - mockNATSClient *jobmocks.MockNATSClient, - subject string, - opts *publishAndWaitMockOpts, -) { - if opts.mockError != nil && opts.errorMode == errorOnKVPut { - mockKV.EXPECT(). - Put(gomock.Any(), gomock.Any(), gomock.Any()). - Return(uint64(0), opts.mockError) - return - } - - // kv.Put succeeds - mockKV.EXPECT(). - Put(gomock.Any(), gomock.Any(), gomock.Any()). - Return(uint64(1), nil) - - if opts.mockError != nil && opts.errorMode == errorOnPublish { - mockNATSClient.EXPECT(). - Publish(gomock.Any(), subject, gomock.Any()). - Return(opts.mockError) - return - } - - // natsClient.Publish succeeds - mockNATSClient.EXPECT(). - Publish(gomock.Any(), subject, gomock.Any()). - Return(nil) - - if opts.mockError != nil && opts.errorMode == errorOnWatch { - mockKV.EXPECT(). - Watch(gomock.Any(), gomock.Any()). - Return(nil, opts.mockError) - return - } - - if opts.mockError != nil && opts.errorMode == errorOnTimeout { - // Return a channel that never sends anything, causing timeout - ch := make(chan jetstream.KeyValueEntry) - - mockWatcher := jobmocks.NewMockKeyWatcher(ctrl) - mockWatcher.EXPECT().Updates().Return(ch).AnyTimes() - mockWatcher.EXPECT().Stop().Return(nil) - - mockKV.EXPECT(). - Watch(gomock.Any(), gomock.Any()). - Return(mockWatcher, nil) - return - } - - // Create mock entry with response data - mockEntry := jobmocks.NewMockKeyValueEntry(ctrl) - mockEntry.EXPECT().Value().Return([]byte(opts.responseData)) - - // Create buffered channel and optionally send nil first - bufSize := 1 - if opts.sendNilFirst { - bufSize = 2 - } - ch := make(chan jetstream.KeyValueEntry, bufSize) - if opts.sendNilFirst { - ch <- nil - } - ch <- mockEntry - - // Create mock watcher - mockWatcher := jobmocks.NewMockKeyWatcher(ctrl) - mockWatcher.EXPECT().Updates().Return(ch).AnyTimes() - mockWatcher.EXPECT().Stop().Return(nil) - - // kv.Watch returns the mock watcher - mockKV.EXPECT(). - Watch(gomock.Any(), gomock.Any()). - Return(mockWatcher, nil) -} diff --git a/internal/job/client/signing_public_test.go b/internal/job/client/signing_public_test.go index 75206ab66..abfbd00e4 100644 --- a/internal/job/client/signing_public_test.go +++ b/internal/job/client/signing_public_test.go @@ -90,18 +90,41 @@ func (s *SigningPublicTestSuite) TestWrapInSignedEnvelope() { name string payload []byte setupFn func() - expectError bool - wantContains string + validateFunc func([]byte, error, ed25519.PublicKey) }{ { - name: "when wrapping valid payload", - payload: []byte(`{"id":"test-job","operation":{"type":"node.hostname.get"}}`), - expectError: false, + name: "when wrapping valid payload", + payload: []byte(`{"id":"test-job","operation":{"type":"node.hostname.get"}}`), + validateFunc: func(result []byte, err error, pubKey ed25519.PublicKey) { + s.NoError(err) + + payload := []byte(`{"id":"test-job","operation":{"type":"node.hostname.get"}}`) + + var envelope job.SignedEnvelope + s.NoError(json.Unmarshal(result, &envelope)) + s.Equal(payload, envelope.Payload) + s.NotEmpty(envelope.Signature) + s.Equal("SHA256:test-fingerprint", envelope.Fingerprint) + + s.True(ed25519.Verify(pubKey, payload, envelope.Signature)) + }, }, { - name: "when wrapping empty payload", - payload: []byte{}, - expectError: false, + name: "when wrapping empty payload", + payload: []byte{}, + validateFunc: func(result []byte, err error, pubKey ed25519.PublicKey) { + s.NoError(err) + + payload := []byte{} + + var envelope job.SignedEnvelope + s.NoError(json.Unmarshal(result, &envelope)) + s.Equal(payload, envelope.Payload) + s.NotEmpty(envelope.Signature) + s.Equal("SHA256:test-fingerprint", envelope.Fingerprint) + + s.True(ed25519.Verify(pubKey, payload, envelope.Signature)) + }, }, { name: "when marshal fails returns error", @@ -111,8 +134,10 @@ func (s *SigningPublicTestSuite) TestWrapInSignedEnvelope() { return nil, errors.New("marshal error") }) }, - expectError: true, - wantContains: "marshal signed envelope", + validateFunc: func(_ []byte, err error, _ ed25519.PublicKey) { + s.Error(err) + s.Contains(err.Error(), "marshal signed envelope") + }, }, } @@ -126,25 +151,7 @@ func (s *SigningPublicTestSuite) TestWrapInSignedEnvelope() { result, err := client.ExportWrapInSignedEnvelope(signer, tt.payload) - if tt.expectError { - s.Error(err) - if tt.wantContains != "" { - s.Contains(err.Error(), tt.wantContains) - } - return - } - - s.NoError(err) - - // Verify the result is a valid SignedEnvelope. - var envelope job.SignedEnvelope - s.NoError(json.Unmarshal(result, &envelope)) - s.Equal(tt.payload, envelope.Payload) - s.NotEmpty(envelope.Signature) - s.Equal("SHA256:test-fingerprint", envelope.Fingerprint) - - // Verify signature is valid. - s.True(ed25519.Verify(pubKey, tt.payload, envelope.Signature)) + tt.validateFunc(result, err, pubKey) }) } } @@ -153,13 +160,13 @@ func (s *SigningPublicTestSuite) TestUnwrapSignedEnvelope() { signer, pubKey := newSigner(gomock.NewController(s.T())) tests := []struct { - name string - setupData func() []byte - pubKey ed25519.PublicKey - wantPayload []byte - wantEnv bool - expectError bool - errorMsg string + name string + setupData func() []byte + pubKey ed25519.PublicKey + wantEnv bool + expectError bool + errorMsg string + validateFunc func([]byte) }{ { name: "when valid signed envelope with correct key", @@ -169,9 +176,11 @@ func (s *SigningPublicTestSuite) TestUnwrapSignedEnvelope() { return wrapped }, pubKey: pubKey, - wantPayload: []byte(`{"id":"test"}`), wantEnv: true, expectError: false, + validateFunc: func(got []byte) { + s.Equal([]byte(`{"id":"test"}`), got) + }, }, { name: "when valid signed envelope with nil key skips verification", @@ -181,9 +190,11 @@ func (s *SigningPublicTestSuite) TestUnwrapSignedEnvelope() { return wrapped }, pubKey: nil, - wantPayload: []byte(`{"id":"test"}`), wantEnv: true, expectError: false, + validateFunc: func(got []byte) { + s.Equal([]byte(`{"id":"test"}`), got) + }, }, { name: "when valid signed envelope with wrong key fails verification", @@ -196,10 +207,12 @@ func (s *SigningPublicTestSuite) TestUnwrapSignedEnvelope() { otherPub, _, _ := ed25519.GenerateKey(rand.Reader) return otherPub }(), - wantPayload: nil, wantEnv: true, expectError: true, errorMsg: "invalid signature", + validateFunc: func(got []byte) { + s.Equal([]byte(nil), got) + }, }, { name: "when raw JSON passes through as non-envelope", @@ -207,9 +220,11 @@ func (s *SigningPublicTestSuite) TestUnwrapSignedEnvelope() { return []byte(`{"id":"test","operation":{"type":"node.hostname.get"}}`) }, pubKey: pubKey, - wantPayload: []byte(`{"id":"test","operation":{"type":"node.hostname.get"}}`), wantEnv: false, expectError: false, + validateFunc: func(got []byte) { + s.Equal([]byte(`{"id":"test","operation":{"type":"node.hostname.get"}}`), got) + }, }, { name: "when invalid JSON passes through as non-envelope", @@ -217,9 +232,11 @@ func (s *SigningPublicTestSuite) TestUnwrapSignedEnvelope() { return []byte(`not json at all`) }, pubKey: pubKey, - wantPayload: []byte(`not json at all`), wantEnv: false, expectError: false, + validateFunc: func(got []byte) { + s.Equal([]byte(`not json at all`), got) + }, }, { name: "when envelope-like JSON with empty payload passes through", @@ -227,9 +244,11 @@ func (s *SigningPublicTestSuite) TestUnwrapSignedEnvelope() { return []byte(`{"payload":"","signature":"","fingerprint":""}`) }, pubKey: pubKey, - wantPayload: []byte(`{"payload":"","signature":"","fingerprint":""}`), wantEnv: false, expectError: false, + validateFunc: func(got []byte) { + s.Equal([]byte(`{"payload":"","signature":"","fingerprint":""}`), got) + }, }, } @@ -249,7 +268,7 @@ func (s *SigningPublicTestSuite) TestUnwrapSignedEnvelope() { s.NoError(err) s.Equal(tt.wantEnv, isEnvelope) - s.Equal(tt.wantPayload, payload) + tt.validateFunc(payload) }) } } @@ -269,6 +288,8 @@ func (s *SigningPublicTestSuite) TestRoundTrip() { s.Equal(originalPayload, unwrapped) } -func TestSigningPublicTestSuite(t *testing.T) { +func TestSigningPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SigningPublicTestSuite)) } diff --git a/internal/job/config_public_test.go b/internal/job/config_public_test.go index 578d39e01..351b11f88 100644 --- a/internal/job/config_public_test.go +++ b/internal/job/config_public_test.go @@ -45,7 +45,7 @@ func (suite *ConfigPublicTestSuite) TestGetJobsStreamConfig() { tests := []struct { name string streamConfig *config.NATSStream - wantCheck func(config *jetstream.StreamConfig) + validateFunc func(config *jetstream.StreamConfig) }{ { name: "when using file storage and old discard policy", @@ -58,7 +58,8 @@ func (suite *ConfigPublicTestSuite) TestGetJobsStreamConfig() { Replicas: 1, Discard: "old", }, - wantCheck: func(config *jetstream.StreamConfig) { + validateFunc: func(config *jetstream.StreamConfig) { + suite.NotNil(config) suite.Equal("JOBS", config.Name) suite.Equal("Stream for job request and processing", config.Description) suite.Equal([]string{"job.>"}, config.Subjects) @@ -80,7 +81,8 @@ func (suite *ConfigPublicTestSuite) TestGetJobsStreamConfig() { Replicas: 3, Discard: "new", }, - wantCheck: func(config *jetstream.StreamConfig) { + validateFunc: func(config *jetstream.StreamConfig) { + suite.NotNil(config) suite.Equal("JOBS_MEMORY", config.Name) suite.Equal("Stream for job request and processing", config.Description) suite.Equal([]string{"job.memory.>"}, config.Subjects) @@ -102,7 +104,8 @@ func (suite *ConfigPublicTestSuite) TestGetJobsStreamConfig() { Replicas: 1, Discard: "old", }, - wantCheck: func(config *jetstream.StreamConfig) { + validateFunc: func(config *jetstream.StreamConfig) { + suite.NotNil(config) suite.Equal(jetstream.FileStorage, config.Storage) }, }, @@ -117,7 +120,8 @@ func (suite *ConfigPublicTestSuite) TestGetJobsStreamConfig() { Replicas: 1, Discard: "unknown", }, - wantCheck: func(config *jetstream.StreamConfig) { + validateFunc: func(config *jetstream.StreamConfig) { + suite.NotNil(config) suite.Equal(jetstream.DiscardOld, config.Discard) }, }, @@ -125,9 +129,7 @@ func (suite *ConfigPublicTestSuite) TestGetJobsStreamConfig() { for _, tt := range tests { suite.Run(tt.name, func() { - streamConfig := job.GetJobsStreamConfig(tt.streamConfig) - suite.NotNil(streamConfig) - tt.wantCheck(streamConfig) + tt.validateFunc(job.GetJobsStreamConfig(tt.streamConfig)) }) } } @@ -137,7 +139,7 @@ func (suite *ConfigPublicTestSuite) TestGetJobsConsumerConfig() { name string consumerConfig *config.AgentConsumer streamSubjects string - wantCheck func(config jetstream.ConsumerConfig) + validateFunc func(config jetstream.ConsumerConfig) }{ { name: "when using instant replay policy", @@ -149,7 +151,7 @@ func (suite *ConfigPublicTestSuite) TestGetJobsConsumerConfig() { ReplayPolicy: "instant", }, streamSubjects: "job.>", - wantCheck: func(config jetstream.ConsumerConfig) { + validateFunc: func(config jetstream.ConsumerConfig) { suite.Equal("jobs-agent", config.Name) suite.Equal("Consumer for processing job requests", config.Description) suite.Equal("jobs-agent", config.Durable) @@ -171,7 +173,7 @@ func (suite *ConfigPublicTestSuite) TestGetJobsConsumerConfig() { ReplayPolicy: "original", }, streamSubjects: "job.test.>", - wantCheck: func(config jetstream.ConsumerConfig) { + validateFunc: func(config jetstream.ConsumerConfig) { suite.Equal("test-consumer", config.Name) suite.Equal("test-consumer", config.Durable) suite.Equal(3, config.MaxDeliver) @@ -191,7 +193,7 @@ func (suite *ConfigPublicTestSuite) TestGetJobsConsumerConfig() { ReplayPolicy: "unknown", }, streamSubjects: "job.unknown.>", - wantCheck: func(config jetstream.ConsumerConfig) { + validateFunc: func(config jetstream.ConsumerConfig) { suite.Equal(jetstream.ReplayInstantPolicy, config.ReplayPolicy) }, }, @@ -199,17 +201,18 @@ func (suite *ConfigPublicTestSuite) TestGetJobsConsumerConfig() { for _, tt := range tests { suite.Run(tt.name, func() { - consumerConfig := job.GetJobsConsumerConfig(tt.consumerConfig, tt.streamSubjects) - tt.wantCheck(consumerConfig) + tt.validateFunc( + job.GetJobsConsumerConfig(tt.consumerConfig, tt.streamSubjects), + ) }) } } func (suite *ConfigPublicTestSuite) TestGetKVBucketConfig() { tests := []struct { - name string - kvConfig *config.NATSKV - wantCheck func(config jetstream.KeyValueConfig) + name string + kvConfig *config.NATSKV + validateFunc func(config jetstream.KeyValueConfig) }{ { name: "when using file storage", @@ -220,7 +223,8 @@ func (suite *ConfigPublicTestSuite) TestGetKVBucketConfig() { Storage: "file", Replicas: 1, }, - wantCheck: func(config jetstream.KeyValueConfig) { + validateFunc: func(config jetstream.KeyValueConfig) { + suite.NotNil(config) suite.Equal("job-responses", config.Bucket) suite.Equal("Storage for job responses indexed by request ID", config.Description) suite.Equal(1*time.Hour, config.TTL) @@ -238,7 +242,8 @@ func (suite *ConfigPublicTestSuite) TestGetKVBucketConfig() { Storage: "memory", Replicas: 3, }, - wantCheck: func(config jetstream.KeyValueConfig) { + validateFunc: func(config jetstream.KeyValueConfig) { + suite.NotNil(config) suite.Equal("job-memory", config.Bucket) suite.Equal("Storage for job responses indexed by request ID", config.Description) suite.Equal(30*time.Minute, config.TTL) @@ -256,7 +261,8 @@ func (suite *ConfigPublicTestSuite) TestGetKVBucketConfig() { Storage: "unknown", Replicas: 1, }, - wantCheck: func(config jetstream.KeyValueConfig) { + validateFunc: func(config jetstream.KeyValueConfig) { + suite.NotNil(config) suite.Equal(jetstream.FileStorage, config.Storage) }, }, @@ -264,13 +270,13 @@ func (suite *ConfigPublicTestSuite) TestGetKVBucketConfig() { for _, tt := range tests { suite.Run(tt.name, func() { - kvConfig := job.GetKVBucketConfig(tt.kvConfig) - suite.NotNil(kvConfig) - tt.wantCheck(kvConfig) + tt.validateFunc(job.GetKVBucketConfig(tt.kvConfig)) }) } } -func TestConfigPublicTestSuite(t *testing.T) { +func TestConfigPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ConfigPublicTestSuite)) } diff --git a/internal/job/export_test.go b/internal/job/export_test.go index 1faf84a24..bffb5c07e 100644 --- a/internal/job/export_test.go +++ b/internal/job/export_test.go @@ -23,7 +23,9 @@ package job import "github.com/shirou/gopsutil/v4/host" // SetDefaultHostnameProvider overrides the default hostname provider for testing. -func SetDefaultHostnameProvider(p HostnameProvider) { +func SetDefaultHostnameProvider( + p HostnameProvider, +) { defaultHostnameProvider = p } @@ -39,7 +41,9 @@ func ExportNewGopsutilHostnameProvider() HostnameProvider { } // SetHostInfoFn overrides the host.Info function for testing. -func SetHostInfoFn(fn func() (*host.InfoStat, error)) { +func SetHostInfoFn( + fn func() (*host.InfoStat, error), +) { hostInfoFn = fn } diff --git a/internal/job/hostname_public_test.go b/internal/job/hostname_public_test.go index da61298b8..0efe736b8 100644 --- a/internal/job/hostname_public_test.go +++ b/internal/job/hostname_public_test.go @@ -48,10 +48,15 @@ func (s *HostnamePublicTestSuite) TearDownTest() { func (s *HostnamePublicTestSuite) TestGetAgentHostnameProviderError() { tests := []struct { - name string + name string + validateFunc func(string, error) }{ { name: "falls back to unknown when provider errors", + validateFunc: func(hostname string, err error) { + s.NoError(err) + s.Equal("unknown", hostname) + }, }, } @@ -63,10 +68,7 @@ func (s *HostnamePublicTestSuite) TestGetAgentHostnameProviderError() { job.SetDefaultHostnameProvider(mockProvider) defer job.ResetDefaultHostnameProvider() - hostname, err := job.GetAgentHostname("") - - s.NoError(err) - s.Equal("unknown", hostname) + tt.validateFunc(job.GetAgentHostname("")) }) } } @@ -158,8 +160,7 @@ func (s *HostnamePublicTestSuite) TestGetAgentHostnameWithProvider() { name string configuredHostname string setupProvider func() job.HostnameProvider - expectedHostname string - expectError bool + validateFunc func(string, error) }{ { name: "configured hostname bypasses provider", @@ -169,8 +170,10 @@ func (s *HostnamePublicTestSuite) TestGetAgentHostnameWithProvider() { // Provider is not called when hostname is pre-configured. return m }, - expectedHostname: "configured-agent", - expectError: false, + validateFunc: func(hostname string, err error) { + s.NoError(err) + s.Equal("configured-agent", hostname) + }, }, { name: "empty config uses provider successfully", @@ -180,8 +183,10 @@ func (s *HostnamePublicTestSuite) TestGetAgentHostnameWithProvider() { m.EXPECT().Hostname().Return("system-host", nil) return m }, - expectedHostname: "system-host", - expectError: false, + validateFunc: func(hostname string, err error) { + s.NoError(err) + s.Equal("system-host", hostname) + }, }, { name: "empty config with provider error returns unknown", @@ -191,8 +196,10 @@ func (s *HostnamePublicTestSuite) TestGetAgentHostnameWithProvider() { m.EXPECT().Hostname().Return("", errors.New("provider error")) return m }, - expectedHostname: "unknown", - expectError: false, + validateFunc: func(hostname string, err error) { + s.NoError(err) + s.Equal("unknown", hostname) + }, }, { name: "empty config with empty hostname returns unknown", @@ -202,34 +209,28 @@ func (s *HostnamePublicTestSuite) TestGetAgentHostnameWithProvider() { m.EXPECT().Hostname().Return("", nil) return m }, - expectedHostname: "unknown", - expectError: false, + validateFunc: func(hostname string, err error) { + s.NoError(err) + s.Equal("unknown", hostname) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - hostname, err := job.GetAgentHostnameWithProvider( + tt.validateFunc(job.GetAgentHostnameWithProvider( tt.configuredHostname, tt.setupProvider(), - ) - - if tt.expectError { - s.Error(err) - } else { - s.NoError(err) - s.Equal(tt.expectedHostname, hostname) - } + )) }) } } func (s *HostnamePublicTestSuite) TestGetLocalHostnameWithProvider() { tests := []struct { - name string - setupProvider func() job.HostnameProvider - expectedHostname string - expectError bool + name string + setupProvider func() job.HostnameProvider + validateFunc func(string, error) }{ { name: "successful hostname retrieval", @@ -238,8 +239,10 @@ func (s *HostnamePublicTestSuite) TestGetLocalHostnameWithProvider() { m.EXPECT().Hostname().Return("test-host", nil) return m }, - expectedHostname: "test-host", - expectError: false, + validateFunc: func(hostname string, err error) { + s.NoError(err) + s.Equal("test-host", hostname) + }, }, { name: "provider error", @@ -248,7 +251,9 @@ func (s *HostnamePublicTestSuite) TestGetLocalHostnameWithProvider() { m.EXPECT().Hostname().Return("", errors.New("hostname error")) return m }, - expectError: true, + validateFunc: func(_ string, err error) { + s.Error(err) + }, }, { name: "empty hostname from provider", @@ -257,21 +262,16 @@ func (s *HostnamePublicTestSuite) TestGetLocalHostnameWithProvider() { m.EXPECT().Hostname().Return("", nil) return m }, - expectedHostname: "", - expectError: false, + validateFunc: func(hostname string, err error) { + s.NoError(err) + s.Equal("", hostname) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - hostname, err := job.GetLocalHostnameWithProvider(tt.setupProvider()) - - if tt.expectError { - s.Error(err) - } else { - s.NoError(err) - s.Equal(tt.expectedHostname, hostname) - } + tt.validateFunc(job.GetLocalHostnameWithProvider(tt.setupProvider())) }) } } @@ -320,10 +320,15 @@ func (s *HostnamePublicTestSuite) TestHostnameProviderInterface() { func (s *HostnamePublicTestSuite) TestGopsutilHostnameProviderError() { tests := []struct { - name string + name string + validateFunc func(string, error) }{ { name: "returns error when host.Info fails", + validateFunc: func(hostname string, err error) { + s.Error(err) + s.Empty(hostname) + }, }, } @@ -335,14 +340,13 @@ func (s *HostnamePublicTestSuite) TestGopsutilHostnameProviderError() { defer job.ResetHostInfoFn() provider := job.ExportNewGopsutilHostnameProvider() - hostname, err := provider.Hostname() - - s.Error(err) - s.Empty(hostname) + tt.validateFunc(provider.Hostname()) }) } } -func TestHostnamePublicTestSuite(t *testing.T) { +func TestHostnamePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HostnamePublicTestSuite)) } diff --git a/internal/job/subjects_public_test.go b/internal/job/subjects_public_test.go index 78f8b3cd7..fa6905b63 100644 --- a/internal/job/subjects_public_test.go +++ b/internal/job/subjects_public_test.go @@ -43,34 +43,44 @@ func (suite *SubjectsPublicTestSuite) TearDownTest() {} func (suite *SubjectsPublicTestSuite) TestBuildQuerySubject() { tests := []struct { - name string - hostname string - want string + name string + hostname string + validateFunc func(string) }{ { name: "when building query subject for specific server", hostname: "server-01", - want: "jobs.query.server-01", + validateFunc: func(got string) { + suite.Equal("jobs.query.server-01", got) + }, }, { name: "when building query subject for web server", hostname: "web-server", - want: "jobs.query.web-server", + validateFunc: func(got string) { + suite.Equal("jobs.query.web-server", got) + }, }, { name: "when building with wildcard hostname", hostname: job.AllHosts, - want: "jobs.query.*", + validateFunc: func(got string) { + suite.Equal("jobs.query.*", got) + }, }, { name: "when building with any hostname", hostname: job.AnyHost, - want: "jobs.query._any", + validateFunc: func(got string) { + suite.Equal("jobs.query._any", got) + }, }, { name: "when building query subject for all hosts", hostname: "", - want: "jobs.query.*", + validateFunc: func(got string) { + suite.Equal("jobs.query.*", got) + }, }, } @@ -82,41 +92,51 @@ func (suite *SubjectsPublicTestSuite) TestBuildQuerySubject() { } else { got = job.BuildQuerySubject(tt.hostname) } - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } func (suite *SubjectsPublicTestSuite) TestBuildModifySubject() { tests := []struct { - name string - hostname string - want string + name string + hostname string + validateFunc func(string) }{ { name: "when building modify subject for specific server", hostname: "server-01", - want: "jobs.modify.server-01", + validateFunc: func(got string) { + suite.Equal("jobs.modify.server-01", got) + }, }, { name: "when building modify subject for db server", hostname: "db-server", - want: "jobs.modify.db-server", + validateFunc: func(got string) { + suite.Equal("jobs.modify.db-server", got) + }, }, { name: "when building with wildcard hostname", hostname: job.AllHosts, - want: "jobs.modify.*", + validateFunc: func(got string) { + suite.Equal("jobs.modify.*", got) + }, }, { name: "when building with any hostname", hostname: job.AnyHost, - want: "jobs.modify._any", + validateFunc: func(got string) { + suite.Equal("jobs.modify._any", got) + }, }, { name: "when building modify subject for all hosts", hostname: "", - want: "jobs.modify.*", + validateFunc: func(got string) { + suite.Equal("jobs.modify.*", got) + }, }, } @@ -128,7 +148,7 @@ func (suite *SubjectsPublicTestSuite) TestBuildModifySubject() { } else { got = job.BuildModifySubject(tt.hostname) } - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } @@ -137,88 +157,153 @@ func (suite *SubjectsPublicTestSuite) TestParseSubject() { tests := []struct { name string subject string - wantPrefix string - wantHostname string - wantErr bool + validateFunc func(string, string, error) }{ { - name: "when parsing valid query subject", - subject: "jobs.query.server-01", - wantPrefix: "jobs.query", - wantHostname: "server-01", - wantErr: false, + name: "when parsing valid query subject", + subject: "jobs.query.server-01", + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if false { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("jobs.query", gotPrefix) + suite.Equal("server-01", gotHostname) + }, }, { - name: "when parsing valid modify subject", - subject: "jobs.modify.web-01", - wantPrefix: "jobs.modify", - wantHostname: "web-01", - wantErr: false, + name: "when parsing valid modify subject", + subject: "jobs.modify.web-01", + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if false { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("jobs.modify", gotPrefix) + suite.Equal("web-01", gotHostname) + }, }, { - name: "when parsing subject with wildcard hostname", - subject: "jobs.query.*", - wantPrefix: "jobs.query", - wantHostname: "*", - wantErr: false, + name: "when parsing subject with wildcard hostname", + subject: "jobs.query.*", + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if false { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("jobs.query", gotPrefix) + suite.Equal("*", gotHostname) + }, }, { - name: "when parsing subject with any hostname", - subject: "jobs.modify._any", - wantPrefix: "jobs.modify", - wantHostname: "_any", - wantErr: false, + name: "when parsing subject with any hostname", + subject: "jobs.modify._any", + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if false { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("jobs.modify", gotPrefix) + suite.Equal("_any", gotHostname) + }, }, { name: "when parsing invalid subject with too few parts", subject: "jobs.query", - wantErr: true, + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if true { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("", gotPrefix) + suite.Equal("", gotHostname) + }, }, { - name: "when parsing host subject", - subject: "jobs.query.host.server-01", - wantPrefix: "jobs.query", - wantHostname: "server-01", - wantErr: false, + name: "when parsing host subject", + subject: "jobs.query.host.server-01", + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if false { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("jobs.query", gotPrefix) + suite.Equal("server-01", gotHostname) + }, }, { - name: "when parsing label subject", - subject: "jobs.query.label.group.web", - wantPrefix: "jobs.query", - wantHostname: "group:web", - wantErr: false, + name: "when parsing label subject", + subject: "jobs.query.label.group.web", + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if false { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("jobs.query", gotPrefix) + suite.Equal("group:web", gotHostname) + }, }, { - name: "when parsing hierarchical label subject", - subject: "jobs.query.label.group.web.dev.us-east", - wantPrefix: "jobs.query", - wantHostname: "group:web.dev.us-east", - wantErr: false, + name: "when parsing hierarchical label subject", + subject: "jobs.query.label.group.web.dev.us-east", + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if false { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("jobs.query", gotPrefix) + suite.Equal("group:web.dev.us-east", gotHostname) + }, }, { name: "when parsing invalid 4-part subject without host prefix", subject: "jobs.query.invalid.server1", - wantErr: true, + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if true { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("", gotPrefix) + suite.Equal("", gotHostname) + }, }, { name: "when parsing empty subject", subject: "", - wantErr: true, + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if true { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("", gotPrefix) + suite.Equal("", gotHostname) + }, }, } for _, tt := range tests { suite.Run(tt.name, func() { - gotPrefix, gotHostname, err := job.ParseSubject(tt.subject) - - if tt.wantErr { - suite.Error(err) - return - } - - suite.NoError(err) - suite.Equal(tt.wantPrefix, gotPrefix) - suite.Equal(tt.wantHostname, gotHostname) + tt.validateFunc(job.ParseSubject(tt.subject)) }) } } @@ -232,121 +317,149 @@ func (suite *SubjectsPublicTestSuite) TestGetLocalHostname() { func (suite *SubjectsPublicTestSuite) TestSanitizeHostname() { tests := []struct { - name string - hostname string - want string + name string + hostname string + validateFunc func(string) }{ { name: "when hostname has no special characters", hostname: "server01", - want: "server01", + validateFunc: func(got string) { + suite.Equal("server01", got) + }, }, { name: "when hostname has hyphens", hostname: "web-server-01", - want: "web_server_01", + validateFunc: func(got string) { + suite.Equal("web_server_01", got) + }, }, { name: "when hostname has dots", hostname: "server.example.com", - want: "server_example_com", + validateFunc: func(got string) { + suite.Equal("server_example_com", got) + }, }, { name: "when hostname has hyphens and dots", hostname: "Johns-MacBook-Pro-2.local", - want: "Johns_MacBook_Pro_2_local", + validateFunc: func(got string) { + suite.Equal("Johns_MacBook_Pro_2_local", got) + }, }, { name: "when hostname has mixed special characters", hostname: "test@host#123.domain!", - want: "test_host_123_domain_", + validateFunc: func(got string) { + suite.Equal("test_host_123_domain_", got) + }, }, { name: "when hostname has underscores (should be preserved)", hostname: "test_server_01", - want: "test_server_01", + validateFunc: func(got string) { + suite.Equal("test_server_01", got) + }, }, { name: "when hostname has numbers", hostname: "server123", - want: "server123", + validateFunc: func(got string) { + suite.Equal("server123", got) + }, }, { name: "when hostname is empty", hostname: "", - want: "", + validateFunc: func(got string) { + suite.Equal("", got) + }, }, { name: "when hostname has spaces", hostname: "my server name", - want: "my_server_name", + validateFunc: func(got string) { + suite.Equal("my_server_name", got) + }, }, } for _, tt := range tests { suite.Run(tt.name, func() { got := job.SanitizeHostname(tt.hostname) - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } func (suite *SubjectsPublicTestSuite) TestBuildAgentSubscriptionPattern() { tests := []struct { - name string - hostname string - labels map[string]string - want []string + name string + hostname string + labels map[string]string + validateFunc func([]string) }{ { name: "when building subscription pattern for specific hostname", hostname: "web-server-01", - want: []string{ - "jobs.*.host.web_server_01", - "jobs.*._any", - "jobs.*._all", + validateFunc: func(got []string) { + suite.Equal([]string{ + "jobs.*.host.web_server_01", + "jobs.*._any", + "jobs.*._all", + }, got) }, }, { name: "when building subscription pattern for localhost", hostname: "localhost", - want: []string{ - "jobs.*.host.localhost", - "jobs.*._any", - "jobs.*._all", + validateFunc: func(got []string) { + suite.Equal([]string{ + "jobs.*.host.localhost", + "jobs.*._any", + "jobs.*._all", + }, got) }, }, { name: "when building subscription pattern with dotted hostname", hostname: "api.example.com", - want: []string{ - "jobs.*.host.api_example_com", - "jobs.*._any", - "jobs.*._all", + validateFunc: func(got []string) { + suite.Equal([]string{ + "jobs.*.host.api_example_com", + "jobs.*._any", + "jobs.*._all", + }, got) }, }, { name: "when building with hierarchical label", hostname: "web-01", labels: map[string]string{"group": "web.dev.us-east"}, - want: []string{ - "jobs.*.host.web_01", - "jobs.*._any", - "jobs.*._all", - "jobs.*.label.group.web", - "jobs.*.label.group.web.dev", - "jobs.*.label.group.web.dev.us-east", + validateFunc: func(got []string) { + suite.Equal([]string{ + "jobs.*.host.web_01", + "jobs.*._any", + "jobs.*._all", + "jobs.*.label.group.web", + "jobs.*.label.group.web.dev", + "jobs.*.label.group.web.dev.us-east", + }, got) }, }, { name: "when building with flat label", hostname: "web-01", labels: map[string]string{"team": "platform"}, - want: []string{ - "jobs.*.host.web_01", - "jobs.*._any", - "jobs.*._all", - "jobs.*.label.team.platform", + validateFunc: func(got []string) { + suite.Equal([]string{ + "jobs.*.host.web_01", + "jobs.*._any", + "jobs.*._all", + "jobs.*.label.team.platform", + }, got) }, }, } @@ -354,355 +467,435 @@ func (suite *SubjectsPublicTestSuite) TestBuildAgentSubscriptionPattern() { for _, tt := range tests { suite.Run(tt.name, func() { got := job.BuildAgentSubscriptionPattern(tt.hostname, tt.labels) - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } func (suite *SubjectsPublicTestSuite) TestBuildAgentQueueGroup() { tests := []struct { - name string - category string - want string + name string + category string + validateFunc func(string) }{ { name: "when building queue group for node category", category: "node", - want: "agents.node", + validateFunc: func(got string) { + suite.Equal("agents.node", got) + }, }, { name: "when building queue group for network category", category: "network", - want: "agents.network", + validateFunc: func(got string) { + suite.Equal("agents.network", got) + }, }, { name: "when building queue group for jobs category", category: "jobs", - want: "agents.jobs", + validateFunc: func(got string) { + suite.Equal("agents.jobs", got) + }, }, { name: "when building queue group with empty category", category: "", - want: "agents.", + validateFunc: func(got string) { + suite.Equal("agents.", got) + }, }, { name: "when building queue group with complex category", category: "custom-service", - want: "agents.custom-service", + validateFunc: func(got string) { + suite.Equal("agents.custom-service", got) + }, }, } for _, tt := range tests { suite.Run(tt.name, func() { got := job.BuildAgentQueueGroup(tt.category) - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } func (suite *SubjectsPublicTestSuite) TestIsSpecialHostname() { tests := []struct { - name string - hostname string - want bool + name string + hostname string + validateFunc func(bool) }{ { name: "when hostname is AllHosts wildcard", hostname: job.AllHosts, - want: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when hostname is AnyHost", hostname: job.AnyHost, - want: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when hostname is LocalHost", hostname: job.LocalHost, - want: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when hostname is BroadcastHost", hostname: job.BroadcastHost, - want: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when hostname is regular server name", hostname: "web-server-01", - want: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, { name: "when hostname is localhost", hostname: "localhost", - want: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, { name: "when hostname is FQDN", hostname: "api.example.com", - want: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, { name: "when hostname is empty", hostname: "", - want: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, { name: "when hostname looks like special but isn't exact", hostname: "_any_server", - want: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, } for _, tt := range tests { suite.Run(tt.name, func() { got := job.IsSpecialHostname(tt.hostname) - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } func (suite *SubjectsPublicTestSuite) TestValidateLabel() { tests := []struct { - name string - key string - value string - wantErr bool + name string + key string + value string + validateFunc func(error) }{ { name: "when key and value are simple alphanumeric", key: "role", value: "web", + validateFunc: func(err error) { + suite.NoError(err) + }, }, { name: "when value has hyphens and underscores", key: "env", value: "us-east_1", + validateFunc: func(err error) { + suite.NoError(err) + }, }, { name: "when value is hierarchical with dots", key: "group", value: "web.dev.us-east", + validateFunc: func(err error) { + suite.NoError(err) + }, }, { - name: "when key contains dots", - key: "my.key", - value: "web", - wantErr: true, + name: "when key contains dots", + key: "my.key", + value: "web", + validateFunc: func(err error) { + suite.Error(err) + }, }, { - name: "when key contains colon", - key: "my:key", - value: "web", - wantErr: true, + name: "when key contains colon", + key: "my:key", + value: "web", + validateFunc: func(err error) { + suite.Error(err) + }, }, { - name: "when value segment contains spaces", - key: "group", - value: "web.dev server", - wantErr: true, + name: "when value segment contains spaces", + key: "group", + value: "web.dev server", + validateFunc: func(err error) { + suite.Error(err) + }, }, { - name: "when value has empty segment", - key: "group", - value: "web..dev", - wantErr: true, + name: "when value has empty segment", + key: "group", + value: "web..dev", + validateFunc: func(err error) { + suite.Error(err) + }, }, { - name: "when key is empty", - key: "", - value: "web", - wantErr: true, + name: "when key is empty", + key: "", + value: "web", + validateFunc: func(err error) { + suite.Error(err) + }, }, } for _, tt := range tests { suite.Run(tt.name, func() { - err := job.ValidateLabel(tt.key, tt.value) - if tt.wantErr { - suite.Error(err) - } else { - suite.NoError(err) - } + tt.validateFunc(job.ValidateLabel(tt.key, tt.value)) }) } } func (suite *SubjectsPublicTestSuite) TestParseTarget() { tests := []struct { - name string - target string - wantRouting string - wantKey string - wantValue string + name string + target string + validateFunc func(string, string, string) }{ { - name: "when target is _any", - target: "_any", - wantRouting: "_any", + name: "when target is _any", + target: "_any", + validateFunc: func(rt string, key string, value string) { + suite.Equal("_any", rt) + suite.Equal("", key) + suite.Equal("", value) + }, }, { - name: "when target is _all", - target: "_all", - wantRouting: "_all", + name: "when target is _all", + target: "_all", + validateFunc: func(rt string, key string, value string) { + suite.Equal("_all", rt) + suite.Equal("", key) + suite.Equal("", value) + }, }, { - name: "when target is a hostname", - target: "server1", - wantRouting: "host", - wantKey: "server1", + name: "when target is a hostname", + target: "server1", + validateFunc: func(rt string, key string, value string) { + suite.Equal("host", rt) + suite.Equal("server1", key) + suite.Equal("", value) + }, }, { - name: "when target is a flat label", - target: "role:web", - wantRouting: "label", - wantKey: "role", - wantValue: "web", + name: "when target is a flat label", + target: "role:web", + validateFunc: func(rt string, key string, value string) { + suite.Equal("label", rt) + suite.Equal("role", key) + suite.Equal("web", value) + }, }, { - name: "when target is a hierarchical label", - target: "group:web.dev.us-east", - wantRouting: "label", - wantKey: "group", - wantValue: "web.dev.us-east", + name: "when target is a hierarchical label", + target: "group:web.dev.us-east", + validateFunc: func(rt string, key string, value string) { + suite.Equal("label", rt) + suite.Equal("group", key) + suite.Equal("web.dev.us-east", value) + }, }, } for _, tt := range tests { suite.Run(tt.name, func() { - rt, key, value := job.ParseTarget(tt.target) - suite.Equal(tt.wantRouting, rt) - suite.Equal(tt.wantKey, key) - suite.Equal(tt.wantValue, value) + tt.validateFunc(job.ParseTarget(tt.target)) }) } } func (suite *SubjectsPublicTestSuite) TestBuildSubjectFromTarget() { tests := []struct { - name string - prefix string - target string - want string + name string + prefix string + target string + validateFunc func(string) }{ { name: "when target is _any", prefix: "jobs.query", target: "_any", - want: "jobs.query._any", + validateFunc: func(got string) { + suite.Equal("jobs.query._any", got) + }, }, { name: "when target is _all", prefix: "jobs.modify", target: "_all", - want: "jobs.modify._all", + validateFunc: func(got string) { + suite.Equal("jobs.modify._all", got) + }, }, { name: "when target is a hostname", prefix: "jobs.query", target: "server1", - want: "jobs.query.host.server1", + validateFunc: func(got string) { + suite.Equal("jobs.query.host.server1", got) + }, }, { name: "when target is a dotted hostname", prefix: "jobs.query", target: "my-server.local", - want: "jobs.query.host.my_server_local", + validateFunc: func(got string) { + suite.Equal("jobs.query.host.my_server_local", got) + }, }, { name: "when target is a flat label", prefix: "jobs.query", target: "role:web", - want: "jobs.query.label.role.web", + validateFunc: func(got string) { + suite.Equal("jobs.query.label.role.web", got) + }, }, { name: "when target is a hierarchical label", prefix: "jobs.query", target: "group:web.dev.us-east", - want: "jobs.query.label.group.web.dev.us-east", + validateFunc: func(got string) { + suite.Equal("jobs.query.label.group.web.dev.us-east", got) + }, }, } for _, tt := range tests { suite.Run(tt.name, func() { got := job.BuildSubjectFromTarget(tt.prefix, tt.target) - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } func (suite *SubjectsPublicTestSuite) TestIsBroadcastTarget() { tests := []struct { - name string - target string - want bool + name string + target string + validateFunc func(bool) }{ { name: "when target is _all", target: "_all", - want: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when target is a label", target: "role:web", - want: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when target is a hierarchical label", target: "group:web.dev", - want: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when target is _any", target: "_any", - want: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, { name: "when target is a hostname", target: "server1", - want: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, } for _, tt := range tests { suite.Run(tt.name, func() { got := job.IsBroadcastTarget(tt.target) - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } func (suite *SubjectsPublicTestSuite) TestBuildLabelSubjects() { tests := []struct { - name string - key string - value string - want []string + name string + key string + value string + validateFunc func([]string) }{ { name: "when value is flat", key: "role", value: "web", - want: []string{ - "jobs.*.label.role.web", + validateFunc: func(got []string) { + suite.Equal([]string{ + "jobs.*.label.role.web", + }, got) }, }, { name: "when value is hierarchical with two levels", key: "group", value: "web.dev", - want: []string{ - "jobs.*.label.group.web", - "jobs.*.label.group.web.dev", + validateFunc: func(got []string) { + suite.Equal([]string{ + "jobs.*.label.group.web", + "jobs.*.label.group.web.dev", + }, got) }, }, { name: "when value is hierarchical with three levels", key: "group", value: "web.dev.us-east", - want: []string{ - "jobs.*.label.group.web", - "jobs.*.label.group.web.dev", - "jobs.*.label.group.web.dev.us-east", + validateFunc: func(got []string) { + suite.Equal([]string{ + "jobs.*.label.group.web", + "jobs.*.label.group.web.dev", + "jobs.*.label.group.web.dev.us-east", + }, got) }, }, } @@ -710,7 +903,7 @@ func (suite *SubjectsPublicTestSuite) TestBuildLabelSubjects() { for _, tt := range tests { suite.Run(tt.name, func() { got := job.BuildLabelSubjects(tt.key, tt.value) - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } @@ -723,7 +916,7 @@ func (suite *SubjectsPublicTestSuite) TestInit() { wantModifyPrefix string wantBuildQuery string wantSubscription string - wantLabelSubject string + validateFunc func([]string) }{ { name: "when namespace is empty", @@ -732,7 +925,9 @@ func (suite *SubjectsPublicTestSuite) TestInit() { wantModifyPrefix: "jobs.modify", wantBuildQuery: "jobs.query._any", wantSubscription: "jobs.*._any", - wantLabelSubject: "jobs.*.label.role.web", + validateFunc: func(labels []string) { + suite.Equal([]string{"jobs.*.label.role.web"}, labels) + }, }, { name: "when namespace is set", @@ -741,7 +936,9 @@ func (suite *SubjectsPublicTestSuite) TestInit() { wantModifyPrefix: "osapi.jobs.modify", wantBuildQuery: "osapi.jobs.query._any", wantSubscription: "osapi.jobs.*._any", - wantLabelSubject: "osapi.jobs.*.label.role.web", + validateFunc: func(labels []string) { + suite.Equal([]string{"osapi.jobs.*.label.role.web"}, labels) + }, }, } @@ -755,8 +952,7 @@ func (suite *SubjectsPublicTestSuite) TestInit() { suite.Equal(tt.wantBuildQuery, job.BuildQuerySubject("_any")) subs := job.BuildAgentSubscriptionPattern("web-01", nil) suite.Contains(subs, tt.wantSubscription) - labels := job.BuildLabelSubjects("role", "web") - suite.Equal([]string{tt.wantLabelSubject}, labels) + tt.validateFunc(job.BuildLabelSubjects("role", "web")) }) } } @@ -766,42 +962,82 @@ func (suite *SubjectsPublicTestSuite) TestParseSubjectWithNamespace() { name string namespace string subject string - wantPrefix string - wantHostname string - wantErr bool + validateFunc func(string, string, error) }{ { - name: "when parsing namespaced query subject", - namespace: "osapi", - subject: "osapi.jobs.query.host.server-01", - wantPrefix: "osapi.jobs.query", - wantHostname: "server-01", + name: "when parsing namespaced query subject", + namespace: "osapi", + subject: "osapi.jobs.query.host.server-01", + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if false { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("osapi.jobs.query", gotPrefix) + suite.Equal("server-01", gotHostname) + }, }, { - name: "when parsing namespaced modify subject", - namespace: "osapi", - subject: "osapi.jobs.modify._any", - wantPrefix: "osapi.jobs.modify", - wantHostname: "_any", + name: "when parsing namespaced modify subject", + namespace: "osapi", + subject: "osapi.jobs.modify._any", + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if false { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("osapi.jobs.modify", gotPrefix) + suite.Equal("_any", gotHostname) + }, }, { - name: "when parsing namespaced label subject", - namespace: "osapi", - subject: "osapi.jobs.query.label.group.web.dev", - wantPrefix: "osapi.jobs.query", - wantHostname: "group:web.dev", + name: "when parsing namespaced label subject", + namespace: "osapi", + subject: "osapi.jobs.query.label.group.web.dev", + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if false { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("osapi.jobs.query", gotPrefix) + suite.Equal("group:web.dev", gotHostname) + }, }, { name: "when parsing invalid namespaced subject with too few parts", namespace: "osapi", subject: "osapi.jobs", - wantErr: true, + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if true { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("", gotPrefix) + suite.Equal("", gotHostname) + }, }, { name: "when parsing namespaced subject without jobs token", namespace: "osapi", subject: "osapi.other.query._any", - wantErr: true, + validateFunc: func(gotPrefix string, gotHostname string, err error) { + if true { + suite.Error(err) + return + } + + suite.NoError(err) + suite.Equal("", gotPrefix) + suite.Equal("", gotHostname) + }, }, } @@ -810,80 +1046,81 @@ func (suite *SubjectsPublicTestSuite) TestParseSubjectWithNamespace() { job.Init(tt.namespace) defer job.Init("") - gotPrefix, gotHostname, err := job.ParseSubject(tt.subject) - - if tt.wantErr { - suite.Error(err) - return - } - - suite.NoError(err) - suite.Equal(tt.wantPrefix, gotPrefix) - suite.Equal(tt.wantHostname, gotHostname) + tt.validateFunc(job.ParseSubject(tt.subject)) }) } } func (suite *SubjectsPublicTestSuite) TestApplyNamespaceToInfraName() { tests := []struct { - name string - namespace string - infraName string - want string + name string + namespace string + infraName string + validateFunc func(string) }{ { name: "when namespace is empty", namespace: "", infraName: "JOBS", - want: "JOBS", + validateFunc: func(got string) { + suite.Equal("JOBS", got) + }, }, { name: "when namespace is set", namespace: "osapi", infraName: "JOBS", - want: "osapi-JOBS", + validateFunc: func(got string) { + suite.Equal("osapi-JOBS", got) + }, }, { name: "when namespace applied to KV bucket", namespace: "osapi", infraName: "job-queue", - want: "osapi-job-queue", + validateFunc: func(got string) { + suite.Equal("osapi-job-queue", got) + }, }, } for _, tt := range tests { suite.Run(tt.name, func() { got := job.ApplyNamespaceToInfraName(tt.namespace, tt.infraName) - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } func (suite *SubjectsPublicTestSuite) TestApplyNamespaceToSubjects() { tests := []struct { - name string - namespace string - subjects string - want string + name string + namespace string + subjects string + validateFunc func(string) }{ { name: "when namespace is empty", namespace: "", subjects: "jobs.>", - want: "jobs.>", + validateFunc: func(got string) { + suite.Equal("jobs.>", got) + }, }, { name: "when namespace is set", namespace: "osapi", subjects: "jobs.>", - want: "osapi.jobs.>", + validateFunc: func(got string) { + suite.Equal("osapi.jobs.>", got) + }, }, } for _, tt := range tests { suite.Run(tt.name, func() { got := job.ApplyNamespaceToSubjects(tt.namespace, tt.subjects) - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } @@ -897,64 +1134,82 @@ func (suite *SubjectsPublicTestSuite) TestCountExpectedAgents() { } tests := []struct { - name string - agents []job.AgentInfo - target string - want int + name string + agents []job.AgentInfo + target string + validateFunc func(int) }{ { name: "when target is _all returns full count", agents: agents, target: "_all", - want: 4, + validateFunc: func(got int) { + suite.Equal(4, got) + }, }, { name: "when label exact match", agents: agents, target: "group:web.dev.us-east", - want: 1, + validateFunc: func(got int) { + suite.Equal(1, got) + }, }, { name: "when label prefix match", agents: agents, target: "group:web", - want: 2, + validateFunc: func(got int) { + suite.Equal(2, got) + }, }, { name: "when label prefix match at second level", agents: agents, target: "group:web.dev", - want: 2, + validateFunc: func(got int) { + suite.Equal(2, got) + }, }, { name: "when no agents match label", agents: agents, target: "group:staging", - want: 0, + validateFunc: func(got int) { + suite.Equal(0, got) + }, }, { name: "when label key does not exist on any agent", agents: agents, target: "region:us-east", - want: 0, + validateFunc: func(got int) { + suite.Equal(0, got) + }, }, { name: "when agent list is empty", agents: []job.AgentInfo{}, target: "_all", - want: 0, + validateFunc: func(got int) { + suite.Equal(0, got) + }, }, { name: "when target is a hostname returns 0", agents: agents, target: "web-01", - want: 0, + validateFunc: func(got int) { + suite.Equal(0, got) + }, }, { name: "when target is _any returns 0", agents: agents, target: "_any", - want: 0, + validateFunc: func(got int) { + suite.Equal(0, got) + }, }, { name: "when _all excludes cordoned agents", @@ -964,7 +1219,9 @@ func (suite *SubjectsPublicTestSuite) TestCountExpectedAgents() { {Hostname: "web-03"}, }, target: "_all", - want: 2, + validateFunc: func(got int) { + suite.Equal(2, got) + }, }, { name: "when _all excludes draining agents", @@ -973,7 +1230,9 @@ func (suite *SubjectsPublicTestSuite) TestCountExpectedAgents() { {Hostname: "web-02", State: job.AgentStateDraining}, }, target: "_all", - want: 1, + validateFunc: func(got int) { + suite.Equal(1, got) + }, }, { name: "when _all excludes pending agents", @@ -982,7 +1241,9 @@ func (suite *SubjectsPublicTestSuite) TestCountExpectedAgents() { {Hostname: "web-02", State: job.AgentStatePending}, }, target: "_all", - want: 1, + validateFunc: func(got int) { + suite.Equal(1, got) + }, }, { name: "when label match excludes cordoned agents", @@ -995,7 +1256,9 @@ func (suite *SubjectsPublicTestSuite) TestCountExpectedAgents() { {Hostname: "web-02", Labels: map[string]string{"group": "web.dev"}}, }, target: "group:web", - want: 1, + validateFunc: func(got int) { + suite.Equal(1, got) + }, }, { name: "when label match excludes draining agents", @@ -1008,14 +1271,16 @@ func (suite *SubjectsPublicTestSuite) TestCountExpectedAgents() { {Hostname: "web-02", Labels: map[string]string{"group": "web.dev"}}, }, target: "group:web", - want: 1, + validateFunc: func(got int) { + suite.Equal(1, got) + }, }, } for _, tt := range tests { suite.Run(tt.name, func() { got := job.CountExpectedAgents(tt.agents, tt.target) - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } @@ -1029,52 +1294,66 @@ func (suite *SubjectsPublicTestSuite) TestExpectedAgentHostnames() { } tests := []struct { - name string - agents []job.AgentInfo - target string - want []string + name string + agents []job.AgentInfo + target string + validateFunc func([]string) }{ { name: "when target is _all returns all hostnames", agents: agents, target: "_all", - want: []string{"web-01", "web-02", "db-01", "plain-01"}, + validateFunc: func(got []string) { + suite.Equal([]string{"web-01", "web-02", "db-01", "plain-01"}, got) + }, }, { name: "when label exact match returns matching hostnames", agents: agents, target: "group:web.dev.us-east", - want: []string{"web-01"}, + validateFunc: func(got []string) { + suite.Equal([]string{"web-01"}, got) + }, }, { name: "when label prefix match returns matching hostnames", agents: agents, target: "group:web", - want: []string{"web-01", "web-02"}, + validateFunc: func(got []string) { + suite.Equal([]string{"web-01", "web-02"}, got) + }, }, { name: "when no agents match label returns nil", agents: agents, target: "group:staging", - want: nil, + validateFunc: func(got []string) { + suite.Equal([]string(nil), got) + }, }, { name: "when agent list is empty returns nil", agents: []job.AgentInfo{}, target: "_all", - want: nil, + validateFunc: func(got []string) { + suite.Equal([]string(nil), got) + }, }, { name: "when target is a hostname returns nil", agents: agents, target: "web-01", - want: nil, + validateFunc: func(got []string) { + suite.Equal([]string(nil), got) + }, }, { name: "when target is _any returns nil", agents: agents, target: "_any", - want: nil, + validateFunc: func(got []string) { + suite.Equal([]string(nil), got) + }, }, { name: "when _all excludes cordoned agents", @@ -1084,7 +1363,9 @@ func (suite *SubjectsPublicTestSuite) TestExpectedAgentHostnames() { {Hostname: "web-03"}, }, target: "_all", - want: []string{"web-01", "web-03"}, + validateFunc: func(got []string) { + suite.Equal([]string{"web-01", "web-03"}, got) + }, }, { name: "when _all excludes draining agents", @@ -1093,7 +1374,9 @@ func (suite *SubjectsPublicTestSuite) TestExpectedAgentHostnames() { {Hostname: "web-02", State: job.AgentStateDraining}, }, target: "_all", - want: []string{"web-01"}, + validateFunc: func(got []string) { + suite.Equal([]string{"web-01"}, got) + }, }, { name: "when _all excludes pending agents", @@ -1102,7 +1385,9 @@ func (suite *SubjectsPublicTestSuite) TestExpectedAgentHostnames() { {Hostname: "web-02", State: job.AgentStatePending}, }, target: "_all", - want: []string{"web-01"}, + validateFunc: func(got []string) { + suite.Equal([]string{"web-01"}, got) + }, }, { name: "when label match excludes cordoned agents", @@ -1115,18 +1400,22 @@ func (suite *SubjectsPublicTestSuite) TestExpectedAgentHostnames() { {Hostname: "web-02", Labels: map[string]string{"group": "web.dev"}}, }, target: "group:web", - want: []string{"web-02"}, + validateFunc: func(got []string) { + suite.Equal([]string{"web-02"}, got) + }, }, } for _, tt := range tests { suite.Run(tt.name, func() { got := job.ExpectedAgentHostnames(tt.agents, tt.target) - suite.Equal(tt.want, got) + tt.validateFunc(got) }) } } -func TestSubjectsPublicTestSuite(t *testing.T) { +func TestSubjectsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SubjectsPublicTestSuite)) } diff --git a/internal/job/types_public_test.go b/internal/job/types_public_test.go index 9b982498d..1e6f52dae 100644 --- a/internal/job/types_public_test.go +++ b/internal/job/types_public_test.go @@ -299,6 +299,8 @@ func (suite *TypesPublicTestSuite) TestAgentInfoFactsFieldsJSONRoundTrip() { } } -func TestTypesPublicTestSuite(t *testing.T) { +func TestTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(TypesPublicTestSuite)) } diff --git a/internal/provider/command/command_public_test.go b/internal/provider/command/command_public_test.go index 111c8b4a5..1270eeeaa 100644 --- a/internal/provider/command/command_public_test.go +++ b/internal/provider/command/command_public_test.go @@ -47,10 +47,14 @@ func (s *CommandPublicTestSuite) TearDownTest() { func (s *CommandPublicTestSuite) TestNew() { tests := []struct { - name string + name string + validateFunc func(*command.Executor) }{ { name: "creates executor with logger and exec manager", + validateFunc: func(executor *command.Executor) { + s.NotNil(executor) + }, }, } @@ -58,13 +62,13 @@ func (s *CommandPublicTestSuite) TestNew() { s.Run(tt.name, func() { mockExecMgr := execMocks.NewMockManager(s.mockCtrl) - executor := command.New(slog.Default(), mockExecMgr) - - s.NotNil(executor) + tt.validateFunc(command.New(slog.Default(), mockExecMgr)) }) } } -func TestCommandPublicTestSuite(t *testing.T) { +func TestCommandPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CommandPublicTestSuite)) } diff --git a/internal/provider/command/exec_public_test.go b/internal/provider/command/exec_public_test.go index b282440dd..406fa0a3b 100644 --- a/internal/provider/command/exec_public_test.go +++ b/internal/provider/command/exec_public_test.go @@ -53,13 +53,11 @@ func (s *ExecPublicTestSuite) TearDownTest() { func (s *ExecPublicTestSuite) TestExec() { tests := []struct { - name string - params command.ExecParams - mockResult *exec.CmdResult - mockError error - expectError bool - errorContains string - validate func(*command.Result) + name string + params command.ExecParams + mockResult *exec.CmdResult + mockError error + validateFunc func(*command.Result, error) }{ { name: "successful execution", @@ -75,11 +73,13 @@ func (s *ExecPublicTestSuite) TestExec() { ExitCode: 0, DurationMs: 12, }, - validate: func(r *command.Result) { - s.Equal("total 0\n", r.Stdout) - s.Empty(r.Stderr) - s.Equal(0, r.ExitCode) - s.Equal(int64(12), r.DurationMs) + validateFunc: func(result *command.Result, err error) { + s.NoError(err) + s.NotNil(result) + s.Equal("total 0\n", result.Stdout) + s.Empty(result.Stderr) + s.Equal(0, result.ExitCode) + s.Equal(int64(12), result.DurationMs) }, }, { @@ -93,9 +93,11 @@ func (s *ExecPublicTestSuite) TestExec() { ExitCode: 1, DurationMs: 5, }, - validate: func(r *command.Result) { - s.Equal(1, r.ExitCode) - s.Equal("error occurred\n", r.Stderr) + validateFunc: func(result *command.Result, err error) { + s.NoError(err) + s.NotNil(result) + s.Equal(1, result.ExitCode) + s.Equal("error occurred\n", result.Stderr) }, }, { @@ -103,9 +105,12 @@ func (s *ExecPublicTestSuite) TestExec() { params: command.ExecParams{ Command: "nonexistent", }, - mockError: errors.New("command not found"), - expectError: true, - errorContains: "command execution failed", + mockError: errors.New("command not found"), + validateFunc: func(result *command.Result, err error) { + s.Error(err) + s.Contains(err.Error(), "command execution failed") + s.Nil(result) + }, }, } @@ -120,23 +125,13 @@ func (s *ExecPublicTestSuite) TestExec() { ). Return(tt.mockResult, tt.mockError) - result, err := s.sut.Exec(tt.params) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorContains) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(s.sut.Exec(tt.params)) }) } } -func TestExecPublicTestSuite(t *testing.T) { +func TestExecPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ExecPublicTestSuite)) } diff --git a/internal/provider/command/mocks/mocks.go b/internal/provider/command/mocks/mocks.go index 1a29cebeb..1db25642d 100644 --- a/internal/provider/command/mocks/mocks.go +++ b/internal/provider/command/mocks/mocks.go @@ -27,12 +27,16 @@ import ( ) // NewPlainMockProvider creates a Mock without defaults. -func NewPlainMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewPlainMockProvider( + ctrl *gomock.Controller, +) *MockProvider { return NewMockProvider(ctrl) } // NewDefaultMockProvider creates a Mock with defaults. -func NewDefaultMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewDefaultMockProvider( + ctrl *gomock.Controller, +) *MockProvider { mock := NewPlainMockProvider(ctrl) mock.EXPECT().Exec(gomock.Any()).Return(&command.Result{ diff --git a/internal/provider/command/shell_public_test.go b/internal/provider/command/shell_public_test.go index 46c96e1d4..da09856cb 100644 --- a/internal/provider/command/shell_public_test.go +++ b/internal/provider/command/shell_public_test.go @@ -53,13 +53,11 @@ func (s *ShellPublicTestSuite) TearDownTest() { func (s *ShellPublicTestSuite) TestShell() { tests := []struct { - name string - params command.ShellParams - mockResult *exec.CmdResult - mockError error - expectError bool - errorContains string - validate func(*command.Result) + name string + params command.ShellParams + mockResult *exec.CmdResult + mockError error + validateFunc func(*command.Result, error) }{ { name: "successful shell command", @@ -74,11 +72,13 @@ func (s *ShellPublicTestSuite) TestShell() { ExitCode: 0, DurationMs: 15, }, - validate: func(r *command.Result) { - s.Equal("HELLO\n", r.Stdout) - s.Empty(r.Stderr) - s.Equal(0, r.ExitCode) - s.Equal(int64(15), r.DurationMs) + validateFunc: func(result *command.Result, err error) { + s.NoError(err) + s.NotNil(result) + s.Equal("HELLO\n", result.Stdout) + s.Empty(result.Stderr) + s.Equal(0, result.ExitCode) + s.Equal(int64(15), result.DurationMs) }, }, { @@ -92,8 +92,10 @@ func (s *ShellPublicTestSuite) TestShell() { ExitCode: 2, DurationMs: 3, }, - validate: func(r *command.Result) { - s.Equal(2, r.ExitCode) + validateFunc: func(result *command.Result, err error) { + s.NoError(err) + s.NotNil(result) + s.Equal(2, result.ExitCode) }, }, { @@ -101,9 +103,12 @@ func (s *ShellPublicTestSuite) TestShell() { params: command.ShellParams{ Command: "bad command", }, - mockError: errors.New("shell failed"), - expectError: true, - errorContains: "shell execution failed", + mockError: errors.New("shell failed"), + validateFunc: func(result *command.Result, err error) { + s.Error(err) + s.Contains(err.Error(), "shell execution failed") + s.Nil(result) + }, }, } @@ -118,23 +123,13 @@ func (s *ShellPublicTestSuite) TestShell() { ). Return(tt.mockResult, tt.mockError) - result, err := s.sut.Shell(tt.params) - - if tt.expectError { - s.Error(err) - s.Contains(err.Error(), tt.errorContains) - s.Nil(result) - } else { - s.NoError(err) - s.NotNil(result) - if tt.validate != nil { - tt.validate(result) - } - } + tt.validateFunc(s.sut.Shell(tt.params)) }) } } -func TestShellPublicTestSuite(t *testing.T) { +func TestShellPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ShellPublicTestSuite)) } diff --git a/internal/provider/container/docker/docker.go b/internal/provider/container/docker/docker.go index 931cc3972..c8a7b8680 100644 --- a/internal/provider/container/docker/docker.go +++ b/internal/provider/container/docker/docker.go @@ -1,3 +1,23 @@ +// Copyright (c) 2026 John Dewey + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + // Package docker provides the Docker container management provider using the Docker Engine API. package docker diff --git a/internal/provider/container/docker/docker_public_test.go b/internal/provider/container/docker/docker_public_test.go index ecdafd021..64b2e4013 100644 --- a/internal/provider/container/docker/docker_public_test.go +++ b/internal/provider/container/docker/docker_public_test.go @@ -1,3 +1,23 @@ +// Copyright (c) 2026 John Dewey + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + package docker_test import ( diff --git a/internal/provider/container/docker/types.go b/internal/provider/container/docker/types.go index fafcd6d6d..e9a8b8c73 100644 --- a/internal/provider/container/docker/types.go +++ b/internal/provider/container/docker/types.go @@ -1,3 +1,23 @@ +// Copyright (c) 2026 John Dewey + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + // Package docker provides the Docker container management provider. package docker diff --git a/internal/provider/facts_public_test.go b/internal/provider/facts_public_test.go index 86c4c15ca..2c9d19118 100644 --- a/internal/provider/facts_public_test.go +++ b/internal/provider/facts_public_test.go @@ -38,16 +38,18 @@ func (suite *FactsPublicTestSuite) TearDownTest() {} func (suite *FactsPublicTestSuite) TestSetFactsFunc() { tests := []struct { - name string - factsFn provider.FactsFunc - wantFacts map[string]any + name string + factsFn provider.FactsFunc + validateFunc func(map[string]any) }{ { name: "when sets the facts function", factsFn: func() map[string]any { return map[string]any{"cpu_count": 4} }, - wantFacts: map[string]any{"cpu_count": 4}, + validateFunc: func(got map[string]any) { + suite.Equal(map[string]any{"cpu_count": 4}, got) + }, }, } @@ -57,30 +59,34 @@ func (suite *FactsPublicTestSuite) TestSetFactsFunc() { fa.SetFactsFunc(tc.factsFn) got := fa.Facts() - suite.Equal(tc.wantFacts, got) + tc.validateFunc(got) }) } } func (suite *FactsPublicTestSuite) TestFacts() { tests := []struct { - name string - factsFn provider.FactsFunc - setFacts bool - wantFacts map[string]any + name string + factsFn provider.FactsFunc + setFacts bool + validateFunc func(map[string]any) }{ { - name: "when factsFn is nil returns nil", - setFacts: false, - wantFacts: nil, + name: "when factsFn is nil returns nil", + setFacts: false, + validateFunc: func(got map[string]any) { + suite.Equal(map[string]any(nil), got) + }, }, { - name: "when factsFn is set returns facts", - setFacts: true, + name: "when factsFn is set returns facts", factsFn: func() map[string]any { return map[string]any{"cpu_count": 4} }, - wantFacts: map[string]any{"cpu_count": 4}, + setFacts: true, + validateFunc: func(got map[string]any) { + suite.Equal(map[string]any{"cpu_count": 4}, got) + }, }, } @@ -92,7 +98,7 @@ func (suite *FactsPublicTestSuite) TestFacts() { } got := fa.Facts() - suite.Equal(tc.wantFacts, got) + tc.validateFunc(got) }) } } @@ -104,18 +110,20 @@ type testFactsProvider struct { func (suite *FactsPublicTestSuite) TestWireProviderFacts() { tests := []struct { - name string - providers []any - wantFacts map[string]any - checkIdx int + name string + providers []any + checkIdx int + validateFunc func(map[string]any) }{ { name: "when wires facts to implementing providers", providers: []any{ &testFactsProvider{}, }, - wantFacts: map[string]any{"os": "linux"}, - checkIdx: 0, + checkIdx: 0, + validateFunc: func(got map[string]any) { + suite.Equal(map[string]any{"os": "linux"}, got) + }, }, { name: "when skips non-implementing providers", @@ -123,8 +131,10 @@ func (suite *FactsPublicTestSuite) TestWireProviderFacts() { "not-a-provider", &testFactsProvider{}, }, - wantFacts: map[string]any{"os": "linux"}, - checkIdx: 1, + checkIdx: 1, + validateFunc: func(got map[string]any) { + suite.Equal(map[string]any{"os": "linux"}, got) + }, }, } @@ -142,13 +152,15 @@ func (suite *FactsPublicTestSuite) TestWireProviderFacts() { suite.Require().True(ok) got := p.Facts() - suite.Equal(tc.wantFacts, got) + tc.validateFunc(got) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestFactsPublicTestSuite(t *testing.T) { +func TestFactsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FactsPublicTestSuite)) } diff --git a/internal/provider/file/deploy_public_test.go b/internal/provider/file/deploy_public_test.go index 98c0c835e..7c4d87f0e 100644 --- a/internal/provider/file/deploy_public_test.go +++ b/internal/provider/file/deploy_public_test.go @@ -675,6 +675,8 @@ func (suite *DeployPublicTestSuite) TestDeploy() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDeployPublicTestSuite(t *testing.T) { +func TestDeployPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DeployPublicTestSuite)) } diff --git a/internal/provider/file/export_test.go b/internal/provider/file/export_test.go index 694f3e815..952d0934e 100644 --- a/internal/provider/file/export_test.go +++ b/internal/provider/file/export_test.go @@ -23,7 +23,9 @@ package file import "encoding/json" // SetMarshalJSON overrides the marshal function for testing. -func SetMarshalJSON(fn func(interface{}) ([]byte, error)) { +func SetMarshalJSON( + fn func(interface{}) ([]byte, error), +) { marshalJSON = fn } diff --git a/internal/provider/file/mocks/mocks.go b/internal/provider/file/mocks/mocks.go index 347886e14..cb5fb046c 100644 --- a/internal/provider/file/mocks/mocks.go +++ b/internal/provider/file/mocks/mocks.go @@ -27,12 +27,16 @@ import ( ) // NewPlainMockProvider creates a Mock without defaults. -func NewPlainMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewPlainMockProvider( + ctrl *gomock.Controller, +) *MockProvider { return NewMockProvider(ctrl) } // NewDefaultMockProvider creates a Mock with defaults. -func NewDefaultMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewDefaultMockProvider( + ctrl *gomock.Controller, +) *MockProvider { mock := NewPlainMockProvider(ctrl) mock.EXPECT().Deploy(gomock.Any(), gomock.Any()).Return(&file.DeployResult{ diff --git a/internal/provider/file/support_public_test.go b/internal/provider/file/sha256_public_test.go similarity index 100% rename from internal/provider/file/support_public_test.go rename to internal/provider/file/sha256_public_test.go diff --git a/internal/provider/file/status_public_test.go b/internal/provider/file/status_public_test.go index e6e6e8501..b1631ad9f 100644 --- a/internal/provider/file/status_public_test.go +++ b/internal/provider/file/status_public_test.go @@ -70,12 +70,10 @@ func (suite *StatusPublicTestSuite) TestStatus() { driftedSHA := computeTestSHA256(driftedContent) tests := []struct { - name string - setupMock func() - req file.StatusRequest - want *file.StatusResult - wantErr bool - wantErrMsg string + name string + setupMock func() + req file.StatusRequest + validateFunc func(*file.StatusResult, error) }{ { name: "when file in sync", @@ -99,10 +97,14 @@ func (suite *StatusPublicTestSuite) TestStatus() { req: file.StatusRequest{ Path: "/etc/nginx/nginx.conf", }, - want: &file.StatusResult{ - Path: "/etc/nginx/nginx.conf", - Status: "in-sync", - SHA256: fileSHA, + validateFunc: func(got *file.StatusResult, err error) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(&file.StatusResult{ + Path: "/etc/nginx/nginx.conf", + Status: "in-sync", + SHA256: fileSHA, + }, got) }, }, { @@ -127,10 +129,14 @@ func (suite *StatusPublicTestSuite) TestStatus() { req: file.StatusRequest{ Path: "/etc/nginx/nginx.conf", }, - want: &file.StatusResult{ - Path: "/etc/nginx/nginx.conf", - Status: "drifted", - SHA256: driftedSHA, + validateFunc: func(got *file.StatusResult, err error) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(&file.StatusResult{ + Path: "/etc/nginx/nginx.conf", + Status: "drifted", + SHA256: driftedSHA, + }, got) }, }, { @@ -152,9 +158,13 @@ func (suite *StatusPublicTestSuite) TestStatus() { req: file.StatusRequest{ Path: "/etc/nginx/nginx.conf", }, - want: &file.StatusResult{ - Path: "/etc/nginx/nginx.conf", - Status: "missing", + validateFunc: func(got *file.StatusResult, err error) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(&file.StatusResult{ + Path: "/etc/nginx/nginx.conf", + Status: "missing", + }, got) }, }, { @@ -170,8 +180,11 @@ func (suite *StatusPublicTestSuite) TestStatus() { req: file.StatusRequest{ Path: "/etc/nginx/nginx.conf", }, - wantErr: true, - wantErrMsg: "failed to parse file state", + validateFunc: func(got *file.StatusResult, err error) { + suite.Error(err) + suite.ErrorContains(err, "failed to parse file state") + suite.Nil(got) + }, }, { name: "when no state entry", @@ -183,9 +196,13 @@ func (suite *StatusPublicTestSuite) TestStatus() { req: file.StatusRequest{ Path: "/etc/nginx/nginx.conf", }, - want: &file.StatusResult{ - Path: "/etc/nginx/nginx.conf", - Status: "missing", + validateFunc: func(got *file.StatusResult, err error) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(&file.StatusResult{ + Path: "/etc/nginx/nginx.conf", + Status: "missing", + }, got) }, }, } @@ -207,23 +224,15 @@ func (suite *StatusPublicTestSuite) TestStatus() { "test-host", ) - got, err := provider.Status(suite.ctx, tc.req) - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrMsg) - suite.Nil(got) - } else { - suite.NoError(err) - suite.Require().NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(provider.Status(suite.ctx, tc.req)) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestStatusPublicTestSuite(t *testing.T) { +func TestStatusPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(StatusPublicTestSuite)) } diff --git a/internal/provider/file/template_public_test.go b/internal/provider/file/template_public_test.go index 78d46eb8c..c8a1a58c6 100644 --- a/internal/provider/file/template_public_test.go +++ b/internal/provider/file/template_public_test.go @@ -54,38 +54,60 @@ func (suite *TemplatePublicTestSuite) TearDownTest() {} func (suite *TemplatePublicTestSuite) TestDeployTemplate() { tests := []struct { - name string - template string - vars map[string]any - factsFn provider.FactsFunc - hostname string - wantContent string - wantErr bool - wantErrMsg string - wantChanged bool + name string + template string + vars map[string]any + factsFn provider.FactsFunc + hostname string + wantErr bool + validateFunc func(*file.DeployResult, error, avfs.VFS) }{ { - name: "when simple var substitution", - template: "server {{ .Vars.host }}", - vars: map[string]any{"host": "10.0.0.1"}, - hostname: "web-01", - wantContent: "server 10.0.0.1", - wantChanged: true, + name: "when simple var substitution", + template: "server {{ .Vars.host }}", + vars: map[string]any{"host": "10.0.0.1"}, + hostname: "web-01", + validateFunc: func(got *file.DeployResult, err error, appFs avfs.VFS) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(true, got.Changed) + suite.Equal("/etc/test.conf", got.Path) + + data, readErr := appFs.ReadFile("/etc/test.conf") + suite.Require().NoError(readErr) + suite.Equal("server 10.0.0.1", string(data)) + }, }, { - name: "when hostname", - template: "# {{ .Hostname }}", - hostname: "web-01", - wantContent: "# web-01", - wantChanged: true, + name: "when hostname", + template: "# {{ .Hostname }}", + hostname: "web-01", + validateFunc: func(got *file.DeployResult, err error, appFs avfs.VFS) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(true, got.Changed) + suite.Equal("/etc/test.conf", got.Path) + + data, readErr := appFs.ReadFile("/etc/test.conf") + suite.Require().NoError(readErr) + suite.Equal("# web-01", string(data)) + }, }, { - name: "when conditional with vars", - template: `{{ if eq .Vars.env "prod" }}production{{ else }}dev{{ end }}`, - vars: map[string]any{"env": "prod"}, - hostname: "web-01", - wantContent: "production", - wantChanged: true, + name: "when conditional with vars", + template: `{{ if eq .Vars.env "prod" }}production{{ else }}dev{{ end }}`, + vars: map[string]any{"env": "prod"}, + hostname: "web-01", + validateFunc: func(got *file.DeployResult, err error, appFs avfs.VFS) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(true, got.Changed) + suite.Equal("/etc/test.conf", got.Path) + + data, readErr := appFs.ReadFile("/etc/test.conf") + suite.Require().NoError(readErr) + suite.Equal("production", string(data)) + }, }, { name: "when facts available", @@ -93,47 +115,83 @@ func (suite *TemplatePublicTestSuite) TestDeployTemplate() { factsFn: func() map[string]any { return map[string]any{"architecture": "amd64"} }, - hostname: "web-01", - wantContent: "arch: amd64", - wantChanged: true, + hostname: "web-01", + validateFunc: func(got *file.DeployResult, err error, appFs avfs.VFS) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(true, got.Changed) + suite.Equal("/etc/test.conf", got.Path) + + data, readErr := appFs.ReadFile("/etc/test.conf") + suite.Require().NoError(readErr) + suite.Equal("arch: amd64", string(data)) + }, }, { - name: "when nil facts", - template: "{{ .Hostname }}", - factsFn: nil, - hostname: "web-01", - wantContent: "web-01", - wantChanged: true, + name: "when nil facts", + template: "{{ .Hostname }}", + factsFn: nil, + hostname: "web-01", + validateFunc: func(got *file.DeployResult, err error, appFs avfs.VFS) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(true, got.Changed) + suite.Equal("/etc/test.conf", got.Path) + + data, readErr := appFs.ReadFile("/etc/test.conf") + suite.Require().NoError(readErr) + suite.Equal("web-01", string(data)) + }, }, { - name: "when nil vars", - template: "{{ .Hostname }}", - vars: nil, - hostname: "web-01", - wantContent: "web-01", - wantChanged: true, + name: "when nil vars", + template: "{{ .Hostname }}", + vars: nil, + hostname: "web-01", + validateFunc: func(got *file.DeployResult, err error, appFs avfs.VFS) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(true, got.Changed) + suite.Equal("/etc/test.conf", got.Path) + + data, readErr := appFs.ReadFile("/etc/test.conf") + suite.Require().NoError(readErr) + suite.Equal("web-01", string(data)) + }, }, { - name: "when template execution fails", - template: "{{ call .Hostname }}", - hostname: "web-01", - wantErr: true, - wantErrMsg: "failed to render template", + name: "when template execution fails", + template: "{{ call .Hostname }}", + hostname: "web-01", + wantErr: true, + validateFunc: func(got *file.DeployResult, err error, _ avfs.VFS) { + suite.Error(err) + suite.ErrorContains(err, "failed to render template") + suite.Nil(got) + }, }, { - name: "when invalid template syntax", - template: "{{ .Invalid", - hostname: "web-01", - wantErr: true, - wantErrMsg: "failed to render template", + name: "when invalid template syntax", + template: "{{ .Invalid", + hostname: "web-01", + wantErr: true, + validateFunc: func(got *file.DeployResult, err error, _ avfs.VFS) { + suite.Error(err) + suite.ErrorContains(err, "failed to render template") + suite.Nil(got) + }, }, { - name: "when missing var key returns error", - template: "val={{ .Vars.missing }}", - vars: map[string]any{}, - hostname: "web-01", - wantErr: true, - wantErrMsg: "failed to render template", + name: "when missing var key returns error", + template: "val={{ .Vars.missing }}", + vars: map[string]any{}, + hostname: "web-01", + wantErr: true, + validateFunc: func(got *file.DeployResult, err error, _ avfs.VFS) { + suite.Error(err) + suite.ErrorContains(err, "failed to render template") + suite.Nil(got) + }, }, { name: "when missing fact key via index renders no value", @@ -141,44 +199,84 @@ func (suite *TemplatePublicTestSuite) TestDeployTemplate() { factsFn: func() map[string]any { return map[string]any{"architecture": "amd64"} }, - hostname: "web-01", - wantContent: "os=", - wantChanged: true, + hostname: "web-01", + validateFunc: func(got *file.DeployResult, err error, appFs avfs.VFS) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(true, got.Changed) + suite.Equal("/etc/test.conf", got.Path) + + data, readErr := appFs.ReadFile("/etc/test.conf") + suite.Require().NoError(readErr) + suite.Equal("os=", string(data)) + }, }, { - name: "when multiple vars", - template: "{{ .Vars.host }}:{{ .Vars.port }}", - vars: map[string]any{"host": "10.0.0.1", "port": "8080"}, - hostname: "web-01", - wantContent: "10.0.0.1:8080", - wantChanged: true, + name: "when multiple vars", + template: "{{ .Vars.host }}:{{ .Vars.port }}", + vars: map[string]any{"host": "10.0.0.1", "port": "8080"}, + hostname: "web-01", + validateFunc: func(got *file.DeployResult, err error, appFs avfs.VFS) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(true, got.Changed) + suite.Equal("/etc/test.conf", got.Path) + + data, readErr := appFs.ReadFile("/etc/test.conf") + suite.Require().NoError(readErr) + suite.Equal("10.0.0.1:8080", string(data)) + }, }, { name: "when facts and vars combined", template: `host={{ .Hostname }} arch={{ index .Facts "architecture" }} env={{ .Vars.env }}`, + vars: map[string]any{"env": "staging"}, factsFn: func() map[string]any { return map[string]any{"architecture": "arm64"} }, - vars: map[string]any{"env": "staging"}, - hostname: "web-02", - wantContent: "host=web-02 arch=arm64 env=staging", - wantChanged: true, + hostname: "web-02", + validateFunc: func(got *file.DeployResult, err error, appFs avfs.VFS) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(true, got.Changed) + suite.Equal("/etc/test.conf", got.Path) + + data, readErr := appFs.ReadFile("/etc/test.conf") + suite.Require().NoError(readErr) + suite.Equal("host=web-02 arch=arm64 env=staging", string(data)) + }, }, { - name: "when conditional false branch", - template: `{{ if eq .Vars.env "prod" }}production{{ else }}dev{{ end }}`, - vars: map[string]any{"env": "dev"}, - hostname: "web-01", - wantContent: "dev", - wantChanged: true, + name: "when conditional false branch", + template: `{{ if eq .Vars.env "prod" }}production{{ else }}dev{{ end }}`, + vars: map[string]any{"env": "dev"}, + hostname: "web-01", + validateFunc: func(got *file.DeployResult, err error, appFs avfs.VFS) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(true, got.Changed) + suite.Equal("/etc/test.conf", got.Path) + + data, readErr := appFs.ReadFile("/etc/test.conf") + suite.Require().NoError(readErr) + suite.Equal("dev", string(data)) + }, }, { - name: "when range over vars slice", - template: `{{ range .Vars.servers }}{{ . }} {{ end }}`, - vars: map[string]any{"servers": []any{"a", "b", "c"}}, - hostname: "web-01", - wantContent: "a b c ", - wantChanged: true, + name: "when range over vars slice", + template: `{{ range .Vars.servers }}{{ . }} {{ end }}`, + vars: map[string]any{"servers": []any{"a", "b", "c"}}, + hostname: "web-01", + validateFunc: func(got *file.DeployResult, err error, appFs avfs.VFS) { + suite.NoError(err) + suite.Require().NotNil(got) + suite.Equal(true, got.Changed) + suite.Equal("/etc/test.conf", got.Path) + + data, readErr := appFs.ReadFile("/etc/test.conf") + suite.Require().NoError(readErr) + suite.Equal("a b c ", string(data)) + }, }, } @@ -223,26 +321,15 @@ func (suite *TemplatePublicTestSuite) TestDeployTemplate() { Vars: tc.vars, }) - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrMsg) - suite.Nil(got) - } else { - suite.NoError(err) - suite.Require().NotNil(got) - suite.Equal(tc.wantChanged, got.Changed) - suite.Equal("/etc/test.conf", got.Path) - - data, readErr := appFs.ReadFile("/etc/test.conf") - suite.Require().NoError(readErr) - suite.Equal(tc.wantContent, string(data)) - } + tc.validateFunc(got, err, appFs) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestTemplatePublicTestSuite(t *testing.T) { +func TestTemplatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(TemplatePublicTestSuite)) } diff --git a/internal/provider/file/undeploy_public_test.go b/internal/provider/file/undeploy_public_test.go index d7746b738..6021c748e 100644 --- a/internal/provider/file/undeploy_public_test.go +++ b/internal/provider/file/undeploy_public_test.go @@ -280,6 +280,8 @@ func (suite *UndeployPublicTestSuite) TestUndeploy() { } } -func TestUndeployPublicTestSuite(t *testing.T) { +func TestUndeployPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(UndeployPublicTestSuite)) } diff --git a/internal/provider/network/netinfo/darwin_get_routes_public_test.go b/internal/provider/network/netinfo/darwin_get_routes_public_test.go index 7dcc7d57d..29589872e 100644 --- a/internal/provider/network/netinfo/darwin_get_routes_public_test.go +++ b/internal/provider/network/netinfo/darwin_get_routes_public_test.go @@ -386,6 +386,8 @@ func (suite *GetRoutesDarwinPublicTestSuite) TestNewDarwinProvider() { } } -func TestGetRoutesDarwinPublicTestSuite(t *testing.T) { +func TestGetRoutesDarwinPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(GetRoutesDarwinPublicTestSuite)) } diff --git a/internal/provider/network/netinfo/linux_get_routes_public_test.go b/internal/provider/network/netinfo/linux_get_routes_public_test.go index 706830c97..5bc4d2306 100644 --- a/internal/provider/network/netinfo/linux_get_routes_public_test.go +++ b/internal/provider/network/netinfo/linux_get_routes_public_test.go @@ -243,6 +243,8 @@ func (suite *GetRoutesPublicTestSuite) TestGetPrimaryInterface() { } } -func TestGetRoutesPublicTestSuite(t *testing.T) { +func TestGetRoutesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(GetRoutesPublicTestSuite)) } diff --git a/internal/provider/network/netinfo/mocks/mocks.go b/internal/provider/network/netinfo/mocks/mocks.go index 2c2ac1ef2..265036cca 100644 --- a/internal/provider/network/netinfo/mocks/mocks.go +++ b/internal/provider/network/netinfo/mocks/mocks.go @@ -27,12 +27,16 @@ import ( ) // NewPlainMockProvider creates a Mock without defaults. -func NewPlainMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewPlainMockProvider( + ctrl *gomock.Controller, +) *MockProvider { return NewMockProvider(ctrl) } // NewDefaultMockProvider creates a Mock with defaults. -func NewDefaultMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewDefaultMockProvider( + ctrl *gomock.Controller, +) *MockProvider { mock := NewMockProvider(ctrl) mock.EXPECT().GetInterfaces().Return([]netinfo.InterfaceResult{ diff --git a/internal/provider/network/netinfo/netinfo_public_test.go b/internal/provider/network/netinfo/netinfo_public_test.go index 088f4b60e..a5bc85490 100644 --- a/internal/provider/network/netinfo/netinfo_public_test.go +++ b/internal/provider/network/netinfo/netinfo_public_test.go @@ -310,6 +310,8 @@ func (suite *GetInterfacesPublicTestSuite) TestGetInterfaces() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestGetInterfacesPublicTestSuite(t *testing.T) { +func TestGetInterfacesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(GetInterfacesPublicTestSuite)) } diff --git a/internal/provider/network/netplan/dns/darwin.go b/internal/provider/network/netplan/dns/darwin.go index a9d720e8d..31e20a02f 100644 --- a/internal/provider/network/netplan/dns/darwin.go +++ b/internal/provider/network/netplan/dns/darwin.go @@ -1,5 +1,5 @@ // Copyright (c) 2026 John Dewey -// + // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the diff --git a/internal/provider/network/netplan/dns/darwin_get_by_interface_resolv_conf.go b/internal/provider/network/netplan/dns/darwin_get_by_interface_resolv_conf.go index f7edc7a0b..49c3ffd63 100644 --- a/internal/provider/network/netplan/dns/darwin_get_by_interface_resolv_conf.go +++ b/internal/provider/network/netplan/dns/darwin_get_by_interface_resolv_conf.go @@ -1,5 +1,5 @@ // Copyright (c) 2026 John Dewey -// + // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the diff --git a/internal/provider/network/netplan/dns/darwin_get_by_interface_resolv_conf_public_test.go b/internal/provider/network/netplan/dns/darwin_get_by_interface_resolv_conf_public_test.go index d407cb521..29ebe7aab 100644 --- a/internal/provider/network/netplan/dns/darwin_get_by_interface_resolv_conf_public_test.go +++ b/internal/provider/network/netplan/dns/darwin_get_by_interface_resolv_conf_public_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2026 John Dewey -// + // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the @@ -21,7 +21,6 @@ package dns_test import ( - "fmt" "log/slog" "os" "testing" @@ -60,9 +59,7 @@ func (suite *DarwinGetResolvConfByInterfacePublicTestSuite) TestGetResolvConfByI name string setupMock func() *execMocks.MockManager interfaceName string - want *dns.GetResult - wantErr bool - wantErrType error + validateFunc func(any, error) }{ { name: "when matching interface found", @@ -90,9 +87,12 @@ resolver #2 return mock }, interfaceName: "en0", - want: &dns.GetResult{ - DNSServers: []string{"192.168.1.1", "8.8.8.8"}, - SearchDomains: []string{"example.com", "local.lan"}, + validateFunc: func(got any, err error) { + suite.NoError(err) + suite.Equal(&dns.GetResult{ + DNSServers: []string{"192.168.1.1", "8.8.8.8"}, + SearchDomains: []string{"example.com", "local.lan"}, + }, got) }, }, { @@ -118,8 +118,10 @@ resolver #2 return mock }, interfaceName: "en5", - wantErr: true, - wantErrType: fmt.Errorf("does not exist"), + validateFunc: func(_ any, err error) { + suite.Error(err) + suite.Contains(err.Error(), "does not exist") + }, }, { name: "when scutil command errors", @@ -133,8 +135,10 @@ resolver #2 return mock }, interfaceName: "en0", - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(_ any, err error) { + suite.Error(err) + suite.Contains(err.Error(), assert.AnError.Error()) + }, }, { name: "when no nameservers in output", @@ -154,8 +158,10 @@ resolver #1 return mock }, interfaceName: "en0", - wantErr: true, - wantErrType: fmt.Errorf("no resolver blocks found"), + validateFunc: func(_ any, err error) { + suite.Error(err) + suite.Contains(err.Error(), "no resolver blocks found") + }, }, { name: "when empty output", @@ -169,8 +175,10 @@ resolver #1 return mock }, interfaceName: "en0", - wantErr: true, - wantErrType: fmt.Errorf("no resolver blocks found"), + validateFunc: func(_ any, err error) { + suite.Error(err) + suite.Contains(err.Error(), "no resolver blocks found") + }, }, { name: "when resolver has no search domains", @@ -191,8 +199,11 @@ resolver #1 return mock }, interfaceName: "en0", - want: &dns.GetResult{ - DNSServers: []string{"8.8.8.8", "8.8.4.4"}, + validateFunc: func(got any, err error) { + suite.NoError(err) + suite.Equal(&dns.GetResult{ + DNSServers: []string{"8.8.8.8", "8.8.4.4"}, + }, got) }, }, } @@ -202,21 +213,15 @@ resolver #1 mock := tc.setupMock() darwin := dns.NewDarwinProvider(suite.logger, mock) - got, err := darwin.GetResolvConfByInterface(tc.interfaceName) - - if !tc.wantErr { - suite.NoError(err) - suite.Equal(tc.want, got) - } else { - suite.Error(err) - suite.Contains(err.Error(), tc.wantErrType.Error()) - } + tc.validateFunc(darwin.GetResolvConfByInterface(tc.interfaceName)) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetResolvConfByInterfacePublicTestSuite(t *testing.T) { +func TestDarwinGetResolvConfByInterfacePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetResolvConfByInterfacePublicTestSuite)) } diff --git a/internal/provider/network/netplan/dns/darwin_update_resolv_conf_by_interface.go b/internal/provider/network/netplan/dns/darwin_update_resolv_conf_by_interface.go index 87cfb527d..a4ea4c26c 100644 --- a/internal/provider/network/netplan/dns/darwin_update_resolv_conf_by_interface.go +++ b/internal/provider/network/netplan/dns/darwin_update_resolv_conf_by_interface.go @@ -1,5 +1,5 @@ // Copyright (c) 2026 John Dewey -// + // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the diff --git a/internal/provider/network/netplan/dns/darwin_update_resolv_conf_by_interface_public_test.go b/internal/provider/network/netplan/dns/darwin_update_resolv_conf_by_interface_public_test.go index 88cc42a07..baddf8157 100644 --- a/internal/provider/network/netplan/dns/darwin_update_resolv_conf_by_interface_public_test.go +++ b/internal/provider/network/netplan/dns/darwin_update_resolv_conf_by_interface_public_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2026 John Dewey -// + // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the @@ -56,10 +56,16 @@ func (suite *DarwinUpdateResolvConfByInterfacePublicTestSuite) TearDownTest() { func (suite *DarwinUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvConfByInterface() { tests := []struct { - name string + name string + validateFunc func(*dns.UpdateResult, error) }{ { name: "returns ErrUnsupported on Darwin", + validateFunc: func(result *dns.UpdateResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -68,26 +74,28 @@ func (suite *DarwinUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC mock := execMocks.NewPlainMockManager(suite.ctrl) darwin := dns.NewDarwinProvider(suite.logger, mock) - result, err := darwin.UpdateResolvConfByInterface( + tt.validateFunc(darwin.UpdateResolvConfByInterface( []string{"8.8.8.8"}, []string{"example.com"}, "en0", false, - ) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *DarwinUpdateResolvConfByInterfacePublicTestSuite) TestDeleteNetplanConfig() { tests := []struct { - name string + name string + validateFunc func(bool, error) }{ { name: "returns ErrUnsupported on Darwin", + validateFunc: func(result bool, err error) { + suite.Error(err) + suite.False(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -96,15 +104,13 @@ func (suite *DarwinUpdateResolvConfByInterfacePublicTestSuite) TestDeleteNetplan mock := execMocks.NewPlainMockManager(suite.ctrl) darwin := dns.NewDarwinProvider(suite.logger, mock) - changed, err := darwin.DeleteNetplanConfig("eth0") - - suite.Error(err) - suite.False(changed) - suite.ErrorIs(err, provider.ErrUnsupported) + tt.validateFunc(darwin.DeleteNetplanConfig("eth0")) }) } } -func TestDarwinUpdateResolvConfByInterfacePublicTestSuite(t *testing.T) { +func TestDarwinUpdateResolvConfByInterfacePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinUpdateResolvConfByInterfacePublicTestSuite)) } diff --git a/internal/provider/network/netplan/dns/debian_docker_public_test.go b/internal/provider/network/netplan/dns/debian_docker_public_test.go index db902cb42..9b3368ad6 100644 --- a/internal/provider/network/netplan/dns/debian_docker_public_test.go +++ b/internal/provider/network/netplan/dns/debian_docker_public_test.go @@ -57,9 +57,7 @@ func (s *DebianDockerPublicTestSuite) TestGetResolvConfByInterface() { setupFS func(fs avfs.VFS) overrideFS func() avfs.VFS interfaceName string - want *dns.GetResult - wantErr bool - errContains string + validateFunc func(*dns.GetResult, error) }{ { name: "when resolv.conf has servers search domains and noise", @@ -76,9 +74,12 @@ func (s *DebianDockerPublicTestSuite) TestGetResolvConfByInterface() { ), 0o644) }, interfaceName: "eth0", - want: &dns.GetResult{ - DNSServers: []string{"127.0.0.11", "8.8.8.8"}, - SearchDomains: []string{"example.com", "local.lan"}, + validateFunc: func(got *dns.GetResult, err error) { + s.NoError(err) + s.Equal(&dns.GetResult{ + DNSServers: []string{"127.0.0.11", "8.8.8.8"}, + SearchDomains: []string{"example.com", "local.lan"}, + }, got) }, }, { @@ -90,9 +91,12 @@ func (s *DebianDockerPublicTestSuite) TestGetResolvConfByInterface() { ), 0o644) }, interfaceName: "eth0", - want: &dns.GetResult{ - DNSServers: []string{"8.8.8.8"}, - SearchDomains: []string{"."}, + validateFunc: func(got *dns.GetResult, err error) { + s.NoError(err) + s.Equal(&dns.GetResult{ + DNSServers: []string{"8.8.8.8"}, + SearchDomains: []string{"."}, + }, got) }, }, { @@ -106,9 +110,12 @@ func (s *DebianDockerPublicTestSuite) TestGetResolvConfByInterface() { ), 0o644) }, interfaceName: "eth0", - want: &dns.GetResult{ - DNSServers: []string{"8.8.8.8"}, - SearchDomains: []string{"second.com", "third.com"}, + validateFunc: func(got *dns.GetResult, err error) { + s.NoError(err) + s.Equal(&dns.GetResult{ + DNSServers: []string{"8.8.8.8"}, + SearchDomains: []string{"second.com", "third.com"}, + }, got) }, }, { @@ -117,8 +124,10 @@ func (s *DebianDockerPublicTestSuite) TestGetResolvConfByInterface() { // Don't create the file }, interfaceName: "eth0", - wantErr: true, - errContains: "failed to read /etc/resolv.conf", + validateFunc: func(_ *dns.GetResult, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to read /etc/resolv.conf") + }, }, { name: "when read error during scan", @@ -144,8 +153,10 @@ func (s *DebianDockerPublicTestSuite) TestGetResolvConfByInterface() { return ffs }, interfaceName: "eth0", - wantErr: true, - errContains: "failed to parse /etc/resolv.conf", + validateFunc: func(_ *dns.GetResult, err error) { + s.Error(err) + s.Contains(err.Error(), "failed to parse /etc/resolv.conf") + }, }, } @@ -159,66 +170,64 @@ func (s *DebianDockerPublicTestSuite) TestGetResolvConfByInterface() { } p := dns.NewDebianDockerProvider(s.logger, fs) - got, err := p.GetResolvConfByInterface(tc.interfaceName) - - if tc.wantErr { - s.Error(err) - s.Contains(err.Error(), tc.errContains) - } else { - s.NoError(err) - s.Equal(tc.want, got) - } + tc.validateFunc(p.GetResolvConfByInterface(tc.interfaceName)) }) } } func (s *DebianDockerPublicTestSuite) TestUpdateResolvConfByInterface() { tests := []struct { - name string + name string + validateFunc func(*dns.UpdateResult, error) }{ { name: "returns ErrUnsupported for container", + validateFunc: func(result *dns.UpdateResult, err error) { + s.Error(err) + s.Nil(result) + s.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { p := dns.NewDebianDockerProvider(s.logger, s.fs) - result, err := p.UpdateResolvConfByInterface( + tt.validateFunc(p.UpdateResolvConfByInterface( []string{"8.8.8.8"}, []string{"example.com"}, "eth0", false, - ) - - s.Error(err) - s.Nil(result) - s.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (s *DebianDockerPublicTestSuite) TestDeleteNetplanConfig() { tests := []struct { - name string + name string + validateFunc func(bool, error) }{ { name: "returns ErrUnsupported for container", + validateFunc: func(result bool, err error) { + s.Error(err) + s.False(result) + s.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { p := dns.NewDebianDockerProvider(s.logger, s.fs) - changed, err := p.DeleteNetplanConfig("eth0") - - s.Error(err) - s.False(changed) - s.ErrorIs(err, provider.ErrUnsupported) + tt.validateFunc(p.DeleteNetplanConfig("eth0")) }) } } -func TestDebianDockerPublicTestSuite(t *testing.T) { +func TestDebianDockerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianDockerPublicTestSuite)) } diff --git a/internal/provider/network/netplan/dns/debian_get_resolv_conf_by_interface_public_test.go b/internal/provider/network/netplan/dns/debian_get_resolv_conf_by_interface_public_test.go index e197018ae..c7a102203 100644 --- a/internal/provider/network/netplan/dns/debian_get_resolv_conf_by_interface_public_test.go +++ b/internal/provider/network/netplan/dns/debian_get_resolv_conf_by_interface_public_test.go @@ -61,9 +61,7 @@ func (suite *DebianGetResolvConfPublicTestSuite) TestGetResolvConfByInterface() name string setupMock func() *mocks.MockManager interfaceName string - want *dns.GetResult - wantErr bool - wantErrType error + validateFunc func(any, error) }{ { name: "when GetResolvConf Ok", @@ -73,20 +71,22 @@ func (suite *DebianGetResolvConfPublicTestSuite) TestGetResolvConfByInterface() return mock }, interfaceName: "wlp0s20f3", - want: &dns.GetResult{ - DNSServers: []string{ - "192.168.1.1", - "8.8.8.8", - "8.8.4.4", - "2001:4860:4860::8888", - "2001:4860:4860::8844", - }, - SearchDomains: []string{ - "example.com", - "local.lan", - }, + validateFunc: func(got any, err error) { + suite.NoError(err) + suite.Equal(&dns.GetResult{ + DNSServers: []string{ + "192.168.1.1", + "8.8.8.8", + "8.8.4.4", + "2001:4860:4860::8888", + "2001:4860:4860::8844", + }, + SearchDomains: []string{ + "example.com", + "local.lan", + }, + }, got) }, - wantErr: false, }, { name: "when default DNS Domain", @@ -96,19 +96,21 @@ func (suite *DebianGetResolvConfPublicTestSuite) TestGetResolvConfByInterface() return mock }, interfaceName: "wlp0s20f3", - want: &dns.GetResult{ - DNSServers: []string{ - "192.168.1.1", - "8.8.8.8", - "8.8.4.4", - "2001:4860:4860::8888", - "2001:4860:4860::8844", - }, - SearchDomains: []string{ - ".", - }, + validateFunc: func(got any, err error) { + suite.NoError(err) + suite.Equal(&dns.GetResult{ + DNSServers: []string{ + "192.168.1.1", + "8.8.8.8", + "8.8.4.4", + "2001:4860:4860::8888", + "2001:4860:4860::8844", + }, + SearchDomains: []string{ + ".", + }, + }, got) }, - wantErr: false, }, { name: "when Interface Name is invalid", @@ -124,8 +126,13 @@ func (suite *DebianGetResolvConfPublicTestSuite) TestGetResolvConfByInterface() return mock }, interfaceName: "eth!", - wantErr: true, - wantErrType: fmt.Errorf("interface %q does not exist", "eth!"), + validateFunc: func(_ any, err error) { + suite.Error(err) + suite.Contains( + err.Error(), + fmt.Errorf("interface %q does not exist", "eth!").Error(), + ) + }, }, { name: "when exec.RunCmd errors", @@ -140,8 +147,10 @@ func (suite *DebianGetResolvConfPublicTestSuite) TestGetResolvConfByInterface() return mock }, interfaceName: "wlp0s20f3", - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(_ any, err error) { + suite.Error(err) + suite.Contains(err.Error(), assert.AnError.Error()) + }, }, } @@ -150,21 +159,15 @@ func (suite *DebianGetResolvConfPublicTestSuite) TestGetResolvConfByInterface() mock := tc.setupMock() net := dns.NewDebianProvider(suite.logger, memfs.New(), nil, mock, "test-host") - got, err := net.GetResolvConfByInterface(tc.interfaceName) - - if !tc.wantErr { - suite.NoError(err) - suite.Equal(tc.want, got) - } else { - suite.Error(err) - suite.Contains(err.Error(), tc.wantErrType.Error()) - } + tc.validateFunc(net.GetResolvConfByInterface(tc.interfaceName)) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetResolvConfPublicTestSuite(t *testing.T) { +func TestDebianGetResolvConfPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetResolvConfPublicTestSuite)) } diff --git a/internal/provider/network/netplan/dns/debian_netplan_public_test.go b/internal/provider/network/netplan/dns/debian_netplan_public_test.go index 212933500..50d7f0149 100644 --- a/internal/provider/network/netplan/dns/debian_netplan_public_test.go +++ b/internal/provider/network/netplan/dns/debian_netplan_public_test.go @@ -179,13 +179,15 @@ func (suite *DebianNetplanPublicTestSuite) TestResolvePrimaryInterface() { name string interfaceName string setupFacts func(p *dns.Debian) - want string + validateFunc func(string) }{ { name: "when explicit interface name is provided", interfaceName: "enp3s0", setupFacts: func(_ *dns.Debian) {}, - want: "enp3s0", + validateFunc: func(got string) { + suite.Equal("enp3s0", got) + }, }, { name: "when empty interface and facts has primary_interface", @@ -197,13 +199,17 @@ func (suite *DebianNetplanPublicTestSuite) TestResolvePrimaryInterface() { } }) }, - want: "ens3", + validateFunc: func(got string) { + suite.Equal("ens3", got) + }, }, { name: "when empty interface and no facts", interfaceName: "", setupFacts: func(_ *dns.Debian) {}, - want: "eth0", + validateFunc: func(got string) { + suite.Equal("eth0", got) + }, }, } @@ -217,13 +223,15 @@ func (suite *DebianNetplanPublicTestSuite) TestResolvePrimaryInterface() { got := p.ExportResolvePrimaryInterface(tc.interfaceName) - suite.Equal(tc.want, got) + tc.validateFunc(got) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianNetplanPublicTestSuite(t *testing.T) { +func TestDebianNetplanPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianNetplanPublicTestSuite)) } diff --git a/internal/provider/network/netplan/dns/debian_update_resolv_conf_by_interface_public_test.go b/internal/provider/network/netplan/dns/debian_update_resolv_conf_by_interface_public_test.go index fb0523c98..3ad8caf66 100644 --- a/internal/provider/network/netplan/dns/debian_update_resolv_conf_by_interface_public_test.go +++ b/internal/provider/network/netplan/dns/debian_update_resolv_conf_by_interface_public_test.go @@ -65,9 +65,7 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC servers []string searchDomains []string interfaceName string - wantChanged bool - wantErr bool - wantErrMsg string + validateFunc func(*dns.UpdateResult, error) }{ { name: "when SetResolvConf Ok", @@ -87,7 +85,6 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC return mock, kv }, - interfaceName: "wlp0s20f3", servers: []string{ "8.8.8.8", "9.9.9.9", @@ -96,8 +93,12 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC "foo.local", "bar.local", }, - wantChanged: true, - wantErr: false, + interfaceName: "wlp0s20f3", + validateFunc: func(result *dns.UpdateResult, err error) { + suite.NoError(err) + suite.NotNil(result) + suite.Equal(true, result.Changed) + }, }, { name: "when SetResolvConf preserves existing servers Ok", @@ -115,13 +116,16 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC return mock, kv }, - interfaceName: "wlp0s20f3", searchDomains: []string{ "foo.local", "bar.local", }, - wantChanged: true, - wantErr: false, + interfaceName: "wlp0s20f3", + validateFunc: func(result *dns.UpdateResult, err error) { + suite.NoError(err) + suite.NotNil(result) + suite.Equal(true, result.Changed) + }, }, { name: "when SetResolvConf preserves existing search domains Ok", @@ -139,13 +143,16 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC return mock, kv }, - interfaceName: "wlp0s20f3", servers: []string{ "8.8.8.8", "9.9.9.9", }, - wantChanged: true, - wantErr: false, + interfaceName: "wlp0s20f3", + validateFunc: func(result *dns.UpdateResult, err error) { + suite.NoError(err) + suite.NotNil(result) + suite.Equal(true, result.Changed) + }, }, { name: "when SetResolvConf filters root domain Ok", @@ -163,17 +170,19 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC return mock, kv }, - interfaceName: "wlp0s20f3", servers: []string{ "8.8.8.8", "9.9.9.9", }, - wantChanged: true, - wantErr: false, + interfaceName: "wlp0s20f3", + validateFunc: func(result *dns.UpdateResult, err error) { + suite.NoError(err) + suite.NotNil(result) + suite.Equal(true, result.Changed) + }, }, { - name: "when SetResolvConf missing args errors", - wantErr: true, + name: "when SetResolvConf missing args errors", setupMock: func() (*execmocks.MockManager, *jobmocks.MockKeyValue) { mock := execmocks.NewPlainMockManager(suite.ctrl) kv := jobmocks.NewMockKeyValue(suite.ctrl) @@ -181,7 +190,14 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC return mock, kv }, interfaceName: "wlp0s20f3", - wantErrMsg: "no DNS servers or search domains provided; nothing to update", + validateFunc: func(result *dns.UpdateResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.Contains( + err.Error(), + "no DNS servers or search domains provided; nothing to update", + ) + }, }, { name: "when GetResolvConfByInterface errors", @@ -196,7 +212,6 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC return mock, kv }, - interfaceName: "wlp0s20f3", servers: []string{ "8.8.8.8", "9.9.9.9", @@ -205,8 +220,12 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC "foo.local", "bar.local", }, - wantErr: true, - wantErrMsg: assert.AnError.Error(), + interfaceName: "wlp0s20f3", + validateFunc: func(result *dns.UpdateResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.Contains(err.Error(), assert.AnError.Error()) + }, }, { name: "when netplan generate fails", @@ -224,7 +243,6 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC return mock, kv }, - interfaceName: "wlp0s20f3", servers: []string{ "8.8.8.8", "9.9.9.9", @@ -233,8 +251,12 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC "foo.local", "bar.local", }, - wantErr: true, - wantErrMsg: "netplan validate failed (file rolled back)", + interfaceName: "wlp0s20f3", + validateFunc: func(result *dns.UpdateResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.Contains(err.Error(), "netplan validate failed (file rolled back)") + }, }, { name: "when netplan apply fails", @@ -256,7 +278,6 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC return mock, kv }, - interfaceName: "wlp0s20f3", servers: []string{ "8.8.8.8", "9.9.9.9", @@ -265,8 +286,12 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC "foo.local", "bar.local", }, - wantErr: true, - wantErrMsg: "netplan apply:", + interfaceName: "wlp0s20f3", + validateFunc: func(result *dns.UpdateResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.Contains(err.Error(), "netplan apply:") + }, }, { name: "when interface resolved from facts", @@ -286,12 +311,15 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC return mock, kv }, - interfaceName: "", servers: []string{ "8.8.8.8", }, - wantErr: true, - wantErrMsg: "failed to get current resolvectl configuration", + interfaceName: "", + validateFunc: func(result *dns.UpdateResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.Contains(err.Error(), "failed to get current resolvectl configuration") + }, }, } @@ -302,45 +330,25 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvC _ = fs.MkdirAll("/etc/netplan", 0o755) net := dns.NewDebianProvider(suite.logger, fs, kv, mock, "test-host") - result, err := net.UpdateResolvConfByInterface( + tc.validateFunc(net.UpdateResolvConfByInterface( tc.servers, tc.searchDomains, tc.interfaceName, false, - ) - - if tc.wantErr { - suite.Error(err) - suite.Nil(result) - suite.Contains(err.Error(), tc.wantErrMsg) - } else { - suite.NoError(err) - suite.NotNil(result) - suite.Equal(tc.wantChanged, result.Changed) - } + )) }) } } func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestDeleteNetplanConfig() { tests := []struct { - name string - setupMock func() (*execmocks.MockManager, *jobmocks.MockKeyValue) - setupFS func(avfs.VFS) - wantChanged bool - wantErr bool - wantErrMsg string + name string + setupMock func() (*execmocks.MockManager, *jobmocks.MockKeyValue) + setupFS func(avfs.VFS) + validateFunc func(bool, error) }{ { name: "when file exists and remove succeeds", - setupFS: func(fs avfs.VFS) { - _ = fs.MkdirAll("/etc/netplan", 0o755) - _ = fs.WriteFile( - "/etc/netplan/osapi-dns.yaml", - []byte("network:\n version: 2\n"), - 0o600, - ) - }, setupMock: func() (*execmocks.MockManager, *jobmocks.MockKeyValue) { mock := execmocks.NewPlainMockManager(suite.ctrl) kv := jobmocks.NewMockKeyValue(suite.ctrl) @@ -357,31 +365,37 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestDeleteNetplan return mock, kv }, - wantChanged: true, - }, - { - name: "when file does not exist returns not changed", setupFS: func(fs avfs.VFS) { _ = fs.MkdirAll("/etc/netplan", 0o755) + _ = fs.WriteFile( + "/etc/netplan/osapi-dns.yaml", + []byte("network:\n version: 2\n"), + 0o600, + ) + }, + validateFunc: func(changed bool, err error) { + suite.NoError(err) + suite.Equal(true, changed) }, + }, + { + name: "when file does not exist returns not changed", setupMock: func() (*execmocks.MockManager, *jobmocks.MockKeyValue) { mock := execmocks.NewPlainMockManager(suite.ctrl) kv := jobmocks.NewMockKeyValue(suite.ctrl) return mock, kv }, - wantChanged: false, - }, - { - name: "when netplan apply fails", setupFS: func(fs avfs.VFS) { _ = fs.MkdirAll("/etc/netplan", 0o755) - _ = fs.WriteFile( - "/etc/netplan/osapi-dns.yaml", - []byte("network:\n version: 2\n"), - 0o600, - ) }, + validateFunc: func(changed bool, err error) { + suite.NoError(err) + suite.Equal(false, changed) + }, + }, + { + name: "when netplan apply fails", setupMock: func() (*execmocks.MockManager, *jobmocks.MockKeyValue) { mock := execmocks.NewPlainMockManager(suite.ctrl) kv := jobmocks.NewMockKeyValue(suite.ctrl) @@ -392,8 +406,18 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestDeleteNetplan return mock, kv }, - wantErr: true, - wantErrMsg: "dns delete via netplan:", + setupFS: func(fs avfs.VFS) { + _ = fs.MkdirAll("/etc/netplan", 0o755) + _ = fs.WriteFile( + "/etc/netplan/osapi-dns.yaml", + []byte("network:\n version: 2\n"), + 0o600, + ) + }, + validateFunc: func(_ bool, err error) { + suite.Error(err) + suite.Contains(err.Error(), "dns delete via netplan:") + }, }, } @@ -404,21 +428,15 @@ func (suite *DebianUpdateResolvConfByInterfacePublicTestSuite) TestDeleteNetplan tc.setupFS(fs) net := dns.NewDebianProvider(suite.logger, fs, kv, mock, "test-host") - changed, err := net.DeleteNetplanConfig("eth0") - - if tc.wantErr { - suite.Error(err) - suite.Contains(err.Error(), tc.wantErrMsg) - } else { - suite.NoError(err) - suite.Equal(tc.wantChanged, changed) - } + tc.validateFunc(net.DeleteNetplanConfig("eth0")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianUpdateResolvConfByInterfacePublicTestSuite(t *testing.T) { +func TestDebianUpdateResolvConfByInterfacePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianUpdateResolvConfByInterfacePublicTestSuite)) } diff --git a/internal/provider/network/netplan/dns/linux_public_test.go b/internal/provider/network/netplan/dns/linux_public_test.go index b60717c06..d34e3f29a 100644 --- a/internal/provider/network/netplan/dns/linux_public_test.go +++ b/internal/provider/network/netplan/dns/linux_public_test.go @@ -35,51 +35,57 @@ type LinuxPublicTestSuite struct { func (s *LinuxPublicTestSuite) TestGetResolvConfByInterface() { tests := []struct { - name string + name string + validateFunc func(*dns.GetResult, error) }{ { name: "returns error for linux stub", + validateFunc: func(result *dns.GetResult, err error) { + s.Error(err) + s.Nil(result) + s.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { l := &dns.Linux{} - result, err := l.GetResolvConfByInterface("eth0") - - s.Error(err) - s.Nil(result) - s.ErrorIs(err, provider.ErrUnsupported) + tt.validateFunc(l.GetResolvConfByInterface("eth0")) }) } } func (s *LinuxPublicTestSuite) TestUpdateResolvConfByInterface() { tests := []struct { - name string + name string + validateFunc func(*dns.UpdateResult, error) }{ { name: "returns error for linux stub", + validateFunc: func(result *dns.UpdateResult, err error) { + s.Error(err) + s.Nil(result) + s.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { l := &dns.Linux{} - result, err := l.UpdateResolvConfByInterface( + tt.validateFunc(l.UpdateResolvConfByInterface( []string{"8.8.8.8"}, []string{"example.com"}, "eth0", false, - ) - - s.Error(err) - s.Nil(result) - s.ErrorIs(err, provider.ErrUnsupported) + )) }) } } -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxPublicTestSuite)) } diff --git a/internal/provider/network/netplan/dns/linux_update_resolv_conf_by_interface_public_test.go b/internal/provider/network/netplan/dns/linux_update_resolv_conf_by_interface_public_test.go index 3f0d79754..904aa041a 100644 --- a/internal/provider/network/netplan/dns/linux_update_resolv_conf_by_interface_public_test.go +++ b/internal/provider/network/netplan/dns/linux_update_resolv_conf_by_interface_public_test.go @@ -40,10 +40,15 @@ func (suite *LinuxUpdateResolvConfByInterfacePublicTestSuite) TearDownTest() {} func (suite *LinuxUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvConfByInterface() { tests := []struct { - name string + name string + validateFunc func(*dns.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *dns.UpdateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -54,25 +59,27 @@ func (suite *LinuxUpdateResolvConfByInterfacePublicTestSuite) TestUpdateResolvCo servers := []string{} searchDomains := []string{} interfaceName := "" - result, err := linux.UpdateResolvConfByInterface( + tc.validateFunc(linux.UpdateResolvConfByInterface( servers, searchDomains, interfaceName, false, - ) - - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *LinuxUpdateResolvConfByInterfacePublicTestSuite) TestDeleteNetplanConfig() { tests := []struct { - name string + name string + validateFunc func(bool, error) }{ { name: "returns ErrUnsupported on generic Linux", + validateFunc: func(result bool, err error) { + suite.False(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -80,16 +87,15 @@ func (suite *LinuxUpdateResolvConfByInterfacePublicTestSuite) TestDeleteNetplanC suite.Run(tc.name, func() { linux := dns.NewLinuxProvider() - changed, err := linux.DeleteNetplanConfig("eth0") - - suite.False(changed) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.DeleteNetplanConfig("eth0")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxUpdateResolvConfByInterfacePublicTestSuite(t *testing.T) { +func TestLinuxUpdateResolvConfByInterfacePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxUpdateResolvConfByInterfacePublicTestSuite)) } diff --git a/internal/provider/network/netplan/dns/mocks/mocks.go b/internal/provider/network/netplan/dns/mocks/mocks.go index b0c27f39d..704e0b96f 100644 --- a/internal/provider/network/netplan/dns/mocks/mocks.go +++ b/internal/provider/network/netplan/dns/mocks/mocks.go @@ -27,12 +27,16 @@ import ( ) // NewPlainMockProvider creates a Mock without defaults. -func NewPlainMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewPlainMockProvider( + ctrl *gomock.Controller, +) *MockProvider { return NewMockProvider(ctrl) } // NewDefaultMockProvider creates a Mock with defaults. -func NewDefaultMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewDefaultMockProvider( + ctrl *gomock.Controller, +) *MockProvider { mock := NewMockProvider(ctrl) // Set up default expectations for the mock methods diff --git a/internal/provider/network/netplan/export_test.go b/internal/provider/network/netplan/export_test.go index c9a0bec9d..7d595933b 100644 --- a/internal/provider/network/netplan/export_test.go +++ b/internal/provider/network/netplan/export_test.go @@ -23,7 +23,9 @@ package netplan import "encoding/json" // SetMarshalJSON overrides the marshal function for testing. -func SetMarshalJSON(fn func(interface{}) ([]byte, error)) { +func SetMarshalJSON( + fn func(interface{}) ([]byte, error), +) { marshalJSON = fn } diff --git a/internal/provider/network/netplan/iface/darwin_public_test.go b/internal/provider/network/netplan/iface/darwin_public_test.go index 09dac9bc9..b81ca5b07 100644 --- a/internal/provider/network/netplan/iface/darwin_public_test.go +++ b/internal/provider/network/netplan/iface/darwin_public_test.go @@ -42,100 +42,112 @@ func (suite *DarwinPublicTestSuite) SetupTest() { func (suite *DarwinPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]iface.InterfaceEntry, error) }{ { name: "returns not implemented error", + validateFunc: func(result []iface.InterfaceEntry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *DarwinPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*iface.InterfaceEntry, error) }{ { name: "returns not implemented error", + validateFunc: func(result *iface.InterfaceEntry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), "eth0") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), "eth0")) }) } } func (suite *DarwinPublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*iface.InterfaceResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *iface.InterfaceResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create(context.Background(), iface.InterfaceEntry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Create(context.Background(), iface.InterfaceEntry{})) }) } } func (suite *DarwinPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*iface.InterfaceResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *iface.InterfaceResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background(), iface.InterfaceEntry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background(), iface.InterfaceEntry{})) }) } } func (suite *DarwinPublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*iface.InterfaceResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *iface.InterfaceResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background(), "eth0") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background(), "eth0")) }) } } -func TestDarwinPublicTestSuite(t *testing.T) { +func TestDarwinPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(DarwinPublicTestSuite)) diff --git a/internal/provider/network/netplan/iface/export_test.go b/internal/provider/network/netplan/iface/export_test.go index ffda175f3..45c01d743 100644 --- a/internal/provider/network/netplan/iface/export_test.go +++ b/internal/provider/network/netplan/iface/export_test.go @@ -21,6 +21,9 @@ package iface // GenerateInterfaceYAML exposes generateInterfaceYAML for testing. -func GenerateInterfaceYAML(entry InterfaceEntry, ifaceSection string) []byte { +func GenerateInterfaceYAML( + entry InterfaceEntry, + ifaceSection string, +) []byte { return generateInterfaceYAML(entry, ifaceSection) } diff --git a/internal/provider/network/netplan/iface/interface_public_test.go b/internal/provider/network/netplan/iface/interface_public_test.go index a33b697d1..95bebe1e8 100644 --- a/internal/provider/network/netplan/iface/interface_public_test.go +++ b/internal/provider/network/netplan/iface/interface_public_test.go @@ -829,7 +829,9 @@ func (suite *InterfacePublicTestSuite) TestGenerateInterfaceYAML() { } } -func TestInterfacePublicTestSuite(t *testing.T) { +func TestInterfacePublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(InterfacePublicTestSuite)) diff --git a/internal/provider/network/netplan/iface/linux_public_test.go b/internal/provider/network/netplan/iface/linux_public_test.go index 3b0d7c7ee..180a6a7eb 100644 --- a/internal/provider/network/netplan/iface/linux_public_test.go +++ b/internal/provider/network/netplan/iface/linux_public_test.go @@ -42,100 +42,112 @@ func (suite *LinuxPublicTestSuite) SetupTest() { func (suite *LinuxPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]iface.InterfaceEntry, error) }{ { name: "returns not implemented error", + validateFunc: func(result []iface.InterfaceEntry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *LinuxPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*iface.InterfaceEntry, error) }{ { name: "returns not implemented error", + validateFunc: func(result *iface.InterfaceEntry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), "eth0") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), "eth0")) }) } } func (suite *LinuxPublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*iface.InterfaceResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *iface.InterfaceResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create(context.Background(), iface.InterfaceEntry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Create(context.Background(), iface.InterfaceEntry{})) }) } } func (suite *LinuxPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*iface.InterfaceResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *iface.InterfaceResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background(), iface.InterfaceEntry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background(), iface.InterfaceEntry{})) }) } } func (suite *LinuxPublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*iface.InterfaceResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *iface.InterfaceResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background(), "eth0") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background(), "eth0")) }) } } -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(LinuxPublicTestSuite)) diff --git a/internal/provider/network/netplan/netplan_public_test.go b/internal/provider/network/netplan/netplan_public_test.go index 55f0f4cbc..8a3c28954 100644 --- a/internal/provider/network/netplan/netplan_public_test.go +++ b/internal/provider/network/netplan/netplan_public_test.go @@ -572,7 +572,9 @@ func (suite *NetplanPublicTestSuite) TestComputeSHA256() { } } -func TestNetplanPublicTestSuite(t *testing.T) { +func TestNetplanPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(NetplanPublicTestSuite)) diff --git a/internal/provider/network/netplan/route/darwin_public_test.go b/internal/provider/network/netplan/route/darwin_public_test.go index 9ce78f2b7..afba5a698 100644 --- a/internal/provider/network/netplan/route/darwin_public_test.go +++ b/internal/provider/network/netplan/route/darwin_public_test.go @@ -42,100 +42,112 @@ func (suite *DarwinRoutePublicTestSuite) SetupTest() { func (suite *DarwinRoutePublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]route.ListEntry, error) }{ { name: "returns not implemented error", + validateFunc: func(result []route.ListEntry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *DarwinRoutePublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*route.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result *route.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), "eth0") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), "eth0")) }) } } func (suite *DarwinRoutePublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*route.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *route.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create(context.Background(), route.Entry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Create(context.Background(), route.Entry{})) }) } } func (suite *DarwinRoutePublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*route.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *route.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background(), route.Entry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background(), route.Entry{})) }) } } func (suite *DarwinRoutePublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*route.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *route.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background(), "eth0") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background(), "eth0")) }) } } -func TestDarwinRoutePublicTestSuite(t *testing.T) { +func TestDarwinRoutePublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(DarwinRoutePublicTestSuite)) diff --git a/internal/provider/network/netplan/route/export_test.go b/internal/provider/network/netplan/route/export_test.go index 4e2fc32e7..82df2e865 100644 --- a/internal/provider/network/netplan/route/export_test.go +++ b/internal/provider/network/netplan/route/export_test.go @@ -23,7 +23,9 @@ package route import "encoding/json" // SetMarshalJSON overrides the marshal function for testing. -func SetMarshalJSON(fn func(interface{}) ([]byte, error)) { +func SetMarshalJSON( + fn func(interface{}) ([]byte, error), +) { marshalJSON = fn } @@ -33,21 +35,30 @@ func ResetMarshalJSON() { } // GenerateRouteYAML exposes generateRouteYAML for testing. -func GenerateRouteYAML(entry Entry, ifaceSection string) []byte { +func GenerateRouteYAML( + entry Entry, + ifaceSection string, +) []byte { return generateRouteYAML(entry, ifaceSection) } // ContainsDefaultRoute exposes containsDefaultRoute for testing. -func ContainsDefaultRoute(routes []Route) bool { +func ContainsDefaultRoute( + routes []Route, +) bool { return containsDefaultRoute(routes) } // BuildRouteMetadata exposes buildRouteMetadata for testing. -func BuildRouteMetadata(entry Entry) (map[string]string, error) { +func BuildRouteMetadata( + entry Entry, +) (map[string]string, error) { return buildRouteMetadata(entry) } // RouteFilePath exposes routeFilePath for testing. -func RouteFilePath(interfaceName string) string { +func RouteFilePath( + interfaceName string, +) string { return routeFilePath(interfaceName) } diff --git a/internal/provider/network/netplan/route/linux_public_test.go b/internal/provider/network/netplan/route/linux_public_test.go index c62b9e8f7..777d189ef 100644 --- a/internal/provider/network/netplan/route/linux_public_test.go +++ b/internal/provider/network/netplan/route/linux_public_test.go @@ -42,100 +42,112 @@ func (suite *LinuxRoutePublicTestSuite) SetupTest() { func (suite *LinuxRoutePublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]route.ListEntry, error) }{ { name: "returns not implemented error", + validateFunc: func(result []route.ListEntry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *LinuxRoutePublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*route.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result *route.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), "eth0") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), "eth0")) }) } } func (suite *LinuxRoutePublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*route.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *route.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create(context.Background(), route.Entry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Create(context.Background(), route.Entry{})) }) } } func (suite *LinuxRoutePublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*route.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *route.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background(), route.Entry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background(), route.Entry{})) }) } } func (suite *LinuxRoutePublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*route.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *route.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background(), "eth0") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background(), "eth0")) }) } } -func TestLinuxRoutePublicTestSuite(t *testing.T) { +func TestLinuxRoutePublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(LinuxRoutePublicTestSuite)) diff --git a/internal/provider/network/netplan/route/route_public_test.go b/internal/provider/network/netplan/route/route_public_test.go index d316bf39d..c964deb96 100644 --- a/internal/provider/network/netplan/route/route_public_test.go +++ b/internal/provider/network/netplan/route/route_public_test.go @@ -1135,7 +1135,9 @@ func (suite *RoutePublicTestSuite) TestRouteFilePath() { } } -func TestRoutePublicTestSuite(t *testing.T) { +func TestRoutePublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(RoutePublicTestSuite)) diff --git a/internal/provider/network/netplan/status_public_test.go b/internal/provider/network/netplan/status_public_test.go index 37ae5b818..a20c29fc0 100644 --- a/internal/provider/network/netplan/status_public_test.go +++ b/internal/provider/network/netplan/status_public_test.go @@ -698,7 +698,9 @@ func (suite *StatusPublicTestSuite) TestSectionForType() { } } -func TestStatusPublicTestSuite(t *testing.T) { +func TestStatusPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(StatusPublicTestSuite)) diff --git a/internal/provider/network/ping/darwin.go b/internal/provider/network/ping/darwin.go index 081685951..204c14a71 100644 --- a/internal/provider/network/ping/darwin.go +++ b/internal/provider/network/ping/darwin.go @@ -1,5 +1,5 @@ // Copyright (c) 2026 John Dewey -// + // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the diff --git a/internal/provider/network/ping/darwin_do.go b/internal/provider/network/ping/darwin_do.go index 3fd9f046b..5ef7357d8 100644 --- a/internal/provider/network/ping/darwin_do.go +++ b/internal/provider/network/ping/darwin_do.go @@ -1,5 +1,5 @@ // Copyright (c) 2026 John Dewey -// + // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the diff --git a/internal/provider/network/ping/darwin_do_public_test.go b/internal/provider/network/ping/darwin_do_public_test.go index 0945b9074..703ba867e 100644 --- a/internal/provider/network/ping/darwin_do_public_test.go +++ b/internal/provider/network/ping/darwin_do_public_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2026 John Dewey -// + // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the @@ -21,7 +21,6 @@ package ping_test import ( - "fmt" "testing" "time" @@ -54,16 +53,13 @@ func (suite *DarwinDoPublicTestSuite) TearDownTest() { func (suite *DarwinDoPublicTestSuite) TestDo() { tests := []struct { - name string - setupMock func() *mocks.MockPinger - address string - want *ping.Result - wantErr bool - wantErrType error + name string + setupMock func() *mocks.MockPinger + address string + validateFunc func(*ping.Result, error) }{ { - name: "when Do Ok", - address: "1.1.1.1", + name: "when Do Ok", setupMock: func() *mocks.MockPinger { mock := mocks.NewPlainMockPinger(suite.ctrl) @@ -81,28 +77,32 @@ func (suite *DarwinDoPublicTestSuite) TestDo() { return mock }, - want: &ping.Result{ - PacketsSent: 3, - PacketsReceived: 3, - PacketLoss: 0, - MinRTT: 10 * time.Millisecond, - AvgRTT: 15 * time.Millisecond, - MaxRTT: 20 * time.Millisecond, + address: "1.1.1.1", + validateFunc: func(got *ping.Result, err error) { + suite.NoError(err) + suite.Equal(&ping.Result{ + PacketsSent: 3, + PacketsReceived: 3, + PacketLoss: 0, + MinRTT: 10 * time.Millisecond, + AvgRTT: 15 * time.Millisecond, + MaxRTT: 20 * time.Millisecond, + }, got) }, - wantErr: false, }, { - name: "when NewPingerFn errors", - address: "invalid-address", + name: "when NewPingerFn errors", setupMock: func() *mocks.MockPinger { return nil }, - wantErr: true, - wantErrType: fmt.Errorf("failed to initialize pinger"), + address: "invalid-address", + validateFunc: func(_ *ping.Result, err error) { + suite.Error(err) + suite.Contains(err.Error(), "failed to initialize pinger") + }, }, { - name: "when pinger.Run errors", - address: "1.1.1.1", + name: "when pinger.Run errors", setupMock: func() *mocks.MockPinger { mock := mocks.NewPlainMockPinger(suite.ctrl) @@ -112,12 +112,14 @@ func (suite *DarwinDoPublicTestSuite) TestDo() { return mock }, - wantErr: true, - wantErrType: assert.AnError, + address: "1.1.1.1", + validateFunc: func(_ *ping.Result, err error) { + suite.Error(err) + suite.Contains(err.Error(), assert.AnError.Error()) + }, }, { - name: "when ping operation times out", - address: "1.1.1.1", + name: "when ping operation times out", setupMock: func() *mocks.MockPinger { mock := mocks.NewMockPinger(suite.ctrl) @@ -132,8 +134,11 @@ func (suite *DarwinDoPublicTestSuite) TestDo() { return mock }, - wantErr: true, - wantErrType: fmt.Errorf("ping operation timed out after 5s"), + address: "1.1.1.1", + validateFunc: func(_ *ping.Result, err error) { + suite.Error(err) + suite.Contains(err.Error(), "ping operation timed out after 5s") + }, }, } @@ -148,15 +153,7 @@ func (suite *DarwinDoPublicTestSuite) TestDo() { } } - got, err := darwin.Do(tc.address) - - if !tc.wantErr { - suite.NoError(err) - suite.Equal(tc.want, got) - } else { - suite.Error(err) - suite.Contains(err.Error(), tc.wantErrType.Error()) - } + tc.validateFunc(darwin.Do(tc.address)) }) } } @@ -202,6 +199,8 @@ func (suite *DarwinDoPublicTestSuite) TestNewDarwinProvider() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinDoPublicTestSuite(t *testing.T) { +func TestDarwinDoPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinDoPublicTestSuite)) } diff --git a/internal/provider/network/ping/debian_do_public_test.go b/internal/provider/network/ping/debian_do_public_test.go index 7ba7421db..d84690ceb 100644 --- a/internal/provider/network/ping/debian_do_public_test.go +++ b/internal/provider/network/ping/debian_do_public_test.go @@ -21,7 +21,6 @@ package ping_test import ( - "fmt" "testing" "time" @@ -53,43 +52,44 @@ func (suite *DebianDoPublicTestSuite) TearDownTest() { func (suite *DebianDoPublicTestSuite) TestDo() { tests := []struct { - name string - setupMock func() *mocks.MockPinger - address string - want *ping.Result - wantErr bool - wantErrType error + name string + setupMock func() *mocks.MockPinger + address string + validateFunc func(*ping.Result, error) }{ { - name: "when Do Ok", - address: "1.1.1.1", + name: "when Do Ok", setupMock: func() *mocks.MockPinger { mock := mocks.NewDefaultMockPinger(suite.ctrl) return mock }, - want: &ping.Result{ - PacketsSent: 3, - PacketsReceived: 3, - PacketLoss: 0, - MinRTT: 10 * time.Millisecond, - AvgRTT: 15 * time.Millisecond, - MaxRTT: 20 * time.Millisecond, + address: "1.1.1.1", + validateFunc: func(got *ping.Result, err error) { + suite.NoError(err) + suite.Equal(&ping.Result{ + PacketsSent: 3, + PacketsReceived: 3, + PacketLoss: 0, + MinRTT: 10 * time.Millisecond, + AvgRTT: 15 * time.Millisecond, + MaxRTT: 20 * time.Millisecond, + }, got) }, - wantErr: false, }, { - name: "when NewPingerFn errors", - address: "invalid-address", + name: "when NewPingerFn errors", setupMock: func() *mocks.MockPinger { return nil }, - wantErr: true, - wantErrType: fmt.Errorf("failed to initialize pinger"), + address: "invalid-address", + validateFunc: func(_ *ping.Result, err error) { + suite.Error(err) + suite.Contains(err.Error(), "failed to initialize pinger") + }, }, { - name: "when pinger.Run errors", - address: "1.1.1.1", + name: "when pinger.Run errors", setupMock: func() *mocks.MockPinger { mock := mocks.NewPlainMockPinger(suite.ctrl) @@ -98,12 +98,14 @@ func (suite *DebianDoPublicTestSuite) TestDo() { return mock }, - wantErr: true, - wantErrType: assert.AnError, + address: "1.1.1.1", + validateFunc: func(_ *ping.Result, err error) { + suite.Error(err) + suite.Contains(err.Error(), assert.AnError.Error()) + }, }, { - name: "when ping operation times out", - address: "1.1.1.1", + name: "when ping operation times out", setupMock: func() *mocks.MockPinger { mock := mocks.NewMockPinger(suite.ctrl) @@ -115,8 +117,11 @@ func (suite *DebianDoPublicTestSuite) TestDo() { return mock }, - wantErr: true, - wantErrType: fmt.Errorf("ping operation timed out after 5s"), + address: "1.1.1.1", + validateFunc: func(_ *ping.Result, err error) { + suite.Error(err) + suite.Contains(err.Error(), "ping operation timed out after 5s") + }, }, } @@ -131,15 +136,7 @@ func (suite *DebianDoPublicTestSuite) TestDo() { } } - got, err := debian.Do(tc.address) - - if !tc.wantErr { - suite.NoError(err) - suite.Equal(tc.want, got) - } else { - suite.Error(err) - suite.Contains(err.Error(), tc.wantErrType.Error()) - } + tc.validateFunc(debian.Do(tc.address)) }) } } @@ -164,6 +161,8 @@ func (suite *DebianDoPublicTestSuite) TestSetCount() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianDoPublicTestSuite(t *testing.T) { +func TestDebianDoPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianDoPublicTestSuite)) } diff --git a/internal/provider/network/ping/linux_do_public_test.go b/internal/provider/network/ping/linux_do_public_test.go index 4b274a2d0..badc7f4e8 100644 --- a/internal/provider/network/ping/linux_do_public_test.go +++ b/internal/provider/network/ping/linux_do_public_test.go @@ -45,10 +45,15 @@ func (suite *LinuxDoStatsPublicTestSuite) TearDownTest() {} func (suite *LinuxDoStatsPublicTestSuite) TestDo() { tests := []struct { - name string + name string + validateFunc func(*ping.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *ping.Result, err error) { + suite.Empty(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -56,16 +61,15 @@ func (suite *LinuxDoStatsPublicTestSuite) TestDo() { suite.Run(tc.name, func() { linux := ping.NewLinuxProvider() - got, err := linux.Do("1.1.1.1") - - suite.Empty(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.Do("1.1.1.1")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxDoStatsPublicTestSuite(t *testing.T) { +func TestLinuxDoStatsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxDoStatsPublicTestSuite)) } diff --git a/internal/provider/network/ping/mocks/mocks.go b/internal/provider/network/ping/mocks/mocks.go index fb143604e..a6445d2a6 100644 --- a/internal/provider/network/ping/mocks/mocks.go +++ b/internal/provider/network/ping/mocks/mocks.go @@ -30,12 +30,16 @@ import ( ) // NewPlainMockProvider creates a Mock without defaults. -func NewPlainMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewPlainMockProvider( + ctrl *gomock.Controller, +) *MockProvider { return NewMockProvider(ctrl) } // NewDefaultMockProvider creates a Mock with defaults. -func NewDefaultMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewDefaultMockProvider( + ctrl *gomock.Controller, +) *MockProvider { mock := NewPlainMockProvider(ctrl) result := &ping.Result{ @@ -55,12 +59,16 @@ func NewDefaultMockProvider(ctrl *gomock.Controller) *MockProvider { } // NewPlainMockPinger creates a pinger Mock without defaults. -func NewPlainMockPinger(ctrl *gomock.Controller) *MockPinger { +func NewPlainMockPinger( + ctrl *gomock.Controller, +) *MockPinger { return NewMockPinger(ctrl) } // NewDefaultMockPinger creates a pinger Mock with defaults. -func NewDefaultMockPinger(ctrl *gomock.Controller) *MockPinger { +func NewDefaultMockPinger( + ctrl *gomock.Controller, +) *MockPinger { mock := NewPlainMockPinger(ctrl) SetCommonExpectations(mock) @@ -78,7 +86,9 @@ func NewDefaultMockPinger(ctrl *gomock.Controller) *MockPinger { } // SetCommonExpectations sets the common expectations on the mock pinger. -func SetCommonExpectations(mock *MockPinger) { +func SetCommonExpectations( + mock *MockPinger, +) { mock.EXPECT().SetCount(3) mock.EXPECT().SetPrivileged(false) } diff --git a/internal/provider/node/apt/darwin_public_test.go b/internal/provider/node/apt/darwin_public_test.go index d808c100f..e06365e2a 100644 --- a/internal/provider/node/apt/darwin_public_test.go +++ b/internal/provider/node/apt/darwin_public_test.go @@ -42,120 +42,134 @@ func (suite *DarwinPublicTestSuite) SetupTest() { func (suite *DarwinPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]apt.Package, error) }{ { name: "returns not implemented error", + validateFunc: func(result []apt.Package, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *DarwinPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*apt.Package, error) }{ { name: "returns not implemented error", + validateFunc: func(result *apt.Package, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), "vim") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), "vim")) }) } } func (suite *DarwinPublicTestSuite) TestInstall() { tests := []struct { - name string + name string + validateFunc func(*apt.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *apt.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Install(context.Background(), "vim") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Install(context.Background(), "vim")) }) } } func (suite *DarwinPublicTestSuite) TestRemove() { tests := []struct { - name string + name string + validateFunc func(*apt.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *apt.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Remove(context.Background(), "vim") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Remove(context.Background(), "vim")) }) } } func (suite *DarwinPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*apt.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *apt.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background())) }) } } func (suite *DarwinPublicTestSuite) TestListUpdates() { tests := []struct { - name string + name string + validateFunc func([]apt.Update, error) }{ { name: "returns not implemented error", + validateFunc: func(result []apt.Update, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.ListUpdates(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.ListUpdates(context.Background())) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinPublicTestSuite(t *testing.T) { +func TestDarwinPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinPublicTestSuite)) } diff --git a/internal/provider/node/apt/debian_public_test.go b/internal/provider/node/apt/debian_public_test.go index 9874e9624..bb0bd3484 100644 --- a/internal/provider/node/apt/debian_public_test.go +++ b/internal/provider/node/apt/debian_public_test.go @@ -473,6 +473,8 @@ func (suite *DebianPublicTestSuite) TestListUpdates() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianPublicTestSuite(t *testing.T) { +func TestDebianPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianPublicTestSuite)) } diff --git a/internal/provider/node/apt/linux_public_test.go b/internal/provider/node/apt/linux_public_test.go index 94bc05c61..6643841e9 100644 --- a/internal/provider/node/apt/linux_public_test.go +++ b/internal/provider/node/apt/linux_public_test.go @@ -42,120 +42,134 @@ func (suite *LinuxPublicTestSuite) SetupTest() { func (suite *LinuxPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]apt.Package, error) }{ { name: "returns not implemented error", + validateFunc: func(result []apt.Package, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *LinuxPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*apt.Package, error) }{ { name: "returns not implemented error", + validateFunc: func(result *apt.Package, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), "vim") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), "vim")) }) } } func (suite *LinuxPublicTestSuite) TestInstall() { tests := []struct { - name string + name string + validateFunc func(*apt.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *apt.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Install(context.Background(), "vim") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Install(context.Background(), "vim")) }) } } func (suite *LinuxPublicTestSuite) TestRemove() { tests := []struct { - name string + name string + validateFunc func(*apt.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *apt.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Remove(context.Background(), "vim") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Remove(context.Background(), "vim")) }) } } func (suite *LinuxPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*apt.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *apt.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background())) }) } } func (suite *LinuxPublicTestSuite) TestListUpdates() { tests := []struct { - name string + name string + validateFunc func([]apt.Update, error) }{ { name: "returns not implemented error", + validateFunc: func(result []apt.Update, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.ListUpdates(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.ListUpdates(context.Background())) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxPublicTestSuite)) } diff --git a/internal/provider/node/certificate/darwin_public_test.go b/internal/provider/node/certificate/darwin_public_test.go index cf03888be..550dd25d6 100644 --- a/internal/provider/node/certificate/darwin_public_test.go +++ b/internal/provider/node/certificate/darwin_public_test.go @@ -42,88 +42,98 @@ func (suite *DarwinPublicTestSuite) SetupTest() { func (suite *DarwinPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]certificate.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result []certificate.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *DarwinPublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*certificate.CreateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(got *certificate.CreateResult, err error) { + suite.Nil(got) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create( + tc.validateFunc(suite.provider.Create( context.Background(), certificate.Entry{Name: "test"}, - ) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *DarwinPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*certificate.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(got *certificate.UpdateResult, err error) { + suite.Nil(got) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update( + tc.validateFunc(suite.provider.Update( context.Background(), certificate.Entry{Name: "test"}, - ) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *DarwinPublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*certificate.DeleteResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *certificate.DeleteResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background(), "test") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background(), "test")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinPublicTestSuite(t *testing.T) { +func TestDarwinPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinPublicTestSuite)) } diff --git a/internal/provider/node/certificate/debian_list_public_test.go b/internal/provider/node/certificate/debian_list_public_test.go index 015646da8..a404c177b 100644 --- a/internal/provider/node/certificate/debian_list_public_test.go +++ b/internal/provider/node/certificate/debian_list_public_test.go @@ -371,6 +371,8 @@ func (suite *DebianListPublicTestSuite) TestList() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianListPublicTestSuite(t *testing.T) { +func TestDebianListPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianListPublicTestSuite)) } diff --git a/internal/provider/node/certificate/debian_public_test.go b/internal/provider/node/certificate/debian_public_test.go index 42853cc41..01ab64ee9 100644 --- a/internal/provider/node/certificate/debian_public_test.go +++ b/internal/provider/node/certificate/debian_public_test.go @@ -626,6 +626,8 @@ func (suite *DebianPublicTestSuite) TestDelete() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianPublicTestSuite(t *testing.T) { +func TestDebianPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianPublicTestSuite)) } diff --git a/internal/provider/node/certificate/linux_public_test.go b/internal/provider/node/certificate/linux_public_test.go index 30d7c30e0..564b826d5 100644 --- a/internal/provider/node/certificate/linux_public_test.go +++ b/internal/provider/node/certificate/linux_public_test.go @@ -42,88 +42,98 @@ func (suite *LinuxPublicTestSuite) SetupTest() { func (suite *LinuxPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]certificate.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result []certificate.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *LinuxPublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*certificate.CreateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(got *certificate.CreateResult, err error) { + suite.Nil(got) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create( + tc.validateFunc(suite.provider.Create( context.Background(), certificate.Entry{Name: "test"}, - ) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *LinuxPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*certificate.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(got *certificate.UpdateResult, err error) { + suite.Nil(got) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update( + tc.validateFunc(suite.provider.Update( context.Background(), certificate.Entry{Name: "test"}, - ) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *LinuxPublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*certificate.DeleteResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *certificate.DeleteResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background(), "test") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background(), "test")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxPublicTestSuite)) } diff --git a/internal/provider/node/disk/darwin_get_local_usage_public_test.go b/internal/provider/node/disk/darwin_get_local_usage_public_test.go index 7de353c40..ecee2866c 100644 --- a/internal/provider/node/disk/darwin_get_local_usage_public_test.go +++ b/internal/provider/node/disk/darwin_get_local_usage_public_test.go @@ -50,11 +50,9 @@ func (suite *DarwinGetLocalUsageStatsPublicTestSuite) TearDownTest() { func (suite *DarwinGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { tests := []struct { - name string - setupMock func(*disk.Darwin) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func(*disk.Darwin) + validateFunc func([]disk.Result, error) }{ { name: "when GetLocalUsageStats Ok", @@ -116,22 +114,24 @@ func (suite *DarwinGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { } } }, - want: []disk.Result{ - { - Name: "/", - Total: 500000000000, - Used: 250000000000, - Free: 250000000000, - }, - { - Name: "/Volumes/Data", - Total: 1000000000000, - Used: 750000000000, - Free: 250000000000, - }, + validateFunc: func(got []disk.Result, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal([]disk.Result{ + { + Name: "/", + Total: 500000000000, + Used: 250000000000, + Free: 250000000000, + }, + { + Name: "/Volumes/Data", + Total: 1000000000000, + Used: 750000000000, + Free: 250000000000, + }, + }, got) }, - - wantErr: false, }, { name: "when disk.Usage returns EACCES PathError", @@ -170,15 +170,18 @@ func (suite *DarwinGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { } } }, - want: []disk.Result{ - { - Name: "/", - Total: 500000000000, - Used: 250000000000, - Free: 250000000000, - }, + validateFunc: func(got []disk.Result, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal([]disk.Result{ + { + Name: "/", + Total: 500000000000, + Used: 250000000000, + Free: 250000000000, + }, + }, got) }, - wantErr: false, }, { name: "when disk.Partitions errors", @@ -187,8 +190,11 @@ func (suite *DarwinGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got []disk.Result, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Nil(got) + }, }, { name: "when disk.Usage errors", @@ -206,8 +212,11 @@ func (suite *DarwinGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got []disk.Result, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Nil(got) + }, }, } @@ -219,23 +228,15 @@ func (suite *DarwinGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { tc.setupMock(darwin) } - got, err := darwin.GetLocalUsageStats() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Nil(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(darwin.GetLocalUsageStats()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetLocalUsageStatsPublicTestSuite(t *testing.T) { +func TestDarwinGetLocalUsageStatsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetLocalUsageStatsPublicTestSuite)) } diff --git a/internal/provider/node/disk/debian_get_local_usage_public_test.go b/internal/provider/node/disk/debian_get_local_usage_public_test.go index 3768f6991..c3df94e00 100644 --- a/internal/provider/node/disk/debian_get_local_usage_public_test.go +++ b/internal/provider/node/disk/debian_get_local_usage_public_test.go @@ -49,11 +49,9 @@ func (suite *DebianGetLocalUsageStatsPublicTestSuite) TearDownTest() { func (suite *DebianGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { tests := []struct { - name string - setupMock func(*disk.Debian) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func(*disk.Debian) + validateFunc func([]disk.Result, error) }{ { name: "when GetLocalUsageStats Ok", @@ -115,22 +113,24 @@ func (suite *DebianGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { } } }, - want: []disk.Result{ - { - Name: "/dev/disk1", - Total: 500000000000, - Used: 250000000000, - Free: 250000000000, - }, - { - Name: "/dev/disk2", - Total: 1000000000000, - Used: 750000000000, - Free: 250000000000, - }, + validateFunc: func(got []disk.Result, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal([]disk.Result{ + { + Name: "/dev/disk1", + Total: 500000000000, + Used: 250000000000, + Free: 250000000000, + }, + { + Name: "/dev/disk2", + Total: 1000000000000, + Used: 750000000000, + Free: 250000000000, + }, + }, got) }, - - wantErr: false, }, { name: "when disk.Partitions errors", @@ -139,8 +139,11 @@ func (suite *DebianGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got []disk.Result, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Nil(got) + }, }, { name: "when disk.Usage errors", @@ -158,8 +161,11 @@ func (suite *DebianGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got []disk.Result, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Nil(got) + }, }, } @@ -171,23 +177,15 @@ func (suite *DebianGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { tc.setupMock(debian) } - got, err := debian.GetLocalUsageStats() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Nil(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(debian.GetLocalUsageStats()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetLocalUsageStatsPublicTestSuite(t *testing.T) { +func TestDebianGetLocalUsageStatsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetLocalUsageStatsPublicTestSuite)) } diff --git a/internal/provider/node/disk/disk_public_test.go b/internal/provider/node/disk/disk_public_test.go index 4e59f5af7..a3fa04574 100644 --- a/internal/provider/node/disk/disk_public_test.go +++ b/internal/provider/node/disk/disk_public_test.go @@ -41,9 +41,9 @@ func (suite *DiskPublicTestSuite) TearDownTest() {} func (suite *DiskPublicTestSuite) TestIsPermissionError() { tests := []struct { - name string - err error - want bool + name string + err error + validateFunc func(bool) }{ { name: "when error is EACCES wrapped in os.PathError", @@ -52,7 +52,9 @@ func (suite *DiskPublicTestSuite) TestIsPermissionError() { Path: "/restricted", Err: syscall.EACCES, }, - want: true, + validateFunc: func(got bool) { + suite.Equal(true, got) + }, }, { name: "when error is a different syscall errno", @@ -61,12 +63,16 @@ func (suite *DiskPublicTestSuite) TestIsPermissionError() { Path: "/file", Err: syscall.EPERM, // Not EACCES. }, - want: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, { name: "when error is not a PathError", err: errors.New("some other error"), - want: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, { name: "when PathError contains non-syscall error", @@ -75,12 +81,16 @@ func (suite *DiskPublicTestSuite) TestIsPermissionError() { Path: "/file", Err: errors.New("some random error"), }, - want: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, { name: "when error is nil", err: nil, - want: false, + validateFunc: func(got bool) { + suite.Equal(false, got) + }, }, } @@ -88,11 +98,13 @@ func (suite *DiskPublicTestSuite) TestIsPermissionError() { suite.Run(tc.name, func() { got := disk.ExportIsPermissionError(tc.err) - suite.Equal(tc.want, got) + tc.validateFunc(got) }) } } -func TestDiskPublicTestSuite(t *testing.T) { +func TestDiskPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DiskPublicTestSuite)) } diff --git a/internal/provider/node/disk/linux_get_local_usage_public_test.go b/internal/provider/node/disk/linux_get_local_usage_public_test.go index a10e5c343..cd66cc616 100644 --- a/internal/provider/node/disk/linux_get_local_usage_public_test.go +++ b/internal/provider/node/disk/linux_get_local_usage_public_test.go @@ -40,10 +40,15 @@ func (suite *LinuxGetLocalUsageStatsPublicTestSuite) TearDownTest() {} func (suite *LinuxGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { tests := []struct { - name string + name string + validateFunc func([]disk.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result []disk.Result, err error) { + suite.Empty(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -51,16 +56,15 @@ func (suite *LinuxGetLocalUsageStatsPublicTestSuite) TestGetLocalUsageStats() { suite.Run(tc.name, func() { linux := disk.NewLinuxProvider() - got, err := linux.GetLocalUsageStats() - - suite.Empty(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.GetLocalUsageStats()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxGetLocalUsageStatsPublicTestSuite(t *testing.T) { +func TestLinuxGetLocalUsageStatsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxGetLocalUsageStatsPublicTestSuite)) } diff --git a/internal/provider/node/disk/mocks/mocks.go b/internal/provider/node/disk/mocks/mocks.go index 5e58edeca..9b7d83650 100644 --- a/internal/provider/node/disk/mocks/mocks.go +++ b/internal/provider/node/disk/mocks/mocks.go @@ -27,12 +27,16 @@ import ( ) // NewPlainMockProvider creates a Mock without defaults. -func NewPlainMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewPlainMockProvider( + ctrl *gomock.Controller, +) *MockProvider { return NewMockProvider(ctrl) } // NewDefaultMockProvider creates a Mock with defaults. -func NewDefaultMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewDefaultMockProvider( + ctrl *gomock.Controller, +) *MockProvider { mock := NewMockProvider(ctrl) mock.EXPECT().GetLocalUsageStats().Return([]disk.Result{ diff --git a/internal/provider/node/host/darwin_get_architecture_public_test.go b/internal/provider/node/host/darwin_get_architecture_public_test.go index 8a3f39241..a8e1ae7e3 100644 --- a/internal/provider/node/host/darwin_get_architecture_public_test.go +++ b/internal/provider/node/host/darwin_get_architecture_public_test.go @@ -40,11 +40,9 @@ func (suite *DarwinGetArchitecturePublicTestSuite) TearDownTest() {} func (suite *DarwinGetArchitecturePublicTestSuite) TestGetArchitecture() { tests := []struct { - name string - setupMock func() func() (*sysHost.InfoStat, error) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysHost.InfoStat, error) + validateFunc func(string, error) }{ { name: "when GetArchitecture Ok", @@ -53,8 +51,11 @@ func (suite *DarwinGetArchitecturePublicTestSuite) TestGetArchitecture() { return &sysHost.InfoStat{KernelArch: "arm64"}, nil } }, - want: "arm64", - wantErr: false, + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal("arm64", got) + }, }, { name: "when host.Info errors", @@ -63,8 +64,11 @@ func (suite *DarwinGetArchitecturePublicTestSuite) TestGetArchitecture() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got string, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Empty(got) + }, }, } @@ -76,23 +80,15 @@ func (suite *DarwinGetArchitecturePublicTestSuite) TestGetArchitecture() { darwin.InfoFn = tc.setupMock() } - got, err := darwin.GetArchitecture() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Empty(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(darwin.GetArchitecture()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetArchitecturePublicTestSuite(t *testing.T) { +func TestDarwinGetArchitecturePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetArchitecturePublicTestSuite)) } diff --git a/internal/provider/node/host/darwin_get_cpu_count_public_test.go b/internal/provider/node/host/darwin_get_cpu_count_public_test.go index 880626996..171549eba 100644 --- a/internal/provider/node/host/darwin_get_cpu_count_public_test.go +++ b/internal/provider/node/host/darwin_get_cpu_count_public_test.go @@ -38,10 +38,9 @@ func (suite *DarwinGetCPUCountPublicTestSuite) TearDownTest() {} func (suite *DarwinGetCPUCountPublicTestSuite) TestGetCPUCount() { tests := []struct { - name string - setupMock func(d *host.Darwin) - want interface{} - wantErr bool + name string + setupMock func(d *host.Darwin) + validateFunc func(int, error) }{ { name: "when GetCPUCount Ok", @@ -50,8 +49,10 @@ func (suite *DarwinGetCPUCountPublicTestSuite) TestGetCPUCount() { return 10 } }, - want: 10, - wantErr: false, + validateFunc: func(got int, err error) { + suite.NoError(err) + suite.Equal(10, got) + }, }, { name: "when NumCPU returns 1", @@ -60,8 +61,10 @@ func (suite *DarwinGetCPUCountPublicTestSuite) TestGetCPUCount() { return 1 } }, - want: 1, - wantErr: false, + validateFunc: func(got int, err error) { + suite.NoError(err) + suite.Equal(1, got) + }, }, } @@ -73,21 +76,15 @@ func (suite *DarwinGetCPUCountPublicTestSuite) TestGetCPUCount() { tc.setupMock(darwin) } - got, err := darwin.GetCPUCount() - - if tc.wantErr { - suite.Error(err) - suite.Equal(0, got) - } else { - suite.NoError(err) - suite.Equal(tc.want, got) - } + tc.validateFunc(darwin.GetCPUCount()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetCPUCountPublicTestSuite(t *testing.T) { +func TestDarwinGetCPUCountPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetCPUCountPublicTestSuite)) } diff --git a/internal/provider/node/host/darwin_get_fqdn_public_test.go b/internal/provider/node/host/darwin_get_fqdn_public_test.go index f2ed34502..56df37d12 100644 --- a/internal/provider/node/host/darwin_get_fqdn_public_test.go +++ b/internal/provider/node/host/darwin_get_fqdn_public_test.go @@ -39,11 +39,9 @@ func (suite *DarwinGetFQDNPublicTestSuite) TearDownTest() {} func (suite *DarwinGetFQDNPublicTestSuite) TestGetFQDN() { tests := []struct { - name string - setupMock func(d *host.Darwin) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func(d *host.Darwin) + validateFunc func(string, error) }{ { name: "when GetFQDN Ok", @@ -52,8 +50,11 @@ func (suite *DarwinGetFQDNPublicTestSuite) TestGetFQDN() { return "mac-01.local", nil } }, - want: "mac-01.local", - wantErr: false, + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal("mac-01.local", got) + }, }, { name: "when os.Hostname errors", @@ -62,8 +63,11 @@ func (suite *DarwinGetFQDNPublicTestSuite) TestGetFQDN() { return "", assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got string, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Empty(got) + }, }, } @@ -75,23 +79,15 @@ func (suite *DarwinGetFQDNPublicTestSuite) TestGetFQDN() { tc.setupMock(darwin) } - got, err := darwin.GetFQDN() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Empty(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(darwin.GetFQDN()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetFQDNPublicTestSuite(t *testing.T) { +func TestDarwinGetFQDNPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetFQDNPublicTestSuite)) } diff --git a/internal/provider/node/host/darwin_get_hostname_public_test.go b/internal/provider/node/host/darwin_get_hostname_public_test.go index a922efde9..d6ed7c17e 100644 --- a/internal/provider/node/host/darwin_get_hostname_public_test.go +++ b/internal/provider/node/host/darwin_get_hostname_public_test.go @@ -40,11 +40,9 @@ func (suite *DarwinGetHostnamePublicTestSuite) TearDownTest() {} func (suite *DarwinGetHostnamePublicTestSuite) TestGetHostname() { tests := []struct { - name string - setupMock func() func() (*sysHost.InfoStat, error) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysHost.InfoStat, error) + validateFunc func(string, error) }{ { name: "when GetHostname Ok", @@ -53,8 +51,11 @@ func (suite *DarwinGetHostnamePublicTestSuite) TestGetHostname() { return &sysHost.InfoStat{Hostname: "default-hostname"}, nil } }, - want: "default-hostname", - wantErr: false, + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal("default-hostname", got) + }, }, { name: "when host.Info errors", @@ -63,8 +64,11 @@ func (suite *DarwinGetHostnamePublicTestSuite) TestGetHostname() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got string, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Empty(got) + }, }, } @@ -76,23 +80,15 @@ func (suite *DarwinGetHostnamePublicTestSuite) TestGetHostname() { darwin.InfoFn = tc.setupMock() } - got, err := darwin.GetHostname() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Empty(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(darwin.GetHostname()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetHostnamePublicTestSuite(t *testing.T) { +func TestDarwinGetHostnamePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetHostnamePublicTestSuite)) } diff --git a/internal/provider/node/host/darwin_get_kernel_version_public_test.go b/internal/provider/node/host/darwin_get_kernel_version_public_test.go index a4454d8fe..2c9ebe850 100644 --- a/internal/provider/node/host/darwin_get_kernel_version_public_test.go +++ b/internal/provider/node/host/darwin_get_kernel_version_public_test.go @@ -40,11 +40,9 @@ func (suite *DarwinGetKernelVersionPublicTestSuite) TearDownTest() {} func (suite *DarwinGetKernelVersionPublicTestSuite) TestGetKernelVersion() { tests := []struct { - name string - setupMock func() func() (*sysHost.InfoStat, error) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysHost.InfoStat, error) + validateFunc func(string, error) }{ { name: "when GetKernelVersion Ok", @@ -53,8 +51,11 @@ func (suite *DarwinGetKernelVersionPublicTestSuite) TestGetKernelVersion() { return &sysHost.InfoStat{KernelVersion: "24.3.0"}, nil } }, - want: "24.3.0", - wantErr: false, + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal("24.3.0", got) + }, }, { name: "when host.Info errors", @@ -63,8 +64,11 @@ func (suite *DarwinGetKernelVersionPublicTestSuite) TestGetKernelVersion() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got string, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Empty(got) + }, }, } @@ -76,23 +80,15 @@ func (suite *DarwinGetKernelVersionPublicTestSuite) TestGetKernelVersion() { darwin.InfoFn = tc.setupMock() } - got, err := darwin.GetKernelVersion() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Empty(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(darwin.GetKernelVersion()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetKernelVersionPublicTestSuite(t *testing.T) { +func TestDarwinGetKernelVersionPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetKernelVersionPublicTestSuite)) } diff --git a/internal/provider/node/host/darwin_get_os_info_public_test.go b/internal/provider/node/host/darwin_get_os_info_public_test.go index f115a9161..bc881ad1e 100644 --- a/internal/provider/node/host/darwin_get_os_info_public_test.go +++ b/internal/provider/node/host/darwin_get_os_info_public_test.go @@ -40,11 +40,9 @@ func (suite *DarwinGetOSInfoPublicTestSuite) TearDownTest() {} func (suite *DarwinGetOSInfoPublicTestSuite) TestGetOSInfo() { tests := []struct { - name string - setupMock func() func() (*sysHost.InfoStat, error) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysHost.InfoStat, error) + validateFunc func(*host.Result, error) }{ { name: "when GetOSInfo Ok", @@ -56,11 +54,14 @@ func (suite *DarwinGetOSInfoPublicTestSuite) TestGetOSInfo() { }, nil } }, - want: &host.Result{ - Distribution: "darwin", - Version: "15.3", + validateFunc: func(got *host.Result, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal(&host.Result{ + Distribution: "darwin", + Version: "15.3", + }, got) }, - wantErr: false, }, { name: "when host.Info errors", @@ -69,8 +70,11 @@ func (suite *DarwinGetOSInfoPublicTestSuite) TestGetOSInfo() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got *host.Result, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Nil(got) + }, }, } @@ -82,23 +86,15 @@ func (suite *DarwinGetOSInfoPublicTestSuite) TestGetOSInfo() { darwin.InfoFn = tc.setupMock() } - got, err := darwin.GetOSInfo() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Nil(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(darwin.GetOSInfo()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetOSInfoPublicTestSuite(t *testing.T) { +func TestDarwinGetOSInfoPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetOSInfoPublicTestSuite)) } diff --git a/internal/provider/node/host/darwin_get_package_manager_public_test.go b/internal/provider/node/host/darwin_get_package_manager_public_test.go index 829b29b5d..bb3b6e7b8 100644 --- a/internal/provider/node/host/darwin_get_package_manager_public_test.go +++ b/internal/provider/node/host/darwin_get_package_manager_public_test.go @@ -38,10 +38,9 @@ func (suite *DarwinGetPackageManagerPublicTestSuite) TearDownTest() {} func (suite *DarwinGetPackageManagerPublicTestSuite) TestGetPackageManager() { tests := []struct { - name string - setupMock func(d *host.Darwin) - want interface{} - wantErr bool + name string + setupMock func(d *host.Darwin) + validateFunc func(string, error) }{ { name: "when brew detected", @@ -53,8 +52,10 @@ func (suite *DarwinGetPackageManagerPublicTestSuite) TestGetPackageManager() { return "", &host.ExecNotFoundError{Name: file} } }, - want: "brew", - wantErr: false, + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.Equal("brew", got) + }, }, { name: "when no package manager detected", @@ -63,8 +64,10 @@ func (suite *DarwinGetPackageManagerPublicTestSuite) TestGetPackageManager() { return "", &host.ExecNotFoundError{Name: "unknown"} } }, - want: "unknown", - wantErr: false, + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.Equal("unknown", got) + }, }, } @@ -76,21 +79,15 @@ func (suite *DarwinGetPackageManagerPublicTestSuite) TestGetPackageManager() { tc.setupMock(darwin) } - got, err := darwin.GetPackageManager() - - if tc.wantErr { - suite.Error(err) - suite.Empty(got) - } else { - suite.NoError(err) - suite.Equal(tc.want, got) - } + tc.validateFunc(darwin.GetPackageManager()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetPackageManagerPublicTestSuite(t *testing.T) { +func TestDarwinGetPackageManagerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetPackageManagerPublicTestSuite)) } diff --git a/internal/provider/node/host/darwin_get_service_manager_public_test.go b/internal/provider/node/host/darwin_get_service_manager_public_test.go index b60bce9cf..9a503bfa1 100644 --- a/internal/provider/node/host/darwin_get_service_manager_public_test.go +++ b/internal/provider/node/host/darwin_get_service_manager_public_test.go @@ -38,14 +38,15 @@ func (suite *DarwinGetServiceManagerPublicTestSuite) TearDownTest() {} func (suite *DarwinGetServiceManagerPublicTestSuite) TestGetServiceManager() { tests := []struct { - name string - want interface{} - wantErr bool + name string + validateFunc func(string, error) }{ { - name: "when GetServiceManager returns launchd", - want: "launchd", - wantErr: false, + name: "when GetServiceManager returns launchd", + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.Equal("launchd", got) + }, }, } @@ -53,21 +54,15 @@ func (suite *DarwinGetServiceManagerPublicTestSuite) TestGetServiceManager() { suite.Run(tc.name, func() { darwin := host.NewDarwinProvider() - got, err := darwin.GetServiceManager() - - if tc.wantErr { - suite.Error(err) - suite.Empty(got) - } else { - suite.NoError(err) - suite.Equal(tc.want, got) - } + tc.validateFunc(darwin.GetServiceManager()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetServiceManagerPublicTestSuite(t *testing.T) { +func TestDarwinGetServiceManagerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetServiceManagerPublicTestSuite)) } diff --git a/internal/provider/node/host/darwin_get_uptime_public_test.go b/internal/provider/node/host/darwin_get_uptime_public_test.go index af23876d4..01b604e3b 100644 --- a/internal/provider/node/host/darwin_get_uptime_public_test.go +++ b/internal/provider/node/host/darwin_get_uptime_public_test.go @@ -41,11 +41,9 @@ func (suite *DarwinGetUptimePublicTestSuite) TearDownTest() {} func (suite *DarwinGetUptimePublicTestSuite) TestGetUptime() { tests := []struct { - name string - setupMock func() func() (*sysHost.InfoStat, error) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysHost.InfoStat, error) + validateFunc func(time.Duration, error) }{ { name: "when GetUptime Ok", @@ -54,8 +52,11 @@ func (suite *DarwinGetUptimePublicTestSuite) TestGetUptime() { return &sysHost.InfoStat{Uptime: 5 * 3600}, nil } }, - want: time.Hour * 5, - wantErr: false, + validateFunc: func(got time.Duration, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal(time.Hour*5, got) + }, }, { name: "when host.Info errors", @@ -64,8 +65,11 @@ func (suite *DarwinGetUptimePublicTestSuite) TestGetUptime() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got time.Duration, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Equal(time.Duration(0), got) + }, }, } @@ -77,23 +81,15 @@ func (suite *DarwinGetUptimePublicTestSuite) TestGetUptime() { darwin.InfoFn = tc.setupMock() } - got, err := darwin.GetUptime() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Equal(time.Duration(0), got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(darwin.GetUptime()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetUptimePublicTestSuite(t *testing.T) { +func TestDarwinGetUptimePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetUptimePublicTestSuite)) } diff --git a/internal/provider/node/host/darwin_update_hostname_public_test.go b/internal/provider/node/host/darwin_update_hostname_public_test.go index a731251f7..1b3869c78 100644 --- a/internal/provider/node/host/darwin_update_hostname_public_test.go +++ b/internal/provider/node/host/darwin_update_hostname_public_test.go @@ -39,10 +39,15 @@ func (suite *DarwinUpdateHostnamePublicTestSuite) TearDownTest() {} func (suite *DarwinUpdateHostnamePublicTestSuite) TestUpdateHostname() { tests := []struct { - name string + name string + validateFunc func(*host.UpdateHostnameResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *host.UpdateHostnameResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -50,16 +55,15 @@ func (suite *DarwinUpdateHostnamePublicTestSuite) TestUpdateHostname() { suite.Run(tc.name, func() { darwin := host.NewDarwinProvider() - got, err := darwin.UpdateHostname("new-host") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(darwin.UpdateHostname("new-host")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinUpdateHostnamePublicTestSuite(t *testing.T) { +func TestDarwinUpdateHostnamePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinUpdateHostnamePublicTestSuite)) } diff --git a/internal/provider/node/host/debian_docker_public_test.go b/internal/provider/node/host/debian_docker_public_test.go index e9ed82962..fe88b9b81 100644 --- a/internal/provider/node/host/debian_docker_public_test.go +++ b/internal/provider/node/host/debian_docker_public_test.go @@ -35,25 +35,29 @@ type DebianDockerPublicTestSuite struct { func (s *DebianDockerPublicTestSuite) TestUpdateHostname() { tests := []struct { - name string + name string + validateFunc func(*host.UpdateHostnameResult, error) }{ { name: "returns ErrUnsupported for container", + validateFunc: func(result *host.UpdateHostnameResult, err error) { + s.Error(err) + s.Nil(result) + s.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { p := host.NewDebianDockerProvider() - result, err := p.UpdateHostname("new-hostname") - - s.Error(err) - s.Nil(result) - s.ErrorIs(err, provider.ErrUnsupported) + tt.validateFunc(p.UpdateHostname("new-hostname")) }) } } -func TestDebianDockerPublicTestSuite(t *testing.T) { +func TestDebianDockerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianDockerPublicTestSuite)) } diff --git a/internal/provider/node/host/debian_get_architecture_public_test.go b/internal/provider/node/host/debian_get_architecture_public_test.go index beef99a8a..a818af4c3 100644 --- a/internal/provider/node/host/debian_get_architecture_public_test.go +++ b/internal/provider/node/host/debian_get_architecture_public_test.go @@ -40,11 +40,9 @@ func (suite *DebianGetArchitecturePublicTestSuite) TearDownTest() {} func (suite *DebianGetArchitecturePublicTestSuite) TestGetArchitecture() { tests := []struct { - name string - setupMock func() func() (*sysHost.InfoStat, error) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysHost.InfoStat, error) + validateFunc func(string, error) }{ { name: "when GetArchitecture Ok", @@ -53,8 +51,11 @@ func (suite *DebianGetArchitecturePublicTestSuite) TestGetArchitecture() { return &sysHost.InfoStat{KernelArch: "x86_64"}, nil } }, - want: "x86_64", - wantErr: false, + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal("x86_64", got) + }, }, { name: "when host.Info errors", @@ -63,8 +64,11 @@ func (suite *DebianGetArchitecturePublicTestSuite) TestGetArchitecture() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got string, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Empty(got) + }, }, } @@ -76,23 +80,15 @@ func (suite *DebianGetArchitecturePublicTestSuite) TestGetArchitecture() { debian.InfoFn = tc.setupMock() } - got, err := debian.GetArchitecture() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Empty(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(debian.GetArchitecture()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetArchitecturePublicTestSuite(t *testing.T) { +func TestDebianGetArchitecturePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetArchitecturePublicTestSuite)) } diff --git a/internal/provider/node/host/debian_get_cpu_count_public_test.go b/internal/provider/node/host/debian_get_cpu_count_public_test.go index ab7b56fd7..2cd7bd49d 100644 --- a/internal/provider/node/host/debian_get_cpu_count_public_test.go +++ b/internal/provider/node/host/debian_get_cpu_count_public_test.go @@ -38,10 +38,9 @@ func (suite *DebianGetCPUCountPublicTestSuite) TearDownTest() {} func (suite *DebianGetCPUCountPublicTestSuite) TestGetCPUCount() { tests := []struct { - name string - setupMock func(u *host.Debian) - want interface{} - wantErr bool + name string + setupMock func(u *host.Debian) + validateFunc func(int, error) }{ { name: "when GetCPUCount Ok", @@ -50,8 +49,10 @@ func (suite *DebianGetCPUCountPublicTestSuite) TestGetCPUCount() { return 8 } }, - want: 8, - wantErr: false, + validateFunc: func(got int, err error) { + suite.NoError(err) + suite.Equal(8, got) + }, }, { name: "when NumCPU returns 1", @@ -60,8 +61,10 @@ func (suite *DebianGetCPUCountPublicTestSuite) TestGetCPUCount() { return 1 } }, - want: 1, - wantErr: false, + validateFunc: func(got int, err error) { + suite.NoError(err) + suite.Equal(1, got) + }, }, } @@ -73,21 +76,15 @@ func (suite *DebianGetCPUCountPublicTestSuite) TestGetCPUCount() { tc.setupMock(debian) } - got, err := debian.GetCPUCount() - - if tc.wantErr { - suite.Error(err) - suite.Equal(0, got) - } else { - suite.NoError(err) - suite.Equal(tc.want, got) - } + tc.validateFunc(debian.GetCPUCount()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetCPUCountPublicTestSuite(t *testing.T) { +func TestDebianGetCPUCountPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetCPUCountPublicTestSuite)) } diff --git a/internal/provider/node/host/debian_get_fqdn_public_test.go b/internal/provider/node/host/debian_get_fqdn_public_test.go index 6aed98ce7..e7efcb644 100644 --- a/internal/provider/node/host/debian_get_fqdn_public_test.go +++ b/internal/provider/node/host/debian_get_fqdn_public_test.go @@ -39,11 +39,9 @@ func (suite *DebianGetFQDNPublicTestSuite) TearDownTest() {} func (suite *DebianGetFQDNPublicTestSuite) TestGetFQDN() { tests := []struct { - name string - setupMock func(u *host.Debian) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func(u *host.Debian) + validateFunc func(string, error) }{ { name: "when GetFQDN Ok", @@ -52,8 +50,11 @@ func (suite *DebianGetFQDNPublicTestSuite) TestGetFQDN() { return "node-01.example.com", nil } }, - want: "node-01.example.com", - wantErr: false, + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal("node-01.example.com", got) + }, }, { name: "when os.Hostname errors", @@ -62,8 +63,11 @@ func (suite *DebianGetFQDNPublicTestSuite) TestGetFQDN() { return "", assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got string, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Empty(got) + }, }, } @@ -75,23 +79,15 @@ func (suite *DebianGetFQDNPublicTestSuite) TestGetFQDN() { tc.setupMock(debian) } - got, err := debian.GetFQDN() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Empty(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(debian.GetFQDN()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetFQDNPublicTestSuite(t *testing.T) { +func TestDebianGetFQDNPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetFQDNPublicTestSuite)) } diff --git a/internal/provider/node/host/debian_get_hostname_public_test.go b/internal/provider/node/host/debian_get_hostname_public_test.go index de454fc02..80e081ed9 100644 --- a/internal/provider/node/host/debian_get_hostname_public_test.go +++ b/internal/provider/node/host/debian_get_hostname_public_test.go @@ -40,11 +40,9 @@ func (suite *DebianGetHostnamePublicTestSuite) TearDownTest() {} func (suite *DebianGetHostnamePublicTestSuite) TestGetHostname() { tests := []struct { - name string - setupMock func() func() (*sysHost.InfoStat, error) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysHost.InfoStat, error) + validateFunc func(string, error) }{ { name: "when GetHostname Ok", @@ -53,8 +51,11 @@ func (suite *DebianGetHostnamePublicTestSuite) TestGetHostname() { return &sysHost.InfoStat{Hostname: "default-hostname"}, nil } }, - want: "default-hostname", - wantErr: false, + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal("default-hostname", got) + }, }, { name: "when host.Info errors", @@ -63,8 +64,11 @@ func (suite *DebianGetHostnamePublicTestSuite) TestGetHostname() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got string, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Empty(got) + }, }, } @@ -76,23 +80,15 @@ func (suite *DebianGetHostnamePublicTestSuite) TestGetHostname() { debian.InfoFn = tc.setupMock() } - got, err := debian.GetHostname() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Empty(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(debian.GetHostname()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetHostnamePublicTestSuite(t *testing.T) { +func TestDebianGetHostnamePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetHostnamePublicTestSuite)) } diff --git a/internal/provider/node/host/debian_get_kernel_version_public_test.go b/internal/provider/node/host/debian_get_kernel_version_public_test.go index 1e3fbff8f..7aae340dc 100644 --- a/internal/provider/node/host/debian_get_kernel_version_public_test.go +++ b/internal/provider/node/host/debian_get_kernel_version_public_test.go @@ -40,11 +40,9 @@ func (suite *DebianGetKernelVersionPublicTestSuite) TearDownTest() {} func (suite *DebianGetKernelVersionPublicTestSuite) TestGetKernelVersion() { tests := []struct { - name string - setupMock func() func() (*sysHost.InfoStat, error) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysHost.InfoStat, error) + validateFunc func(string, error) }{ { name: "when GetKernelVersion Ok", @@ -53,8 +51,11 @@ func (suite *DebianGetKernelVersionPublicTestSuite) TestGetKernelVersion() { return &sysHost.InfoStat{KernelVersion: "5.15.0-91-generic"}, nil } }, - want: "5.15.0-91-generic", - wantErr: false, + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal("5.15.0-91-generic", got) + }, }, { name: "when host.Info errors", @@ -63,8 +64,11 @@ func (suite *DebianGetKernelVersionPublicTestSuite) TestGetKernelVersion() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got string, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Empty(got) + }, }, } @@ -76,23 +80,15 @@ func (suite *DebianGetKernelVersionPublicTestSuite) TestGetKernelVersion() { debian.InfoFn = tc.setupMock() } - got, err := debian.GetKernelVersion() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Empty(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(debian.GetKernelVersion()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetKernelVersionPublicTestSuite(t *testing.T) { +func TestDebianGetKernelVersionPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetKernelVersionPublicTestSuite)) } diff --git a/internal/provider/node/host/debian_get_os_info_public_test.go b/internal/provider/node/host/debian_get_os_info_public_test.go index 509a19fa3..ba8fa0482 100644 --- a/internal/provider/node/host/debian_get_os_info_public_test.go +++ b/internal/provider/node/host/debian_get_os_info_public_test.go @@ -40,11 +40,9 @@ func (suite *DebianGetOSInfoPublicTestSuite) TearDownTest() {} func (suite *DebianGetOSInfoPublicTestSuite) TestGetOSInfo() { tests := []struct { - name string - setupMock func() func() (*sysHost.InfoStat, error) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysHost.InfoStat, error) + validateFunc func(*host.Result, error) }{ { name: "when GetOSInfo Ok", @@ -56,11 +54,14 @@ func (suite *DebianGetOSInfoPublicTestSuite) TestGetOSInfo() { }, nil } }, - want: &host.Result{ - Distribution: "Debian", - Version: "24.04", + validateFunc: func(got *host.Result, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal(&host.Result{ + Distribution: "Debian", + Version: "24.04", + }, got) }, - wantErr: false, }, { name: "when host.Info errors", @@ -69,8 +70,11 @@ func (suite *DebianGetOSInfoPublicTestSuite) TestGetOSInfo() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got *host.Result, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Nil(got) + }, }, } @@ -82,23 +86,15 @@ func (suite *DebianGetOSInfoPublicTestSuite) TestGetOSInfo() { debian.InfoFn = tc.setupMock() } - got, err := debian.GetOSInfo() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Nil(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(debian.GetOSInfo()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetOSInfoPublicTestSuite(t *testing.T) { +func TestDebianGetOSInfoPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetOSInfoPublicTestSuite)) } diff --git a/internal/provider/node/host/debian_get_package_manager_public_test.go b/internal/provider/node/host/debian_get_package_manager_public_test.go index 57f6ab5e2..f6e15fa40 100644 --- a/internal/provider/node/host/debian_get_package_manager_public_test.go +++ b/internal/provider/node/host/debian_get_package_manager_public_test.go @@ -136,6 +136,8 @@ func (suite *DebianGetPackageManagerPublicTestSuite) TestGetPackageManager() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetPackageManagerPublicTestSuite(t *testing.T) { +func TestDebianGetPackageManagerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetPackageManagerPublicTestSuite)) } diff --git a/internal/provider/node/host/debian_get_service_manager_public_test.go b/internal/provider/node/host/debian_get_service_manager_public_test.go index 279bdd67e..23bd1c4f0 100644 --- a/internal/provider/node/host/debian_get_service_manager_public_test.go +++ b/internal/provider/node/host/debian_get_service_manager_public_test.go @@ -39,10 +39,9 @@ func (suite *DebianGetServiceManagerPublicTestSuite) TearDownTest() {} func (suite *DebianGetServiceManagerPublicTestSuite) TestGetServiceManager() { tests := []struct { - name string - setupMock func(u *host.Debian) - want interface{} - wantErr bool + name string + setupMock func(u *host.Debian) + validateFunc func(string, error) }{ { name: "when systemd detected", @@ -51,8 +50,10 @@ func (suite *DebianGetServiceManagerPublicTestSuite) TestGetServiceManager() { return nil, nil } }, - want: "systemd", - wantErr: false, + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.Equal("systemd", got) + }, }, { name: "when systemd not detected", @@ -61,8 +62,10 @@ func (suite *DebianGetServiceManagerPublicTestSuite) TestGetServiceManager() { return nil, os.ErrNotExist } }, - want: "unknown", - wantErr: false, + validateFunc: func(got string, err error) { + suite.NoError(err) + suite.Equal("unknown", got) + }, }, } @@ -74,21 +77,15 @@ func (suite *DebianGetServiceManagerPublicTestSuite) TestGetServiceManager() { tc.setupMock(debian) } - got, err := debian.GetServiceManager() - - if tc.wantErr { - suite.Error(err) - suite.Empty(got) - } else { - suite.NoError(err) - suite.Equal(tc.want, got) - } + tc.validateFunc(debian.GetServiceManager()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetServiceManagerPublicTestSuite(t *testing.T) { +func TestDebianGetServiceManagerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetServiceManagerPublicTestSuite)) } diff --git a/internal/provider/node/host/debian_get_uptime_public_test.go b/internal/provider/node/host/debian_get_uptime_public_test.go index e2f8fc53b..1b0841301 100644 --- a/internal/provider/node/host/debian_get_uptime_public_test.go +++ b/internal/provider/node/host/debian_get_uptime_public_test.go @@ -41,11 +41,9 @@ func (suite *DebianGetUptimePublicTestSuite) TearDownTest() {} func (suite *DebianGetUptimePublicTestSuite) TestGetUptime() { tests := []struct { - name string - setupMock func() func() (*sysHost.InfoStat, error) - want interface{} - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysHost.InfoStat, error) + validateFunc func(time.Duration, error) }{ { name: "when GetUptime Ok", @@ -54,8 +52,11 @@ func (suite *DebianGetUptimePublicTestSuite) TestGetUptime() { return &sysHost.InfoStat{Uptime: 5 * 3600}, nil } }, - want: time.Hour * 5, - wantErr: false, + validateFunc: func(got time.Duration, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal(time.Hour*5, got) + }, }, { name: "when host.Info errors", @@ -64,8 +65,11 @@ func (suite *DebianGetUptimePublicTestSuite) TestGetUptime() { return nil, assert.AnError } }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got time.Duration, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Equal(time.Duration(0), got) + }, }, } @@ -77,23 +81,15 @@ func (suite *DebianGetUptimePublicTestSuite) TestGetUptime() { debian.InfoFn = tc.setupMock() } - got, err := debian.GetUptime() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Equal(time.Duration(0), got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(debian.GetUptime()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetUptimePublicTestSuite(t *testing.T) { +func TestDebianGetUptimePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetUptimePublicTestSuite)) } diff --git a/internal/provider/node/host/debian_update_hostname_public_test.go b/internal/provider/node/host/debian_update_hostname_public_test.go index cd77e6d00..f42fc385e 100644 --- a/internal/provider/node/host/debian_update_hostname_public_test.go +++ b/internal/provider/node/host/debian_update_hostname_public_test.go @@ -50,12 +50,10 @@ func (suite *DebianUpdateHostnamePublicTestSuite) TearDownTest() { func (suite *DebianUpdateHostnamePublicTestSuite) TestUpdateHostname() { tests := []struct { - name string - hostname string - setupMock func() *mocks.MockManager - want *host.UpdateHostnameResult - wantErr bool - wantErrType error + name string + hostname string + setupMock func() *mocks.MockManager + validateFunc func(*host.UpdateHostnameResult, error) }{ { name: "when hostname changes", @@ -72,8 +70,10 @@ func (suite *DebianUpdateHostnamePublicTestSuite) TestUpdateHostname() { ) return mock }, - want: &host.UpdateHostnameResult{Changed: true}, - wantErr: false, + validateFunc: func(got *host.UpdateHostnameResult, err error) { + suite.NoError(err) + suite.Equal(&host.UpdateHostnameResult{Changed: true}, got) + }, }, { name: "when hostname already set", @@ -85,8 +85,10 @@ func (suite *DebianUpdateHostnamePublicTestSuite) TestUpdateHostname() { Return("existing-host", nil) return mock }, - want: &host.UpdateHostnameResult{Changed: false}, - wantErr: false, + validateFunc: func(got *host.UpdateHostnameResult, err error) { + suite.NoError(err) + suite.Equal(&host.UpdateHostnameResult{Changed: false}, got) + }, }, { name: "when hostname already set with trailing newline", @@ -98,8 +100,10 @@ func (suite *DebianUpdateHostnamePublicTestSuite) TestUpdateHostname() { Return("existing-host\n", nil) return mock }, - want: &host.UpdateHostnameResult{Changed: false}, - wantErr: false, + validateFunc: func(got *host.UpdateHostnameResult, err error) { + suite.NoError(err) + suite.Equal(&host.UpdateHostnameResult{Changed: false}, got) + }, }, { name: "when hostnamectl hostname errors", @@ -111,8 +115,11 @@ func (suite *DebianUpdateHostnamePublicTestSuite) TestUpdateHostname() { Return("", assert.AnError) return mock }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got *host.UpdateHostnameResult, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Nil(got) + }, }, { name: "when hostnamectl set-hostname errors", @@ -129,8 +136,11 @@ func (suite *DebianUpdateHostnamePublicTestSuite) TestUpdateHostname() { ) return mock }, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got *host.UpdateHostnameResult, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Nil(got) + }, }, } @@ -139,22 +149,15 @@ func (suite *DebianUpdateHostnamePublicTestSuite) TestUpdateHostname() { mock := tc.setupMock() debian := host.NewDebianProvider(mock) - got, err := debian.UpdateHostname(tc.hostname) - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Nil(got) - } else { - suite.NoError(err) - suite.Equal(tc.want, got) - } + tc.validateFunc(debian.UpdateHostname(tc.hostname)) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianUpdateHostnamePublicTestSuite(t *testing.T) { +func TestDebianUpdateHostnamePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianUpdateHostnamePublicTestSuite)) } diff --git a/internal/provider/node/host/linux_get_architecture_public_test.go b/internal/provider/node/host/linux_get_architecture_public_test.go index 75dc34c06..6368ecd23 100644 --- a/internal/provider/node/host/linux_get_architecture_public_test.go +++ b/internal/provider/node/host/linux_get_architecture_public_test.go @@ -39,10 +39,15 @@ func (suite *LinuxGetArchitecturePublicTestSuite) TearDownTest() {} func (suite *LinuxGetArchitecturePublicTestSuite) TestGetArchitecture() { tests := []struct { - name string + name string + validateFunc func(string, error) }{ { name: "returns not implemented error", + validateFunc: func(result string, err error) { + suite.Empty(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -50,16 +55,15 @@ func (suite *LinuxGetArchitecturePublicTestSuite) TestGetArchitecture() { suite.Run(tc.name, func() { linux := host.NewLinuxProvider() - got, err := linux.GetArchitecture() - - suite.Empty(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.GetArchitecture()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxGetArchitecturePublicTestSuite(t *testing.T) { +func TestLinuxGetArchitecturePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxGetArchitecturePublicTestSuite)) } diff --git a/internal/provider/node/host/linux_get_cpu_count_public_test.go b/internal/provider/node/host/linux_get_cpu_count_public_test.go index 538e17921..f3004a0ef 100644 --- a/internal/provider/node/host/linux_get_cpu_count_public_test.go +++ b/internal/provider/node/host/linux_get_cpu_count_public_test.go @@ -39,10 +39,15 @@ func (suite *LinuxGetCPUCountPublicTestSuite) TearDownTest() {} func (suite *LinuxGetCPUCountPublicTestSuite) TestGetCPUCount() { tests := []struct { - name string + name string + validateFunc func(int, error) }{ { name: "returns not implemented error", + validateFunc: func(result int, err error) { + suite.Equal(0, result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -50,16 +55,15 @@ func (suite *LinuxGetCPUCountPublicTestSuite) TestGetCPUCount() { suite.Run(tc.name, func() { linux := host.NewLinuxProvider() - got, err := linux.GetCPUCount() - - suite.Equal(0, got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.GetCPUCount()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxGetCPUCountPublicTestSuite(t *testing.T) { +func TestLinuxGetCPUCountPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxGetCPUCountPublicTestSuite)) } diff --git a/internal/provider/node/host/linux_get_fqdn_public_test.go b/internal/provider/node/host/linux_get_fqdn_public_test.go index 0cbf166fa..b5b5b98d2 100644 --- a/internal/provider/node/host/linux_get_fqdn_public_test.go +++ b/internal/provider/node/host/linux_get_fqdn_public_test.go @@ -39,10 +39,15 @@ func (suite *LinuxGetFQDNPublicTestSuite) TearDownTest() {} func (suite *LinuxGetFQDNPublicTestSuite) TestGetFQDN() { tests := []struct { - name string + name string + validateFunc func(string, error) }{ { name: "returns not implemented error", + validateFunc: func(result string, err error) { + suite.Empty(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -50,16 +55,15 @@ func (suite *LinuxGetFQDNPublicTestSuite) TestGetFQDN() { suite.Run(tc.name, func() { linux := host.NewLinuxProvider() - got, err := linux.GetFQDN() - - suite.Empty(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.GetFQDN()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxGetFQDNPublicTestSuite(t *testing.T) { +func TestLinuxGetFQDNPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxGetFQDNPublicTestSuite)) } diff --git a/internal/provider/node/host/linux_get_hostname_public_test.go b/internal/provider/node/host/linux_get_hostname_public_test.go index ff574653c..62f201add 100644 --- a/internal/provider/node/host/linux_get_hostname_public_test.go +++ b/internal/provider/node/host/linux_get_hostname_public_test.go @@ -39,10 +39,15 @@ func (suite *LinuxGetHostnamePublicTestSuite) TearDownTest() {} func (suite *LinuxGetHostnamePublicTestSuite) TestGetHostname() { tests := []struct { - name string + name string + validateFunc func(string, error) }{ { name: "returns not implemented error", + validateFunc: func(result string, err error) { + suite.Empty(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -50,16 +55,15 @@ func (suite *LinuxGetHostnamePublicTestSuite) TestGetHostname() { suite.Run(tc.name, func() { linux := host.NewLinuxProvider() - got, err := linux.GetHostname() - - suite.Empty(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.GetHostname()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxGetHostnamePublicTestSuite(t *testing.T) { +func TestLinuxGetHostnamePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxGetHostnamePublicTestSuite)) } diff --git a/internal/provider/node/host/linux_get_kernel_version_public_test.go b/internal/provider/node/host/linux_get_kernel_version_public_test.go index 0f4a67724..de7fbd720 100644 --- a/internal/provider/node/host/linux_get_kernel_version_public_test.go +++ b/internal/provider/node/host/linux_get_kernel_version_public_test.go @@ -39,10 +39,15 @@ func (suite *LinuxGetKernelVersionPublicTestSuite) TearDownTest() {} func (suite *LinuxGetKernelVersionPublicTestSuite) TestGetKernelVersion() { tests := []struct { - name string + name string + validateFunc func(string, error) }{ { name: "returns not implemented error", + validateFunc: func(result string, err error) { + suite.Empty(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -50,16 +55,15 @@ func (suite *LinuxGetKernelVersionPublicTestSuite) TestGetKernelVersion() { suite.Run(tc.name, func() { linux := host.NewLinuxProvider() - got, err := linux.GetKernelVersion() - - suite.Empty(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.GetKernelVersion()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxGetKernelVersionPublicTestSuite(t *testing.T) { +func TestLinuxGetKernelVersionPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxGetKernelVersionPublicTestSuite)) } diff --git a/internal/provider/node/host/linux_get_os_info_public_test.go b/internal/provider/node/host/linux_get_os_info_public_test.go index 0e2e9d83c..430fc9ac7 100644 --- a/internal/provider/node/host/linux_get_os_info_public_test.go +++ b/internal/provider/node/host/linux_get_os_info_public_test.go @@ -39,10 +39,15 @@ func (suite *LinuxGetOSInfoPublicTestSuite) TearDownTest() {} func (suite *LinuxGetOSInfoPublicTestSuite) TestGetOSInfo() { tests := []struct { - name string + name string + validateFunc func(*host.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *host.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -50,16 +55,15 @@ func (suite *LinuxGetOSInfoPublicTestSuite) TestGetOSInfo() { suite.Run(tc.name, func() { linux := host.NewLinuxProvider() - got, err := linux.GetOSInfo() - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.GetOSInfo()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxGetOSInfoPublicTestSuite(t *testing.T) { +func TestLinuxGetOSInfoPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxGetOSInfoPublicTestSuite)) } diff --git a/internal/provider/node/host/linux_get_package_manager_public_test.go b/internal/provider/node/host/linux_get_package_manager_public_test.go index 5c9066266..c4f2869e2 100644 --- a/internal/provider/node/host/linux_get_package_manager_public_test.go +++ b/internal/provider/node/host/linux_get_package_manager_public_test.go @@ -39,10 +39,15 @@ func (suite *LinuxGetPackageManagerPublicTestSuite) TearDownTest() {} func (suite *LinuxGetPackageManagerPublicTestSuite) TestGetPackageManager() { tests := []struct { - name string + name string + validateFunc func(string, error) }{ { name: "returns not implemented error", + validateFunc: func(result string, err error) { + suite.Empty(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -50,16 +55,15 @@ func (suite *LinuxGetPackageManagerPublicTestSuite) TestGetPackageManager() { suite.Run(tc.name, func() { linux := host.NewLinuxProvider() - got, err := linux.GetPackageManager() - - suite.Empty(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.GetPackageManager()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxGetPackageManagerPublicTestSuite(t *testing.T) { +func TestLinuxGetPackageManagerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxGetPackageManagerPublicTestSuite)) } diff --git a/internal/provider/node/host/linux_get_service_manager_public_test.go b/internal/provider/node/host/linux_get_service_manager_public_test.go index 231c8b010..17992e823 100644 --- a/internal/provider/node/host/linux_get_service_manager_public_test.go +++ b/internal/provider/node/host/linux_get_service_manager_public_test.go @@ -39,10 +39,15 @@ func (suite *LinuxGetServiceManagerPublicTestSuite) TearDownTest() {} func (suite *LinuxGetServiceManagerPublicTestSuite) TestGetServiceManager() { tests := []struct { - name string + name string + validateFunc func(string, error) }{ { name: "returns not implemented error", + validateFunc: func(result string, err error) { + suite.Empty(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -50,16 +55,15 @@ func (suite *LinuxGetServiceManagerPublicTestSuite) TestGetServiceManager() { suite.Run(tc.name, func() { linux := host.NewLinuxProvider() - got, err := linux.GetServiceManager() - - suite.Empty(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.GetServiceManager()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxGetServiceManagerPublicTestSuite(t *testing.T) { +func TestLinuxGetServiceManagerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxGetServiceManagerPublicTestSuite)) } diff --git a/internal/provider/node/host/linux_get_uptime_public_test.go b/internal/provider/node/host/linux_get_uptime_public_test.go index 23d095a60..d7aab2b98 100644 --- a/internal/provider/node/host/linux_get_uptime_public_test.go +++ b/internal/provider/node/host/linux_get_uptime_public_test.go @@ -40,10 +40,15 @@ func (suite *LinuxGetUptimePublicTestSuite) TearDownTest() {} func (suite *LinuxGetUptimePublicTestSuite) TestGetUptime() { tests := []struct { - name string + name string + validateFunc func(time.Duration, error) }{ { name: "returns not implemented error", + validateFunc: func(result time.Duration, err error) { + suite.Equal(time.Duration(0), result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -51,16 +56,15 @@ func (suite *LinuxGetUptimePublicTestSuite) TestGetUptime() { suite.Run(tc.name, func() { linux := host.NewLinuxProvider() - got, err := linux.GetUptime() - - suite.Equal(time.Duration(0), got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.GetUptime()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxGetUptimePublicTestSuite(t *testing.T) { +func TestLinuxGetUptimePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxGetUptimePublicTestSuite)) } diff --git a/internal/provider/node/host/linux_update_hostname_public_test.go b/internal/provider/node/host/linux_update_hostname_public_test.go index a4933fde2..a662b5f9d 100644 --- a/internal/provider/node/host/linux_update_hostname_public_test.go +++ b/internal/provider/node/host/linux_update_hostname_public_test.go @@ -39,10 +39,15 @@ func (suite *LinuxUpdateHostnamePublicTestSuite) TearDownTest() {} func (suite *LinuxUpdateHostnamePublicTestSuite) TestUpdateHostname() { tests := []struct { - name string + name string + validateFunc func(*host.UpdateHostnameResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *host.UpdateHostnameResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -50,16 +55,15 @@ func (suite *LinuxUpdateHostnamePublicTestSuite) TestUpdateHostname() { suite.Run(tc.name, func() { linux := host.NewLinuxProvider() - got, err := linux.UpdateHostname("new-host") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.UpdateHostname("new-host")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxUpdateHostnamePublicTestSuite(t *testing.T) { +func TestLinuxUpdateHostnamePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxUpdateHostnamePublicTestSuite)) } diff --git a/internal/provider/node/host/mocks/mocks.go b/internal/provider/node/host/mocks/mocks.go index ce6b1abb2..0e7ea2ca7 100644 --- a/internal/provider/node/host/mocks/mocks.go +++ b/internal/provider/node/host/mocks/mocks.go @@ -29,12 +29,16 @@ import ( ) // NewPlainMockProvider creates a Mock without defaults. -func NewPlainMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewPlainMockProvider( + ctrl *gomock.Controller, +) *MockProvider { return NewMockProvider(ctrl) } // NewDefaultMockProvider creates a Mock with defaults. -func NewDefaultMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewDefaultMockProvider( + ctrl *gomock.Controller, +) *MockProvider { mock := NewMockProvider(ctrl) mock.EXPECT().GetUptime().Return(time.Hour*5, nil).AnyTimes() diff --git a/internal/provider/node/load/darwin_get_avg_public_test.go b/internal/provider/node/load/darwin_get_avg_public_test.go index 7ebe65b1a..bb3db8132 100644 --- a/internal/provider/node/load/darwin_get_avg_public_test.go +++ b/internal/provider/node/load/darwin_get_avg_public_test.go @@ -40,11 +40,9 @@ func (suite *DarwinGetAverageStatsPublicTestSuite) TearDownTest() {} func (suite *DarwinGetAverageStatsPublicTestSuite) TestGetAverageStats() { tests := []struct { - name string - setupMock func() func() (*sysLoad.AvgStat, error) - want *load.Result - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysLoad.AvgStat, error) + validateFunc func(*load.Result, error) }{ { name: "when GetAverageStats Ok", @@ -57,12 +55,15 @@ func (suite *DarwinGetAverageStatsPublicTestSuite) TestGetAverageStats() { }, nil } }, - want: &load.Result{ - Load1: 1.0, - Load5: 0.5, - Load15: 0.2, + validateFunc: func(got *load.Result, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal(&load.Result{ + Load1: 1.0, + Load5: 0.5, + Load15: 0.2, + }, got) }, - wantErr: false, }, { name: "when load.Avg errors", @@ -71,9 +72,11 @@ func (suite *DarwinGetAverageStatsPublicTestSuite) TestGetAverageStats() { return nil, assert.AnError } }, - want: nil, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got *load.Result, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Nil(got) + }, }, } @@ -85,23 +88,15 @@ func (suite *DarwinGetAverageStatsPublicTestSuite) TestGetAverageStats() { darwin.AvgFn = tc.setupMock() } - got, err := darwin.GetAverageStats() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Nil(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(darwin.GetAverageStats()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetAverageStatsPublicTestSuite(t *testing.T) { +func TestDarwinGetAverageStatsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetAverageStatsPublicTestSuite)) } diff --git a/internal/provider/node/load/debian_get_avg_public_test.go b/internal/provider/node/load/debian_get_avg_public_test.go index e76033f99..0132234b8 100644 --- a/internal/provider/node/load/debian_get_avg_public_test.go +++ b/internal/provider/node/load/debian_get_avg_public_test.go @@ -40,11 +40,9 @@ func (suite *DebianGetAverageStatsPublicTestSuite) TearDownTest() {} func (suite *DebianGetAverageStatsPublicTestSuite) TestGetAverageStats() { tests := []struct { - name string - setupMock func() func() (*sysLoad.AvgStat, error) - want *load.Result - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysLoad.AvgStat, error) + validateFunc func(*load.Result, error) }{ { name: "when GetAverageStats Ok", @@ -57,12 +55,15 @@ func (suite *DebianGetAverageStatsPublicTestSuite) TestGetAverageStats() { }, nil } }, - want: &load.Result{ - Load1: 1.0, - Load5: 0.5, - Load15: 0.2, + validateFunc: func(got *load.Result, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal(&load.Result{ + Load1: 1.0, + Load5: 0.5, + Load15: 0.2, + }, got) }, - wantErr: false, }, { name: "when load.Avg errors", @@ -71,9 +72,11 @@ func (suite *DebianGetAverageStatsPublicTestSuite) TestGetAverageStats() { return nil, assert.AnError } }, - want: nil, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got *load.Result, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Nil(got) + }, }, } @@ -85,23 +88,15 @@ func (suite *DebianGetAverageStatsPublicTestSuite) TestGetAverageStats() { debian.AvgFn = tc.setupMock() } - got, err := debian.GetAverageStats() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Nil(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(debian.GetAverageStats()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetAverageStatsPublicTestSuite(t *testing.T) { +func TestDebianGetAverageStatsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetAverageStatsPublicTestSuite)) } diff --git a/internal/provider/node/load/linux_get_avg_public_test.go b/internal/provider/node/load/linux_get_avg_public_test.go index a76d207d7..58a47bb64 100644 --- a/internal/provider/node/load/linux_get_avg_public_test.go +++ b/internal/provider/node/load/linux_get_avg_public_test.go @@ -39,10 +39,15 @@ func (suite *LinuxGetAverageStatsPublicTestSuite) TearDownTest() {} func (suite *LinuxGetAverageStatsPublicTestSuite) TestGetAverageStats() { tests := []struct { - name string + name string + validateFunc func(*load.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *load.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -50,16 +55,15 @@ func (suite *LinuxGetAverageStatsPublicTestSuite) TestGetAverageStats() { suite.Run(tc.name, func() { linux := load.NewLinuxProvider() - got, err := linux.GetAverageStats() - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.GetAverageStats()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxGetAverageStatsPublicTestSuite(t *testing.T) { +func TestLinuxGetAverageStatsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxGetAverageStatsPublicTestSuite)) } diff --git a/internal/provider/node/load/mocks/mocks.go b/internal/provider/node/load/mocks/mocks.go index 36f2e4e44..b8d5f4d2b 100644 --- a/internal/provider/node/load/mocks/mocks.go +++ b/internal/provider/node/load/mocks/mocks.go @@ -27,12 +27,16 @@ import ( ) // NewPlainMockProvider creates a Mock without defaults. -func NewPlainMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewPlainMockProvider( + ctrl *gomock.Controller, +) *MockProvider { return NewMockProvider(ctrl) } // NewDefaultMockProvider creates a Mock with defaults. -func NewDefaultMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewDefaultMockProvider( + ctrl *gomock.Controller, +) *MockProvider { mock := NewMockProvider(ctrl) mock.EXPECT(). diff --git a/internal/provider/node/log/darwin_public_test.go b/internal/provider/node/log/darwin_public_test.go index d7b67fedb..109c85b4d 100644 --- a/internal/provider/node/log/darwin_public_test.go +++ b/internal/provider/node/log/darwin_public_test.go @@ -42,67 +42,75 @@ func (suite *DarwinPublicTestSuite) SetupTest() { func (suite *DarwinPublicTestSuite) TestQuery() { tests := []struct { - name string + name string + validateFunc func([]oslog.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result []oslog.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Query(context.Background(), oslog.QueryOpts{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Query(context.Background(), oslog.QueryOpts{})) }) } } func (suite *DarwinPublicTestSuite) TestQueryUnit() { tests := []struct { - name string + name string + validateFunc func([]oslog.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(got []oslog.Entry, err error) { + suite.Nil(got) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.QueryUnit( + tc.validateFunc(suite.provider.QueryUnit( context.Background(), "nginx.service", oslog.QueryOpts{}, - ) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *DarwinPublicTestSuite) TestListSources() { tests := []struct { - name string + name string + validateFunc func([]string, error) }{ { name: "returns not implemented error", + validateFunc: func(result []string, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.ListSources(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.ListSources(context.Background())) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinPublicTestSuite(t *testing.T) { +func TestDarwinPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinPublicTestSuite)) } diff --git a/internal/provider/node/log/debian_public_test.go b/internal/provider/node/log/debian_public_test.go index e885ea8af..c9046b6ec 100644 --- a/internal/provider/node/log/debian_public_test.go +++ b/internal/provider/node/log/debian_public_test.go @@ -347,6 +347,8 @@ func (suite *DebianPublicTestSuite) TestListSources() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianPublicTestSuite(t *testing.T) { +func TestDebianPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianPublicTestSuite)) } diff --git a/internal/provider/node/log/linux_public_test.go b/internal/provider/node/log/linux_public_test.go index 8ca6e5bdd..d7ecf4c9a 100644 --- a/internal/provider/node/log/linux_public_test.go +++ b/internal/provider/node/log/linux_public_test.go @@ -42,67 +42,75 @@ func (suite *LinuxPublicTestSuite) SetupTest() { func (suite *LinuxPublicTestSuite) TestQuery() { tests := []struct { - name string + name string + validateFunc func([]oslog.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result []oslog.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Query(context.Background(), oslog.QueryOpts{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Query(context.Background(), oslog.QueryOpts{})) }) } } func (suite *LinuxPublicTestSuite) TestQueryUnit() { tests := []struct { - name string + name string + validateFunc func([]oslog.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(got []oslog.Entry, err error) { + suite.Nil(got) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.QueryUnit( + tc.validateFunc(suite.provider.QueryUnit( context.Background(), "nginx.service", oslog.QueryOpts{}, - ) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *LinuxPublicTestSuite) TestListSources() { tests := []struct { - name string + name string + validateFunc func([]string, error) }{ { name: "returns not implemented error", + validateFunc: func(result []string, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.ListSources(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.ListSources(context.Background())) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxPublicTestSuite)) } diff --git a/internal/provider/node/mem/darwin_get_vm_public_test.go b/internal/provider/node/mem/darwin_get_vm_public_test.go index 4a8f73eff..342bd8649 100644 --- a/internal/provider/node/mem/darwin_get_vm_public_test.go +++ b/internal/provider/node/mem/darwin_get_vm_public_test.go @@ -40,11 +40,9 @@ func (suite *DarwinGetStatsPublicTestSuite) TearDownTest() {} func (suite *DarwinGetStatsPublicTestSuite) TestGetStats() { tests := []struct { - name string - setupMock func() func() (*sysMem.VirtualMemoryStat, error) - want *mem.Result - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysMem.VirtualMemoryStat, error) + validateFunc func(*mem.Result, error) }{ { name: "when GetStats Ok", @@ -57,12 +55,15 @@ func (suite *DarwinGetStatsPublicTestSuite) TestGetStats() { }, nil } }, - want: &mem.Result{ - Total: 1024, - Free: 512, - Cached: 256, + validateFunc: func(got *mem.Result, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal(&mem.Result{ + Total: 1024, + Free: 512, + Cached: 256, + }, got) }, - wantErr: false, }, { name: "when mem.VirtualMemory errors", @@ -71,9 +72,11 @@ func (suite *DarwinGetStatsPublicTestSuite) TestGetStats() { return nil, assert.AnError } }, - want: nil, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got *mem.Result, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Nil(got) + }, }, } @@ -85,23 +88,15 @@ func (suite *DarwinGetStatsPublicTestSuite) TestGetStats() { darwin.VirtualMemoryFn = tc.setupMock() } - got, err := darwin.GetStats() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Nil(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(darwin.GetStats()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinGetStatsPublicTestSuite(t *testing.T) { +func TestDarwinGetStatsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinGetStatsPublicTestSuite)) } diff --git a/internal/provider/node/mem/debian_get_vm_public_test.go b/internal/provider/node/mem/debian_get_vm_public_test.go index 2ce9fd809..b4eb637ec 100644 --- a/internal/provider/node/mem/debian_get_vm_public_test.go +++ b/internal/provider/node/mem/debian_get_vm_public_test.go @@ -40,11 +40,9 @@ func (suite *DebianGetStatsPublicTestSuite) TearDownTest() {} func (suite *DebianGetStatsPublicTestSuite) TestGetStats() { tests := []struct { - name string - setupMock func() func() (*sysMem.VirtualMemoryStat, error) - want *mem.Result - wantErr bool - wantErrType error + name string + setupMock func() func() (*sysMem.VirtualMemoryStat, error) + validateFunc func(*mem.Result, error) }{ { name: "when GetStats Ok", @@ -57,12 +55,15 @@ func (suite *DebianGetStatsPublicTestSuite) TestGetStats() { }, nil } }, - want: &mem.Result{ - Total: 1024, - Free: 512, - Cached: 256, + validateFunc: func(got *mem.Result, err error) { + suite.NoError(err) + suite.NotNil(got) + suite.Equal(&mem.Result{ + Total: 1024, + Free: 512, + Cached: 256, + }, got) }, - wantErr: false, }, { name: "when mem.VirtualMemory errors", @@ -71,9 +72,11 @@ func (suite *DebianGetStatsPublicTestSuite) TestGetStats() { return nil, assert.AnError } }, - want: nil, - wantErr: true, - wantErrType: assert.AnError, + validateFunc: func(got *mem.Result, err error) { + suite.Error(err) + suite.ErrorContains(err, assert.AnError.Error()) + suite.Nil(got) + }, }, } @@ -85,23 +88,15 @@ func (suite *DebianGetStatsPublicTestSuite) TestGetStats() { debian.VirtualMemoryFn = tc.setupMock() } - got, err := debian.GetStats() - - if tc.wantErr { - suite.Error(err) - suite.ErrorContains(err, tc.wantErrType.Error()) - suite.Nil(got) - } else { - suite.NoError(err) - suite.NotNil(got) - suite.Equal(tc.want, got) - } + tc.validateFunc(debian.GetStats()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetStatsPublicTestSuite(t *testing.T) { +func TestDebianGetStatsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetStatsPublicTestSuite)) } diff --git a/internal/provider/node/mem/linux_get_vm_public_test.go b/internal/provider/node/mem/linux_get_vm_public_test.go index d3af6eb75..3f1a1954e 100644 --- a/internal/provider/node/mem/linux_get_vm_public_test.go +++ b/internal/provider/node/mem/linux_get_vm_public_test.go @@ -39,10 +39,15 @@ func (suite *LinuxGetStatsPublicTestSuite) TearDownTest() {} func (suite *LinuxGetStatsPublicTestSuite) TestGetStats() { tests := []struct { - name string + name string + validateFunc func(*mem.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *mem.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } @@ -50,16 +55,15 @@ func (suite *LinuxGetStatsPublicTestSuite) TestGetStats() { suite.Run(tc.name, func() { linux := mem.NewLinuxProvider() - got, err := linux.GetStats() - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(linux.GetStats()) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxGetStatsPublicTestSuite(t *testing.T) { +func TestLinuxGetStatsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxGetStatsPublicTestSuite)) } diff --git a/internal/provider/node/mem/mocks/mocks.go b/internal/provider/node/mem/mocks/mocks.go index c438fdb93..84a3bf0fd 100644 --- a/internal/provider/node/mem/mocks/mocks.go +++ b/internal/provider/node/mem/mocks/mocks.go @@ -27,12 +27,16 @@ import ( ) // NewPlainMockProvider creates a Mock without defaults. -func NewPlainMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewPlainMockProvider( + ctrl *gomock.Controller, +) *MockProvider { return NewMockProvider(ctrl) } // NewDefaultMockProvider creates a Mock with defaults. -func NewDefaultMockProvider(ctrl *gomock.Controller) *MockProvider { +func NewDefaultMockProvider( + ctrl *gomock.Controller, +) *MockProvider { mock := NewMockProvider(ctrl) mock.EXPECT().GetStats().Return(&mem.Result{ diff --git a/internal/provider/node/ntp/darwin_public_test.go b/internal/provider/node/ntp/darwin_public_test.go index 544039ee6..b51b81a66 100644 --- a/internal/provider/node/ntp/darwin_public_test.go +++ b/internal/provider/node/ntp/darwin_public_test.go @@ -42,82 +42,92 @@ func (suite *DarwinPublicTestSuite) SetupTest() { func (suite *DarwinPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*ntp.Status, error) }{ { name: "returns not implemented error", + validateFunc: func(result *ntp.Status, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background())) }) } } func (suite *DarwinPublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*ntp.CreateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *ntp.CreateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create(context.Background(), ntp.Config{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Create(context.Background(), ntp.Config{})) }) } } func (suite *DarwinPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*ntp.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *ntp.UpdateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background(), ntp.Config{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background(), ntp.Config{})) }) } } func (suite *DarwinPublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*ntp.DeleteResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *ntp.DeleteResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background())) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinPublicTestSuite(t *testing.T) { +func TestDarwinPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinPublicTestSuite)) } diff --git a/internal/provider/node/ntp/debian_public_test.go b/internal/provider/node/ntp/debian_public_test.go index ed63889d7..cd899d507 100644 --- a/internal/provider/node/ntp/debian_public_test.go +++ b/internal/provider/node/ntp/debian_public_test.go @@ -649,24 +649,30 @@ func (suite *DebianPublicTestSuite) TestParseTracking() { func (suite *DebianPublicTestSuite) TestParseSources() { tests := []struct { - name string - input string - want []string + name string + input string + validateFunc func([]string) }{ { name: "when valid CSV extracts server names", input: sourcesOutput, - want: []string{"time.cloudflare.com", "ntp.ubuntu.com"}, + validateFunc: func(got []string) { + suite.Equal([]string{"time.cloudflare.com", "ntp.ubuntu.com"}, got) + }, }, { name: "when empty input returns nil", input: "", - want: nil, + validateFunc: func(got []string) { + suite.Equal([]string(nil), got) + }, }, { name: "when line has fewer than 3 fields skips it", input: "^,*\n^,+,valid.server,2,6\n", - want: []string{"valid.server"}, + validateFunc: func(got []string) { + suite.Equal([]string{"valid.server"}, got) + }, }, } @@ -674,31 +680,37 @@ func (suite *DebianPublicTestSuite) TestParseSources() { suite.Run(tc.name, func() { got := ntp.ParseSources(tc.input) - suite.Equal(tc.want, got) + tc.validateFunc(got) }) } } func (suite *DebianPublicTestSuite) TestParseOffset() { tests := []struct { - name string - input string - want string + name string + input string + validateFunc func(string) }{ { name: "when fast returns positive offset", input: "0.000003422 seconds fast of NTP time", - want: "+0.000003422s", + validateFunc: func(got string) { + suite.Equal("+0.000003422s", got) + }, }, { name: "when slow returns negative offset", input: "0.000001834 seconds slow of NTP time", - want: "-0.000001834s", + validateFunc: func(got string) { + suite.Equal("-0.000001834s", got) + }, }, { name: "when too few fields returns empty", input: "0.0 seconds", - want: "", + validateFunc: func(got string) { + suite.Equal("", got) + }, }, } @@ -706,31 +718,37 @@ func (suite *DebianPublicTestSuite) TestParseOffset() { suite.Run(tc.name, func() { got := ntp.ParseOffset(tc.input) - suite.Equal(tc.want, got) + tc.validateFunc(got) }) } } func (suite *DebianPublicTestSuite) TestParseReferenceID() { tests := []struct { - name string - input string - want string + name string + input string + validateFunc func(string) }{ { name: "when parens present extracts hostname", input: "A29FC801 (time.cloudflare.com)", - want: "time.cloudflare.com", + validateFunc: func(got string) { + suite.Equal("time.cloudflare.com", got) + }, }, { name: "when empty parens returns empty", input: "00000000 ()", - want: "", + validateFunc: func(got string) { + suite.Equal("", got) + }, }, { name: "when no parens returns empty", input: "A29FC801", - want: "", + validateFunc: func(got string) { + suite.Equal("", got) + }, }, } @@ -738,31 +756,37 @@ func (suite *DebianPublicTestSuite) TestParseReferenceID() { suite.Run(tc.name, func() { got := ntp.ParseReferenceID(tc.input) - suite.Equal(tc.want, got) + tc.validateFunc(got) }) } } func (suite *DebianPublicTestSuite) TestGenerateContent() { tests := []struct { - name string - servers []string - want string + name string + servers []string + validateFunc func(string) }{ { name: "when multiple servers generates correct content", servers: []string{"0.pool.ntp.org", "1.pool.ntp.org"}, - want: "server 0.pool.ntp.org iburst\nserver 1.pool.ntp.org iburst\n", + validateFunc: func(got string) { + suite.Equal("server 0.pool.ntp.org iburst\nserver 1.pool.ntp.org iburst\n", got) + }, }, { name: "when single server generates one line", servers: []string{"time.google.com"}, - want: "server time.google.com iburst\n", + validateFunc: func(got string) { + suite.Equal("server time.google.com iburst\n", got) + }, }, { name: "when empty servers generates empty content", servers: []string{}, - want: "", + validateFunc: func(got string) { + suite.Equal("", got) + }, }, } @@ -770,35 +794,41 @@ func (suite *DebianPublicTestSuite) TestGenerateContent() { suite.Run(tc.name, func() { got := ntp.GenerateContent(tc.servers) - suite.Equal(tc.want, string(got)) + tc.validateFunc(string(got)) }) } } func (suite *DebianPublicTestSuite) TestComputeSHA256() { tests := []struct { - name string - data []byte + name string + data []byte + validateFunc func(string, string) }{ { name: "when given data returns consistent hash", data: []byte("server 0.pool.ntp.org iburst\n"), + validateFunc: func(got1, got2 string) { + suite.Equal(got1, got2) + suite.Len(got1, 64) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got1 := ntp.ComputeSHA256(tc.data) - got2 := ntp.ComputeSHA256(tc.data) - - suite.Equal(got1, got2) - suite.Len(got1, 64) + tc.validateFunc( + ntp.ComputeSHA256(tc.data), + ntp.ComputeSHA256(tc.data), + ) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianPublicTestSuite(t *testing.T) { +func TestDebianPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianPublicTestSuite)) } diff --git a/internal/provider/node/ntp/linux_public_test.go b/internal/provider/node/ntp/linux_public_test.go index 4a30cac42..540b71e75 100644 --- a/internal/provider/node/ntp/linux_public_test.go +++ b/internal/provider/node/ntp/linux_public_test.go @@ -42,82 +42,92 @@ func (suite *LinuxPublicTestSuite) SetupTest() { func (suite *LinuxPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*ntp.Status, error) }{ { name: "returns not implemented error", + validateFunc: func(result *ntp.Status, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background())) }) } } func (suite *LinuxPublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*ntp.CreateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *ntp.CreateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create(context.Background(), ntp.Config{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Create(context.Background(), ntp.Config{})) }) } } func (suite *LinuxPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*ntp.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *ntp.UpdateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background(), ntp.Config{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background(), ntp.Config{})) }) } } func (suite *LinuxPublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*ntp.DeleteResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *ntp.DeleteResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background())) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxPublicTestSuite)) } diff --git a/internal/provider/node/power/darwin_public_test.go b/internal/provider/node/power/darwin_public_test.go index 4f0ccf61a..ebffb4f89 100644 --- a/internal/provider/node/power/darwin_public_test.go +++ b/internal/provider/node/power/darwin_public_test.go @@ -42,44 +42,50 @@ func (suite *DarwinPublicTestSuite) SetupTest() { func (suite *DarwinPublicTestSuite) TestReboot() { tests := []struct { - name string + name string + validateFunc func(*power.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *power.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Reboot(context.Background(), power.Opts{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Reboot(context.Background(), power.Opts{})) }) } } func (suite *DarwinPublicTestSuite) TestShutdown() { tests := []struct { - name string + name string + validateFunc func(*power.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *power.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Shutdown(context.Background(), power.Opts{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Shutdown(context.Background(), power.Opts{})) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinPublicTestSuite(t *testing.T) { +func TestDarwinPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinPublicTestSuite)) } diff --git a/internal/provider/node/power/debian_public_test.go b/internal/provider/node/power/debian_public_test.go index 5c8f47396..7f08692cc 100644 --- a/internal/provider/node/power/debian_public_test.go +++ b/internal/provider/node/power/debian_public_test.go @@ -286,6 +286,8 @@ func (suite *DebianPublicTestSuite) TestShutdown() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianPublicTestSuite(t *testing.T) { +func TestDebianPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianPublicTestSuite)) } diff --git a/internal/provider/node/power/linux_public_test.go b/internal/provider/node/power/linux_public_test.go index f2c172740..c9525eb23 100644 --- a/internal/provider/node/power/linux_public_test.go +++ b/internal/provider/node/power/linux_public_test.go @@ -42,44 +42,50 @@ func (suite *LinuxPublicTestSuite) SetupTest() { func (suite *LinuxPublicTestSuite) TestReboot() { tests := []struct { - name string + name string + validateFunc func(*power.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *power.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Reboot(context.Background(), power.Opts{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Reboot(context.Background(), power.Opts{})) }) } } func (suite *LinuxPublicTestSuite) TestShutdown() { tests := []struct { - name string + name string + validateFunc func(*power.Result, error) }{ { name: "returns not implemented error", + validateFunc: func(result *power.Result, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Shutdown(context.Background(), power.Opts{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Shutdown(context.Background(), power.Opts{})) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxPublicTestSuite)) } diff --git a/internal/provider/node/process/darwin_public_test.go b/internal/provider/node/process/darwin_public_test.go index 28b870874..4de0ecf79 100644 --- a/internal/provider/node/process/darwin_public_test.go +++ b/internal/provider/node/process/darwin_public_test.go @@ -42,63 +42,71 @@ func (suite *DarwinPublicTestSuite) SetupTest() { func (suite *DarwinPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]process.Info, error) }{ { name: "returns not implemented error", + validateFunc: func(result []process.Info, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *DarwinPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*process.Info, error) }{ { name: "returns not implemented error", + validateFunc: func(result *process.Info, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), 1) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), 1)) }) } } func (suite *DarwinPublicTestSuite) TestSignal() { tests := []struct { - name string + name string + validateFunc func(*process.SignalResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *process.SignalResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Signal(context.Background(), 1, "TERM") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Signal(context.Background(), 1, "TERM")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinPublicTestSuite(t *testing.T) { +func TestDarwinPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinPublicTestSuite)) } diff --git a/internal/provider/node/process/debian_public_test.go b/internal/provider/node/process/debian_public_test.go index 549bc4566..bfdaffd6b 100644 --- a/internal/provider/node/process/debian_public_test.go +++ b/internal/provider/node/process/debian_public_test.go @@ -419,9 +419,9 @@ func (suite *DebianPublicTestSuite) TestSignal() { func (suite *DebianPublicTestSuite) TestGatherInfoErrors() { tests := []struct { - name string - setupMock func() *mocks.MockQuerier - wantErr string + name string + setupMock func() *mocks.MockQuerier + validateFunc func(*process.Info, error) }{ { name: "when Username errors returns error", @@ -432,7 +432,10 @@ func (suite *DebianPublicTestSuite) TestGatherInfoErrors() { return q }, - wantErr: "user error", + validateFunc: func(_ *process.Info, err error) { + suite.Error(err) + suite.Contains(err.Error(), "user error") + }, }, { name: "when Status errors returns error", @@ -444,7 +447,10 @@ func (suite *DebianPublicTestSuite) TestGatherInfoErrors() { return q }, - wantErr: "status error", + validateFunc: func(_ *process.Info, err error) { + suite.Error(err) + suite.Contains(err.Error(), "status error") + }, }, { name: "when CPUPercent errors returns error", @@ -457,7 +463,10 @@ func (suite *DebianPublicTestSuite) TestGatherInfoErrors() { return q }, - wantErr: "cpu error", + validateFunc: func(_ *process.Info, err error) { + suite.Error(err) + suite.Contains(err.Error(), "cpu error") + }, }, { name: "when MemoryPercent errors returns error", @@ -471,7 +480,10 @@ func (suite *DebianPublicTestSuite) TestGatherInfoErrors() { return q }, - wantErr: "mem percent error", + validateFunc: func(_ *process.Info, err error) { + suite.Error(err) + suite.Contains(err.Error(), "mem percent error") + }, }, { name: "when MemoryInfo errors returns error", @@ -486,7 +498,10 @@ func (suite *DebianPublicTestSuite) TestGatherInfoErrors() { return q }, - wantErr: "mem info error", + validateFunc: func(_ *process.Info, err error) { + suite.Error(err) + suite.Contains(err.Error(), "mem info error") + }, }, { name: "when Cmdline errors returns error", @@ -502,7 +517,10 @@ func (suite *DebianPublicTestSuite) TestGatherInfoErrors() { return q }, - wantErr: "cmdline error", + validateFunc: func(_ *process.Info, err error) { + suite.Error(err) + suite.Contains(err.Error(), "cmdline error") + }, }, { name: "when CreateTime errors returns error", @@ -519,7 +537,10 @@ func (suite *DebianPublicTestSuite) TestGatherInfoErrors() { return q }, - wantErr: "create time error", + validateFunc: func(_ *process.Info, err error) { + suite.Error(err) + suite.Contains(err.Error(), "create time error") + }, }, } @@ -529,10 +550,7 @@ func (suite *DebianPublicTestSuite) TestGatherInfoErrors() { suite.mockLister.EXPECT().NewProcess(int32(1)).Return(q, nil) - _, err := suite.provider.Get(context.Background(), 1) - - suite.Error(err) - suite.Contains(err.Error(), tc.wantErr) + tc.validateFunc(suite.provider.Get(context.Background(), 1)) }) } } @@ -611,6 +629,8 @@ func (suite *DebianPublicTestSuite) TestDefaultOSFunctions() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianPublicTestSuite(t *testing.T) { +func TestDebianPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianPublicTestSuite)) } diff --git a/internal/provider/node/process/linux_public_test.go b/internal/provider/node/process/linux_public_test.go index 7328915fc..bf9d9b253 100644 --- a/internal/provider/node/process/linux_public_test.go +++ b/internal/provider/node/process/linux_public_test.go @@ -42,63 +42,71 @@ func (suite *LinuxPublicTestSuite) SetupTest() { func (suite *LinuxPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]process.Info, error) }{ { name: "returns not implemented error", + validateFunc: func(result []process.Info, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *LinuxPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*process.Info, error) }{ { name: "returns not implemented error", + validateFunc: func(result *process.Info, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), 1) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), 1)) }) } } func (suite *LinuxPublicTestSuite) TestSignal() { tests := []struct { - name string + name string + validateFunc func(*process.SignalResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *process.SignalResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Signal(context.Background(), 1, "TERM") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Signal(context.Background(), 1, "TERM")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxPublicTestSuite)) } diff --git a/internal/provider/node/service/darwin_public_test.go b/internal/provider/node/service/darwin_public_test.go index 2f9961eb1..9ff0057d3 100644 --- a/internal/provider/node/service/darwin_public_test.go +++ b/internal/provider/node/service/darwin_public_test.go @@ -42,202 +42,224 @@ func (suite *DarwinPublicTestSuite) SetupTest() { func (suite *DarwinPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]service.Info, error) }{ { name: "returns not implemented error", + validateFunc: func(result []service.Info, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *DarwinPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*service.Info, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.Info, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), "nginx") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), "nginx")) }) } } func (suite *DarwinPublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*service.CreateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(got *service.CreateResult, err error) { + suite.Nil(got) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create( + tc.validateFunc(suite.provider.Create( context.Background(), service.Entry{Name: "test"}, - ) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *DarwinPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*service.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(got *service.UpdateResult, err error) { + suite.Nil(got) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update( + tc.validateFunc(suite.provider.Update( context.Background(), service.Entry{Name: "test"}, - ) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *DarwinPublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*service.DeleteResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.DeleteResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background(), "test") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background(), "test")) }) } } func (suite *DarwinPublicTestSuite) TestStart() { tests := []struct { - name string + name string + validateFunc func(*service.ActionResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.ActionResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Start(context.Background(), "nginx") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Start(context.Background(), "nginx")) }) } } func (suite *DarwinPublicTestSuite) TestStop() { tests := []struct { - name string + name string + validateFunc func(*service.ActionResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.ActionResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Stop(context.Background(), "nginx") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Stop(context.Background(), "nginx")) }) } } func (suite *DarwinPublicTestSuite) TestRestart() { tests := []struct { - name string + name string + validateFunc func(*service.ActionResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.ActionResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Restart(context.Background(), "nginx") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Restart(context.Background(), "nginx")) }) } } func (suite *DarwinPublicTestSuite) TestEnable() { tests := []struct { - name string + name string + validateFunc func(*service.ActionResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.ActionResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Enable(context.Background(), "nginx") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Enable(context.Background(), "nginx")) }) } } func (suite *DarwinPublicTestSuite) TestDisable() { tests := []struct { - name string + name string + validateFunc func(*service.ActionResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.ActionResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Disable(context.Background(), "nginx") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Disable(context.Background(), "nginx")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinPublicTestSuite(t *testing.T) { +func TestDarwinPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinPublicTestSuite)) } diff --git a/internal/provider/node/service/debian_action_public_test.go b/internal/provider/node/service/debian_action_public_test.go index fa0176506..5dfa65835 100644 --- a/internal/provider/node/service/debian_action_public_test.go +++ b/internal/provider/node/service/debian_action_public_test.go @@ -505,6 +505,8 @@ func (suite *DebianActionPublicTestSuite) TestDisable() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianActionPublicTestSuite(t *testing.T) { +func TestDebianActionPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianActionPublicTestSuite)) } diff --git a/internal/provider/node/service/debian_get_public_test.go b/internal/provider/node/service/debian_get_public_test.go index d2792c097..12c097083 100644 --- a/internal/provider/node/service/debian_get_public_test.go +++ b/internal/provider/node/service/debian_get_public_test.go @@ -239,6 +239,8 @@ func (suite *DebianGetPublicTestSuite) TestGet() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianGetPublicTestSuite(t *testing.T) { +func TestDebianGetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianGetPublicTestSuite)) } diff --git a/internal/provider/node/service/debian_list_public_test.go b/internal/provider/node/service/debian_list_public_test.go index 3a5fbd2ee..797b29bc8 100644 --- a/internal/provider/node/service/debian_list_public_test.go +++ b/internal/provider/node/service/debian_list_public_test.go @@ -283,6 +283,8 @@ func (suite *DebianListPublicTestSuite) TestList() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianListPublicTestSuite(t *testing.T) { +func TestDebianListPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianListPublicTestSuite)) } diff --git a/internal/provider/node/service/debian_unit_public_test.go b/internal/provider/node/service/debian_unit_public_test.go index fa86f97d2..fe502d751 100644 --- a/internal/provider/node/service/debian_unit_public_test.go +++ b/internal/provider/node/service/debian_unit_public_test.go @@ -682,6 +682,8 @@ func (suite *DebianUnitPublicTestSuite) TestDelete() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianUnitPublicTestSuite(t *testing.T) { +func TestDebianUnitPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianUnitPublicTestSuite)) } diff --git a/internal/provider/node/service/linux_public_test.go b/internal/provider/node/service/linux_public_test.go index 8c26e3fb6..b0eff5e2c 100644 --- a/internal/provider/node/service/linux_public_test.go +++ b/internal/provider/node/service/linux_public_test.go @@ -42,202 +42,224 @@ func (suite *LinuxPublicTestSuite) SetupTest() { func (suite *LinuxPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]service.Info, error) }{ { name: "returns not implemented error", + validateFunc: func(result []service.Info, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *LinuxPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*service.Info, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.Info, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), "nginx") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), "nginx")) }) } } func (suite *LinuxPublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*service.CreateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(got *service.CreateResult, err error) { + suite.Nil(got) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create( + tc.validateFunc(suite.provider.Create( context.Background(), service.Entry{Name: "test"}, - ) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *LinuxPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*service.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(got *service.UpdateResult, err error) { + suite.Nil(got) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update( + tc.validateFunc(suite.provider.Update( context.Background(), service.Entry{Name: "test"}, - ) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *LinuxPublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*service.DeleteResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.DeleteResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background(), "test") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background(), "test")) }) } } func (suite *LinuxPublicTestSuite) TestStart() { tests := []struct { - name string + name string + validateFunc func(*service.ActionResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.ActionResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Start(context.Background(), "nginx") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Start(context.Background(), "nginx")) }) } } func (suite *LinuxPublicTestSuite) TestStop() { tests := []struct { - name string + name string + validateFunc func(*service.ActionResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.ActionResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Stop(context.Background(), "nginx") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Stop(context.Background(), "nginx")) }) } } func (suite *LinuxPublicTestSuite) TestRestart() { tests := []struct { - name string + name string + validateFunc func(*service.ActionResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.ActionResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Restart(context.Background(), "nginx") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Restart(context.Background(), "nginx")) }) } } func (suite *LinuxPublicTestSuite) TestEnable() { tests := []struct { - name string + name string + validateFunc func(*service.ActionResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.ActionResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Enable(context.Background(), "nginx") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Enable(context.Background(), "nginx")) }) } } func (suite *LinuxPublicTestSuite) TestDisable() { tests := []struct { - name string + name string + validateFunc func(*service.ActionResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *service.ActionResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Disable(context.Background(), "nginx") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Disable(context.Background(), "nginx")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxPublicTestSuite)) } diff --git a/internal/provider/node/sysctl/darwin_public_test.go b/internal/provider/node/sysctl/darwin_public_test.go index c2eeeea50..d13b4c071 100644 --- a/internal/provider/node/sysctl/darwin_public_test.go +++ b/internal/provider/node/sysctl/darwin_public_test.go @@ -42,101 +42,113 @@ func (suite *DarwinPublicTestSuite) SetupTest() { func (suite *DarwinPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]sysctl.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result []sysctl.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *DarwinPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*sysctl.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result *sysctl.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), "net.ipv4.ip_forward") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), "net.ipv4.ip_forward")) }) } } func (suite *DarwinPublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*sysctl.CreateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *sysctl.CreateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create(context.Background(), sysctl.Entry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Create(context.Background(), sysctl.Entry{})) }) } } func (suite *DarwinPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*sysctl.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *sysctl.UpdateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background(), sysctl.Entry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background(), sysctl.Entry{})) }) } } func (suite *DarwinPublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*sysctl.DeleteResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *sysctl.DeleteResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background(), "net.ipv4.ip_forward") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background(), "net.ipv4.ip_forward")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinPublicTestSuite(t *testing.T) { +func TestDarwinPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinPublicTestSuite)) } diff --git a/internal/provider/node/sysctl/debian_public_test.go b/internal/provider/node/sysctl/debian_public_test.go index 92b1cefbe..f054a4bb5 100644 --- a/internal/provider/node/sysctl/debian_public_test.go +++ b/internal/provider/node/sysctl/debian_public_test.go @@ -1389,6 +1389,8 @@ func computeTestSHA256( // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianPublicTestSuite(t *testing.T) { +func TestDebianPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianPublicTestSuite)) } diff --git a/internal/provider/node/sysctl/export_test.go b/internal/provider/node/sysctl/export_test.go index 4d44d809e..d2d40d14c 100644 --- a/internal/provider/node/sysctl/export_test.go +++ b/internal/provider/node/sysctl/export_test.go @@ -23,7 +23,9 @@ package sysctl import "encoding/json" // SetMarshalJSON overrides the marshal function for testing. -func SetMarshalJSON(fn func(interface{}) ([]byte, error)) { +func SetMarshalJSON( + fn func(interface{}) ([]byte, error), +) { marshalJSON = fn } diff --git a/internal/provider/node/sysctl/linux_public_test.go b/internal/provider/node/sysctl/linux_public_test.go index 25fb140e3..1edd7fdc6 100644 --- a/internal/provider/node/sysctl/linux_public_test.go +++ b/internal/provider/node/sysctl/linux_public_test.go @@ -42,101 +42,113 @@ func (suite *LinuxPublicTestSuite) SetupTest() { func (suite *LinuxPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]sysctl.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result []sysctl.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *LinuxPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*sysctl.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result *sysctl.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), "net.ipv4.ip_forward") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), "net.ipv4.ip_forward")) }) } } func (suite *LinuxPublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*sysctl.CreateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *sysctl.CreateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create(context.Background(), sysctl.Entry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Create(context.Background(), sysctl.Entry{})) }) } } func (suite *LinuxPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*sysctl.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *sysctl.UpdateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background(), sysctl.Entry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background(), sysctl.Entry{})) }) } } func (suite *LinuxPublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*sysctl.DeleteResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *sysctl.DeleteResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background(), "net.ipv4.ip_forward") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background(), "net.ipv4.ip_forward")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxPublicTestSuite)) } diff --git a/internal/provider/node/timezone/darwin_public_test.go b/internal/provider/node/timezone/darwin_public_test.go index a23e3df92..5a1fc5ca7 100644 --- a/internal/provider/node/timezone/darwin_public_test.go +++ b/internal/provider/node/timezone/darwin_public_test.go @@ -42,44 +42,50 @@ func (suite *DarwinPublicTestSuite) SetupTest() { func (suite *DarwinPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*timezone.Info, error) }{ { name: "returns not implemented error", + validateFunc: func(result *timezone.Info, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background())) }) } } func (suite *DarwinPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*timezone.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *timezone.UpdateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background(), "America/New_York") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background(), "America/New_York")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinPublicTestSuite(t *testing.T) { +func TestDarwinPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinPublicTestSuite)) } diff --git a/internal/provider/node/timezone/debian_public_test.go b/internal/provider/node/timezone/debian_public_test.go index c4a83a13e..b058b5bed 100644 --- a/internal/provider/node/timezone/debian_public_test.go +++ b/internal/provider/node/timezone/debian_public_test.go @@ -221,6 +221,8 @@ func (suite *DebianPublicTestSuite) TestUpdate() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianPublicTestSuite(t *testing.T) { +func TestDebianPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianPublicTestSuite)) } diff --git a/internal/provider/node/timezone/linux_public_test.go b/internal/provider/node/timezone/linux_public_test.go index 2dbb04d00..581802117 100644 --- a/internal/provider/node/timezone/linux_public_test.go +++ b/internal/provider/node/timezone/linux_public_test.go @@ -42,44 +42,50 @@ func (suite *LinuxPublicTestSuite) SetupTest() { func (suite *LinuxPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*timezone.Info, error) }{ { name: "returns not implemented error", + validateFunc: func(result *timezone.Info, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background())) }) } } func (suite *LinuxPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*timezone.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *timezone.UpdateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background(), "America/New_York") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background(), "America/New_York")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxPublicTestSuite)) } diff --git a/internal/provider/node/user/darwin_public_test.go b/internal/provider/node/user/darwin_public_test.go index 60e59fe94..31ba57ecb 100644 --- a/internal/provider/node/user/darwin_public_test.go +++ b/internal/provider/node/user/darwin_public_test.go @@ -44,294 +44,324 @@ func (suite *DarwinPublicTestSuite) SetupTest() { func (suite *DarwinPublicTestSuite) TestListUsers() { tests := []struct { - name string + name string + validateFunc func([]user.User, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result []user.User, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.ListUsers(suite.ctx) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.ListUsers(suite.ctx)) }) } } func (suite *DarwinPublicTestSuite) TestGetUser() { tests := []struct { - name string + name string + validateFunc func(*user.User, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.User, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.GetUser(suite.ctx, "testuser") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.GetUser(suite.ctx, "testuser")) }) } } func (suite *DarwinPublicTestSuite) TestCreateUser() { tests := []struct { - name string + name string + validateFunc func(*user.Result, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.Result, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.CreateUser(suite.ctx, user.CreateUserOpts{ + tc.validateFunc(suite.provider.CreateUser(suite.ctx, user.CreateUserOpts{ Name: "testuser", - }) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + })) }) } } func (suite *DarwinPublicTestSuite) TestUpdateUser() { tests := []struct { - name string + name string + validateFunc func(*user.Result, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.Result, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.UpdateUser(suite.ctx, "testuser", user.UpdateUserOpts{}) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.UpdateUser(suite.ctx, "testuser", user.UpdateUserOpts{})) }) } } func (suite *DarwinPublicTestSuite) TestDeleteUser() { tests := []struct { - name string + name string + validateFunc func(*user.Result, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.Result, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.DeleteUser(suite.ctx, "testuser") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.DeleteUser(suite.ctx, "testuser")) }) } } func (suite *DarwinPublicTestSuite) TestChangePassword() { tests := []struct { - name string + name string + validateFunc func(*user.Result, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.Result, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.ChangePassword(suite.ctx, "testuser", "secret") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.ChangePassword(suite.ctx, "testuser", "secret")) }) } } func (suite *DarwinPublicTestSuite) TestListGroups() { tests := []struct { - name string + name string + validateFunc func([]user.Group, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result []user.Group, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.ListGroups(suite.ctx) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.ListGroups(suite.ctx)) }) } } func (suite *DarwinPublicTestSuite) TestGetGroup() { tests := []struct { - name string + name string + validateFunc func(*user.Group, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.Group, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.GetGroup(suite.ctx, "testgroup") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.GetGroup(suite.ctx, "testgroup")) }) } } func (suite *DarwinPublicTestSuite) TestCreateGroup() { tests := []struct { - name string + name string + validateFunc func(*user.GroupResult, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.GroupResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.CreateGroup(suite.ctx, user.CreateGroupOpts{ + tc.validateFunc(suite.provider.CreateGroup(suite.ctx, user.CreateGroupOpts{ Name: "testgroup", - }) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + })) }) } } func (suite *DarwinPublicTestSuite) TestUpdateGroup() { tests := []struct { - name string + name string + validateFunc func(*user.GroupResult, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.GroupResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.UpdateGroup( + tc.validateFunc(suite.provider.UpdateGroup( suite.ctx, "testgroup", user.UpdateGroupOpts{}, - ) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *DarwinPublicTestSuite) TestDeleteGroup() { tests := []struct { - name string + name string + validateFunc func(*user.GroupResult, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.GroupResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.DeleteGroup(suite.ctx, "testgroup") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.DeleteGroup(suite.ctx, "testgroup")) }) } } func (suite *DarwinPublicTestSuite) TestListKeys() { tests := []struct { - name string + name string + validateFunc func([]user.SSHKey, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result []user.SSHKey, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.ListKeys(suite.ctx, "testuser") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.ListKeys(suite.ctx, "testuser")) }) } } func (suite *DarwinPublicTestSuite) TestAddKey() { tests := []struct { - name string + name string + validateFunc func(*user.SSHKeyResult, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.SSHKeyResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.AddKey(suite.ctx, "testuser", user.SSHKey{ + tc.validateFunc(suite.provider.AddKey(suite.ctx, "testuser", user.SSHKey{ RawLine: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI test@example", - }) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + })) }) } } func (suite *DarwinPublicTestSuite) TestRemoveKey() { tests := []struct { - name string + name string + validateFunc func(*user.SSHKeyResult, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.SSHKeyResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.RemoveKey(suite.ctx, "testuser", "SHA256:abc123") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.RemoveKey(suite.ctx, "testuser", "SHA256:abc123")) }) } } -func TestDarwinPublicTestSuite(t *testing.T) { +func TestDarwinPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinPublicTestSuite)) } diff --git a/internal/provider/node/user/debian_public_test.go b/internal/provider/node/user/debian_public_test.go index b008e8956..e43e67c1f 100644 --- a/internal/provider/node/user/debian_public_test.go +++ b/internal/provider/node/user/debian_public_test.go @@ -83,7 +83,9 @@ func (suite *DebianPublicTestSuite) TearDownTest() { suite.ctrl.Finish() } -func (suite *DebianPublicTestSuite) writePasswd(content string) { +func (suite *DebianPublicTestSuite) writePasswd( + content string, +) { _ = suite.memFs.MkdirAll("/etc", 0o755) f, err := suite.memFs.Create("/etc/passwd") @@ -94,7 +96,9 @@ func (suite *DebianPublicTestSuite) writePasswd(content string) { suite.Require().NoError(f.Close()) } -func (suite *DebianPublicTestSuite) writeGroup(content string) { +func (suite *DebianPublicTestSuite) writeGroup( + content string, +) { _ = suite.memFs.MkdirAll("/etc", 0o755) f, err := suite.memFs.Create("/etc/group") @@ -1084,6 +1088,8 @@ func (suite *DebianPublicTestSuite) TestDeleteGroup() { } } -func TestDebianPublicTestSuite(t *testing.T) { +func TestDebianPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianPublicTestSuite)) } diff --git a/internal/provider/node/user/debian_ssh_key_public_test.go b/internal/provider/node/user/debian_ssh_key_public_test.go index 35be85b91..df6bc792e 100644 --- a/internal/provider/node/user/debian_ssh_key_public_test.go +++ b/internal/provider/node/user/debian_ssh_key_public_test.go @@ -85,7 +85,9 @@ func (suite *DebianSSHKeyPublicTestSuite) TearDownTest() { suite.ctrl.Finish() } -func (suite *DebianSSHKeyPublicTestSuite) writePasswd(content string) { +func (suite *DebianSSHKeyPublicTestSuite) writePasswd( + content string, +) { _ = suite.memFs.MkdirAll("/etc", 0o755) f, err := suite.memFs.Create("/etc/passwd") @@ -112,7 +114,9 @@ func (suite *DebianSSHKeyPublicTestSuite) writeAuthorizedKeys( suite.Require().NoError(f.Close()) } -func (suite *DebianSSHKeyPublicTestSuite) readFile(path string) string { +func (suite *DebianSSHKeyPublicTestSuite) readFile( + path string, +) string { content, err := suite.memFs.ReadFile(path) suite.Require().NoError(err) @@ -910,6 +914,8 @@ func (suite *DebianSSHKeyPublicTestSuite) TestRemoveKey() { } } -func TestDebianSSHKeyPublicTestSuite(t *testing.T) { +func TestDebianSSHKeyPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianSSHKeyPublicTestSuite)) } diff --git a/internal/provider/node/user/linux_public_test.go b/internal/provider/node/user/linux_public_test.go index 1a5bf7a7d..83b3ec17f 100644 --- a/internal/provider/node/user/linux_public_test.go +++ b/internal/provider/node/user/linux_public_test.go @@ -44,294 +44,324 @@ func (suite *LinuxPublicTestSuite) SetupTest() { func (suite *LinuxPublicTestSuite) TestListUsers() { tests := []struct { - name string + name string + validateFunc func([]user.User, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result []user.User, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.ListUsers(suite.ctx) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.ListUsers(suite.ctx)) }) } } func (suite *LinuxPublicTestSuite) TestGetUser() { tests := []struct { - name string + name string + validateFunc func(*user.User, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.User, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.GetUser(suite.ctx, "testuser") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.GetUser(suite.ctx, "testuser")) }) } } func (suite *LinuxPublicTestSuite) TestCreateUser() { tests := []struct { - name string + name string + validateFunc func(*user.Result, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.Result, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.CreateUser(suite.ctx, user.CreateUserOpts{ + tc.validateFunc(suite.provider.CreateUser(suite.ctx, user.CreateUserOpts{ Name: "testuser", - }) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + })) }) } } func (suite *LinuxPublicTestSuite) TestUpdateUser() { tests := []struct { - name string + name string + validateFunc func(*user.Result, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.Result, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.UpdateUser(suite.ctx, "testuser", user.UpdateUserOpts{}) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.UpdateUser(suite.ctx, "testuser", user.UpdateUserOpts{})) }) } } func (suite *LinuxPublicTestSuite) TestDeleteUser() { tests := []struct { - name string + name string + validateFunc func(*user.Result, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.Result, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.DeleteUser(suite.ctx, "testuser") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.DeleteUser(suite.ctx, "testuser")) }) } } func (suite *LinuxPublicTestSuite) TestChangePassword() { tests := []struct { - name string + name string + validateFunc func(*user.Result, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.Result, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.ChangePassword(suite.ctx, "testuser", "secret") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.ChangePassword(suite.ctx, "testuser", "secret")) }) } } func (suite *LinuxPublicTestSuite) TestListGroups() { tests := []struct { - name string + name string + validateFunc func([]user.Group, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result []user.Group, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.ListGroups(suite.ctx) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.ListGroups(suite.ctx)) }) } } func (suite *LinuxPublicTestSuite) TestGetGroup() { tests := []struct { - name string + name string + validateFunc func(*user.Group, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.Group, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.GetGroup(suite.ctx, "testgroup") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.GetGroup(suite.ctx, "testgroup")) }) } } func (suite *LinuxPublicTestSuite) TestCreateGroup() { tests := []struct { - name string + name string + validateFunc func(*user.GroupResult, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.GroupResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.CreateGroup(suite.ctx, user.CreateGroupOpts{ + tc.validateFunc(suite.provider.CreateGroup(suite.ctx, user.CreateGroupOpts{ Name: "testgroup", - }) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + })) }) } } func (suite *LinuxPublicTestSuite) TestUpdateGroup() { tests := []struct { - name string + name string + validateFunc func(*user.GroupResult, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.GroupResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.UpdateGroup( + tc.validateFunc(suite.provider.UpdateGroup( suite.ctx, "testgroup", user.UpdateGroupOpts{}, - ) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + )) }) } } func (suite *LinuxPublicTestSuite) TestDeleteGroup() { tests := []struct { - name string + name string + validateFunc func(*user.GroupResult, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.GroupResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.DeleteGroup(suite.ctx, "testgroup") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.DeleteGroup(suite.ctx, "testgroup")) }) } } func (suite *LinuxPublicTestSuite) TestListKeys() { tests := []struct { - name string + name string + validateFunc func([]user.SSHKey, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result []user.SSHKey, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.ListKeys(suite.ctx, "testuser") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.ListKeys(suite.ctx, "testuser")) }) } } func (suite *LinuxPublicTestSuite) TestAddKey() { tests := []struct { - name string + name string + validateFunc func(*user.SSHKeyResult, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.SSHKeyResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.AddKey(suite.ctx, "testuser", user.SSHKey{ + tc.validateFunc(suite.provider.AddKey(suite.ctx, "testuser", user.SSHKey{ RawLine: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI test@example", - }) - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + })) }) } } func (suite *LinuxPublicTestSuite) TestRemoveKey() { tests := []struct { - name string + name string + validateFunc func(*user.SSHKeyResult, error) }{ { name: "returns ErrUnsupported", + validateFunc: func(result *user.SSHKeyResult, err error) { + suite.Error(err) + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - result, err := suite.provider.RemoveKey(suite.ctx, "testuser", "SHA256:abc123") - - suite.Error(err) - suite.Nil(result) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.RemoveKey(suite.ctx, "testuser", "SHA256:abc123")) }) } } -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxPublicTestSuite)) } diff --git a/internal/provider/scheduled/cron/darwin_public_test.go b/internal/provider/scheduled/cron/darwin_public_test.go index 20d143d4a..424a8381e 100644 --- a/internal/provider/scheduled/cron/darwin_public_test.go +++ b/internal/provider/scheduled/cron/darwin_public_test.go @@ -42,101 +42,113 @@ func (suite *DarwinPublicTestSuite) SetupTest() { func (suite *DarwinPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]cron.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result []cron.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *DarwinPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*cron.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result *cron.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), "test") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), "test")) }) } } func (suite *DarwinPublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*cron.CreateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *cron.CreateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create(context.Background(), cron.Entry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Create(context.Background(), cron.Entry{})) }) } } func (suite *DarwinPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*cron.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *cron.UpdateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background(), cron.Entry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background(), cron.Entry{})) }) } } func (suite *DarwinPublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*cron.DeleteResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *cron.DeleteResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background(), "test") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background(), "test")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDarwinPublicTestSuite(t *testing.T) { +func TestDarwinPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DarwinPublicTestSuite)) } diff --git a/internal/provider/scheduled/cron/debian_public_test.go b/internal/provider/scheduled/cron/debian_public_test.go index 6338b4e97..7e1dc9e95 100644 --- a/internal/provider/scheduled/cron/debian_public_test.go +++ b/internal/provider/scheduled/cron/debian_public_test.go @@ -1012,6 +1012,8 @@ func (suite *DebianPublicTestSuite) TestGet() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestDebianPublicTestSuite(t *testing.T) { +func TestDebianPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DebianPublicTestSuite)) } diff --git a/internal/provider/scheduled/cron/linux_public_test.go b/internal/provider/scheduled/cron/linux_public_test.go index 890a572e4..30134895a 100644 --- a/internal/provider/scheduled/cron/linux_public_test.go +++ b/internal/provider/scheduled/cron/linux_public_test.go @@ -42,101 +42,113 @@ func (suite *LinuxPublicTestSuite) SetupTest() { func (suite *LinuxPublicTestSuite) TestList() { tests := []struct { - name string + name string + validateFunc func([]cron.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result []cron.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.List(context.Background()) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.List(context.Background())) }) } } func (suite *LinuxPublicTestSuite) TestGet() { tests := []struct { - name string + name string + validateFunc func(*cron.Entry, error) }{ { name: "returns not implemented error", + validateFunc: func(result *cron.Entry, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Get(context.Background(), "test") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Get(context.Background(), "test")) }) } } func (suite *LinuxPublicTestSuite) TestCreate() { tests := []struct { - name string + name string + validateFunc func(*cron.CreateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *cron.CreateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Create(context.Background(), cron.Entry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Create(context.Background(), cron.Entry{})) }) } } func (suite *LinuxPublicTestSuite) TestUpdate() { tests := []struct { - name string + name string + validateFunc func(*cron.UpdateResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *cron.UpdateResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Update(context.Background(), cron.Entry{}) - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Update(context.Background(), cron.Entry{})) }) } } func (suite *LinuxPublicTestSuite) TestDelete() { tests := []struct { - name string + name string + validateFunc func(*cron.DeleteResult, error) }{ { name: "returns not implemented error", + validateFunc: func(result *cron.DeleteResult, err error) { + suite.Nil(result) + suite.ErrorIs(err, provider.ErrUnsupported) + }, }, } for _, tc := range tests { suite.Run(tc.name, func() { - got, err := suite.provider.Delete(context.Background(), "test") - - suite.Nil(got) - suite.ErrorIs(err, provider.ErrUnsupported) + tc.validateFunc(suite.provider.Delete(context.Background(), "test")) }) } } // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestLinuxPublicTestSuite(t *testing.T) { +func TestLinuxPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LinuxPublicTestSuite)) } diff --git a/internal/telemetry/metrics/health.go b/internal/telemetry/metrics/health.go index b261bb81a..034d0aafa 100644 --- a/internal/telemetry/metrics/health.go +++ b/internal/telemetry/metrics/health.go @@ -27,7 +27,9 @@ import ( ) // handleHealth handles GET /health and always returns 200 with {"status":"ok"}. -func (s *Server) handleHealth(c echo.Context) error { +func (s *Server) handleHealth( + c echo.Context, +) error { return c.JSON(http.StatusOK, map[string]string{ "status": "ok", }) @@ -36,7 +38,9 @@ func (s *Server) handleHealth(c echo.Context) error { // handleReady handles GET /health/ready. It returns 503 when no readiness // func is configured or the readiness func returns an error, and 200 when // the readiness func returns nil. -func (s *Server) handleReady(c echo.Context) error { +func (s *Server) handleReady( + c echo.Context, +) error { if s.readinessFunc == nil { return c.JSON(http.StatusServiceUnavailable, map[string]string{ "status": "not_ready", diff --git a/internal/telemetry/metrics/health_public_test.go b/internal/telemetry/metrics/health_public_test.go index 280a3c5ba..8f64b9e8a 100644 --- a/internal/telemetry/metrics/health_public_test.go +++ b/internal/telemetry/metrics/health_public_test.go @@ -115,31 +115,43 @@ func (s *HealthPublicTestSuite) TestHandleReady() { name string readinessFunc func() error wantStatusCode int - wantBodySubstr string + validateFunc func([]byte, error) }{ { name: "returns 503 when no readiness func configured", readinessFunc: nil, wantStatusCode: http.StatusServiceUnavailable, - wantBodySubstr: "not_ready", + validateFunc: func(body []byte, err error) { + s.Require().NoError(err) + s.Contains(string(body), "not_ready") + }, }, { name: "returns 503 when readiness func returns error", readinessFunc: func() error { return errors.New("dependency unavailable") }, wantStatusCode: http.StatusServiceUnavailable, - wantBodySubstr: "dependency unavailable", + validateFunc: func(body []byte, err error) { + s.Require().NoError(err) + s.Contains(string(body), "dependency unavailable") + }, }, { name: "returns 200 when readiness func returns nil", readinessFunc: func() error { return nil }, wantStatusCode: http.StatusOK, - wantBodySubstr: "ready", + validateFunc: func(body []byte, err error) { + s.Require().NoError(err) + s.Contains(string(body), "ready") + }, }, { name: "returns Content-Type application/json", readinessFunc: func() error { return nil }, wantStatusCode: http.StatusOK, - wantBodySubstr: "ready", + validateFunc: func(body []byte, err error) { + s.Require().NoError(err) + s.Contains(string(body), "ready") + }, }, } @@ -171,9 +183,7 @@ func (s *HealthPublicTestSuite) TestHandleReady() { s.Equal(tc.wantStatusCode, resp.StatusCode) s.Equal("application/json", resp.Header.Get("Content-Type")) - body, err := io.ReadAll(resp.Body) - s.Require().NoError(err) - s.Contains(string(body), tc.wantBodySubstr) + tc.validateFunc(io.ReadAll(resp.Body)) }) } } diff --git a/internal/telemetry/metrics/server.go b/internal/telemetry/metrics/server.go index 691b9c0c4..83c47d82b 100644 --- a/internal/telemetry/metrics/server.go +++ b/internal/telemetry/metrics/server.go @@ -116,7 +116,9 @@ func New( // SetReadinessFunc sets a function called by /health/ready to determine // whether this component is ready to serve traffic. If fn returns an error // the endpoint responds 503; if nil it responds 200. -func (s *Server) SetReadinessFunc(fn func() error) { +func (s *Server) SetReadinessFunc( + fn func() error, +) { s.readinessFunc = fn } @@ -200,7 +202,9 @@ func (s *Server) Start() { } // Stop gracefully shuts down the HTTP server and meter provider. -func (s *Server) Stop(ctx context.Context) { +func (s *Server) Stop( + ctx context.Context, +) { if err := s.meterProvider.Shutdown(ctx); err != nil { s.logger.Error( "meter provider shutdown error", diff --git a/internal/telemetry/metrics/server_public_test.go b/internal/telemetry/metrics/server_public_test.go index d71aece1a..745ca0e45 100644 --- a/internal/telemetry/metrics/server_public_test.go +++ b/internal/telemetry/metrics/server_public_test.go @@ -151,22 +151,34 @@ func (s *ServerPublicTestSuite) TestComponentUpGauge() { tests := []struct { name string readinessFunc func() error - wantContains []string + validateFunc func(string) }{ { name: "reports 0 when no readiness func set", readinessFunc: nil, - wantContains: []string{"osapi_component_up", "} 0"}, + validateFunc: func(body string) { + for _, want := range []string{"osapi_component_up", "} 0"} { + s.Contains(body, want) + } + }, }, { name: "reports 1 when readiness func returns nil", readinessFunc: func() error { return nil }, - wantContains: []string{"osapi_component_up", "} 1"}, + validateFunc: func(body string) { + for _, want := range []string{"osapi_component_up", "} 1"} { + s.Contains(body, want) + } + }, }, { name: "reports 0 when readiness func returns error", readinessFunc: func() error { return errors.New("fail") }, - wantContains: []string{"osapi_component_up", "} 0"}, + validateFunc: func(body string) { + for _, want := range []string{"osapi_component_up", "} 0"} { + s.Contains(body, want) + } + }, }, } @@ -182,10 +194,7 @@ func (s *ServerPublicTestSuite) TestComponentUpGauge() { srv.Start() time.Sleep(100 * time.Millisecond) - body := scrapeMetrics(port) - for _, want := range tc.wantContains { - s.Contains(body, want) - } + tc.validateFunc(scrapeMetrics(port)) ctx, cancel := context.WithTimeout( context.Background(), @@ -215,7 +224,7 @@ func (s *ServerPublicTestSuite) TestRegisterSubsystems() { tests := []struct { name string subsystems []metrics.SubsystemStatus - wantContains []string + validateFunc func(string) }{ { name: "registers gauges for each subsystem", @@ -224,10 +233,14 @@ func (s *ServerPublicTestSuite) TestRegisterSubsystems() { {Name: "heartbeat", StatusFn: func() string { return "ok" }}, {Name: "notifier", StatusFn: func() string { return "disabled" }}, }, - wantContains: []string{ - `subsystem="api"} 1`, - `subsystem="heartbeat"} 1`, - `subsystem="notifier"} 0`, + validateFunc: func(body string) { + for _, want := range []string{ + `subsystem="api"} 1`, + `subsystem="heartbeat"} 1`, + `subsystem="notifier"} 0`, + } { + s.Contains(body, want) + } }, }, } @@ -241,10 +254,7 @@ func (s *ServerPublicTestSuite) TestRegisterSubsystems() { srv.Start() time.Sleep(100 * time.Millisecond) - body := scrapeMetrics(port) - for _, want := range tc.wantContains { - s.Contains(body, want) - } + tc.validateFunc(scrapeMetrics(port)) ctx, cancel := context.WithTimeout( context.Background(), @@ -274,19 +284,27 @@ func (s *ServerPublicTestSuite) TestRegisterHeartbeatAge() { tests := []struct { name string timeFn func() time.Time - wantContains []string + validateFunc func(string) }{ { - name: "reports 0 when heartbeat time is zero", - timeFn: func() time.Time { return time.Time{} }, - wantContains: []string{"osapi_heartbeat_age_seconds", "} 0"}, + name: "reports 0 when heartbeat time is zero", + timeFn: func() time.Time { return time.Time{} }, + validateFunc: func(body string) { + for _, want := range []string{"osapi_heartbeat_age_seconds", "} 0"} { + s.Contains(body, want) + } + }, }, { name: "reports positive age when heartbeat time is in the past", timeFn: func() time.Time { return time.Now().Add(-5 * time.Second) }, - wantContains: []string{"osapi_heartbeat_age_seconds"}, + validateFunc: func(body string) { + for _, want := range []string{"osapi_heartbeat_age_seconds"} { + s.Contains(body, want) + } + }, }, } @@ -299,10 +317,7 @@ func (s *ServerPublicTestSuite) TestRegisterHeartbeatAge() { srv.Start() time.Sleep(100 * time.Millisecond) - body := scrapeMetrics(port) - for _, want := range tc.wantContains { - s.Contains(body, want) - } + tc.validateFunc(scrapeMetrics(port)) ctx, cancel := context.WithTimeout( context.Background(), diff --git a/internal/telemetry/process/condition.go b/internal/telemetry/process/condition.go index 695020029..9c671a009 100644 --- a/internal/telemetry/process/condition.go +++ b/internal/telemetry/process/condition.go @@ -1,3 +1,23 @@ +// Copyright (c) 2026 John Dewey + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + package process import ( diff --git a/internal/telemetry/process/condition_public_test.go b/internal/telemetry/process/condition_public_test.go index c66bc9efe..71d567079 100644 --- a/internal/telemetry/process/condition_public_test.go +++ b/internal/telemetry/process/condition_public_test.go @@ -206,6 +206,8 @@ func (s *ConditionPublicTestSuite) TestEvaluateProcessConditions() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestConditionPublicTestSuite(t *testing.T) { +func TestConditionPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ConditionPublicTestSuite)) } diff --git a/internal/telemetry/process/self_public_test.go b/internal/telemetry/process/self_public_test.go index 3de01fbdb..e96303f19 100644 --- a/internal/telemetry/process/self_public_test.go +++ b/internal/telemetry/process/self_public_test.go @@ -182,6 +182,8 @@ func (suite *ProcessPublicTestSuite) TestGetMetricsWithInjection() { // In order for `go test` to run this suite, we need to create // a normal test function and pass our suite to suite.Run. -func TestProcessPublicTestSuite(t *testing.T) { +func TestProcessPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessPublicTestSuite)) } diff --git a/internal/telemetry/tracing/propagation_public_test.go b/internal/telemetry/tracing/propagation_public_test.go index 489b1c1b2..7562515ec 100644 --- a/internal/telemetry/tracing/propagation_public_test.go +++ b/internal/telemetry/tracing/propagation_public_test.go @@ -326,6 +326,8 @@ func (s *PropagationPublicTestSuite) TestMapCarrierKeys() { } } -func TestPropagationPublicTestSuite(t *testing.T) { +func TestPropagationPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PropagationPublicTestSuite)) } diff --git a/internal/telemetry/tracing/slog_public_test.go b/internal/telemetry/tracing/slog_public_test.go index 8fae54a5a..f93754ed9 100644 --- a/internal/telemetry/tracing/slog_public_test.go +++ b/internal/telemetry/tracing/slog_public_test.go @@ -212,6 +212,8 @@ func (s *SlogPublicTestSuite) TestTraceHandlerEnabled() { } } -func TestSlogPublicTestSuite(t *testing.T) { +func TestSlogPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SlogPublicTestSuite)) } diff --git a/internal/telemetry/tracing/tracer_public_test.go b/internal/telemetry/tracing/tracer_public_test.go index 1fc78ff92..c78be14ea 100644 --- a/internal/telemetry/tracing/tracer_public_test.go +++ b/internal/telemetry/tracing/tracer_public_test.go @@ -235,6 +235,8 @@ func (s *InitTracerPublicTestSuite) TestInitTracerWithInjection() { } } -func TestInitTracerPublicTestSuite(t *testing.T) { +func TestInitTracerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(InitTracerPublicTestSuite)) } diff --git a/internal/validation/target.go b/internal/validation/target.go index 1601f553d..f3142dfed 100644 --- a/internal/validation/target.go +++ b/internal/validation/target.go @@ -94,7 +94,9 @@ func getAgents() ([]AgentTarget, error) { // validTarget checks whether the target is a valid routing pattern // (_any, _all), a label matching an active agent, or a direct hostname. -func validTarget(fl validator.FieldLevel) bool { +func validTarget( + fl validator.FieldLevel, +) bool { target := fl.Field().String() if target == "_any" || target == "_all" { diff --git a/internal/validation/target_public_test.go b/internal/validation/target_public_test.go index 154d6531a..619331f73 100644 --- a/internal/validation/target_public_test.go +++ b/internal/validation/target_public_test.go @@ -408,25 +408,31 @@ func (s *TargetPublicTestSuite) TestValidTarget() { func (s *TargetPublicTestSuite) TestResolveTarget() { tests := []struct { - name string - setupLister func() - target string - want string + name string + setupLister func() + target string + validateFunc func(string) }{ { name: "when target is _any returns unchanged", target: "_any", - want: "_any", + validateFunc: func(got string) { + s.Equal("_any", got) + }, }, { name: "when target is _all returns unchanged", target: "_all", - want: "_all", + validateFunc: func(got string) { + s.Equal("_all", got) + }, }, { name: "when target is label returns unchanged", target: "group:web", - want: "group:web", + validateFunc: func(got string) { + s.Equal("group:web", got) + }, }, { name: "when target is hostname resolves to machine ID", @@ -440,7 +446,9 @@ func (s *TargetPublicTestSuite) TestResolveTarget() { ) }, target: "web-01", - want: "abc123", + validateFunc: func(got string) { + s.Equal("abc123", got) + }, }, { name: "when target is machine ID returns unchanged", @@ -454,7 +462,9 @@ func (s *TargetPublicTestSuite) TestResolveTarget() { ) }, target: "abc123", - want: "abc123", + validateFunc: func(got string) { + s.Equal("abc123", got) + }, }, { name: "when target not found returns unchanged", @@ -466,7 +476,9 @@ func (s *TargetPublicTestSuite) TestResolveTarget() { ) }, target: "unknown", - want: "unknown", + validateFunc: func(got string) { + s.Equal("unknown", got) + }, }, { name: "when lister errors returns unchanged", @@ -478,7 +490,9 @@ func (s *TargetPublicTestSuite) TestResolveTarget() { ) }, target: "web-01", - want: "web-01", + validateFunc: func(got string) { + s.Equal("web-01", got) + }, }, } @@ -488,7 +502,7 @@ func (s *TargetPublicTestSuite) TestResolveTarget() { tt.setupLister() } got := validation.ResolveTarget(tt.target) - s.Equal(tt.want, got) + tt.validateFunc(got) }) } } @@ -507,6 +521,8 @@ func (s *TargetPublicTestSuite) TestValidTargetMatchesMachineID() { s.True(ok) } -func TestTargetPublicTestSuite(t *testing.T) { +func TestTargetPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(TargetPublicTestSuite)) } diff --git a/internal/validation/validation_public_test.go b/internal/validation/validation_public_test.go index cf3da040c..4d3a9301c 100644 --- a/internal/validation/validation_public_test.go +++ b/internal/validation/validation_public_test.go @@ -25,6 +25,8 @@ import ( "github.com/stretchr/testify/suite" + "github.com/go-playground/validator/v10" + "github.com/osapi-io/osapi/internal/validation" ) @@ -39,10 +41,9 @@ func (s *ValidationPublicTestSuite) TestStruct() { } tests := []struct { - name string - input any - wantOK bool - contains []string + name string + input any + validateFunc func(string, bool) }{ { name: "when valid struct", @@ -50,15 +51,20 @@ func (s *ValidationPublicTestSuite) TestStruct() { Name: "test", Email: "test@example.com", }, - wantOK: true, + validateFunc: func(_ string, ok bool) { + s.Equal(true, ok) + }, }, { name: "when missing required field", input: testStruct{ Email: "test@example.com", }, - wantOK: false, - contains: []string{"Name", "required"}, + validateFunc: func(errMsg string, ok bool) { + s.Equal(false, ok) + s.Contains(errMsg, "Name") + s.Contains(errMsg, "required") + }, }, { name: "when invalid email", @@ -66,303 +72,375 @@ func (s *ValidationPublicTestSuite) TestStruct() { Name: "test", Email: "not-an-email", }, - wantOK: false, - contains: []string{"Email", "email"}, + validateFunc: func(errMsg string, ok bool) { + s.Equal(false, ok) + s.Contains(errMsg, "Email") + s.Contains(errMsg, "email") + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - errMsg, ok := validation.Struct(tt.input) - s.Equal(tt.wantOK, ok) - - if !ok { - for _, c := range tt.contains { - s.Contains(errMsg, c) - } - } + tt.validateFunc(validation.Struct(tt.input)) }) } } func (s *ValidationPublicTestSuite) TestVar() { tests := []struct { - name string - field any - tag string - wantOK bool - contains []string + name string + field any + tag string + validateFunc func(string, bool) }{ { - name: "when valid field", - field: "hello", - tag: "required", - wantOK: true, + name: "when valid field", + field: "hello", + tag: "required", + validateFunc: func(_ string, ok bool) { + s.Equal(true, ok) + }, }, { - name: "when empty required field", - field: "", - tag: "required", - wantOK: false, - contains: []string{"required"}, + name: "when empty required field", + field: "", + tag: "required", + validateFunc: func(errMsg string, ok bool) { + s.Equal(false, ok) + s.Contains(errMsg, "required") + }, }, { - name: "when invalid email", - field: "not-an-email", - tag: "email", - wantOK: false, - contains: []string{"email"}, + name: "when invalid email", + field: "not-an-email", + tag: "email", + validateFunc: func(errMsg string, ok bool) { + s.Equal(false, ok) + s.Contains(errMsg, "email") + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - errMsg, ok := validation.Var(tt.field, tt.tag) - s.Equal(tt.wantOK, ok) - - if !ok { - for _, c := range tt.contains { - s.Contains(errMsg, c) - } - } + tt.validateFunc(validation.Var(tt.field, tt.tag)) }) } } func (s *ValidationPublicTestSuite) TestAlphanumOrFact() { tests := []struct { - name string - field string - wantOK bool + name string + field string + validateFunc func(bool) }{ { - name: "when alphanumeric value", - field: "eth0", - wantOK: true, + name: "when alphanumeric value", + field: "eth0", + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when fact reference", - field: "@fact.interface.primary", - wantOK: true, + name: "when fact reference", + field: "@fact.interface.primary", + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when fact custom reference", - field: "@fact.custom.mykey", - wantOK: true, + name: "when fact custom reference", + field: "@fact.custom.mykey", + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when non-alphanum non-fact value", - field: "eth-0!", - wantOK: false, + name: "when non-alphanum non-fact value", + field: "eth-0!", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when empty value", - field: "", - wantOK: false, + name: "when empty value", + field: "", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when partial fact prefix", - field: "@fact", - wantOK: false, + name: "when partial fact prefix", + field: "@fact", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when at-sign without fact", - field: "@notfact.x", - wantOK: false, + name: "when at-sign without fact", + field: "@notfact.x", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when unknown fact key", - field: "@fact.primary_interface", - wantOK: false, + name: "when unknown fact key", + field: "@fact.primary_interface", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when fact with bare custom prefix", - field: "@fact.custom.", - wantOK: false, + name: "when fact with bare custom prefix", + field: "@fact.custom.", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { _, ok := validation.Var(tt.field, "required,alphanum_or_fact") - s.Equal(tt.wantOK, ok) + tt.validateFunc(ok) }) } } func (s *ValidationPublicTestSuite) TestIpOrFact() { tests := []struct { - name string - field string - wantOK bool + name string + field string + validateFunc func(bool) }{ { - name: "when valid IPv4", - field: "1.1.1.1", - wantOK: true, + name: "when valid IPv4", + field: "1.1.1.1", + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when valid IPv6", - field: "::1", - wantOK: true, + name: "when valid IPv6", + field: "::1", + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when fact reference", - field: "@fact.custom.gateway", - wantOK: true, + name: "when fact reference", + field: "@fact.custom.gateway", + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when fact interface primary", - field: "@fact.interface.primary", - wantOK: true, + name: "when fact interface primary", + field: "@fact.interface.primary", + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { - name: "when invalid address", - field: "not-an-ip", - wantOK: false, + name: "when invalid address", + field: "not-an-ip", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when empty value", - field: "", - wantOK: false, + name: "when empty value", + field: "", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when partial fact prefix", - field: "@fact", - wantOK: false, + name: "when partial fact prefix", + field: "@fact", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when at-sign without fact", - field: "@notfact.x", - wantOK: false, + name: "when at-sign without fact", + field: "@notfact.x", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when unknown fact key", - field: "@fact.primary_interface", - wantOK: false, + name: "when unknown fact key", + field: "@fact.primary_interface", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, { - name: "when fact with bare custom prefix", - field: "@fact.custom.", - wantOK: false, + name: "when fact with bare custom prefix", + field: "@fact.custom.", + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { _, ok := validation.Var(tt.field, "required,ip_or_fact") - s.Equal(tt.wantOK, ok) + tt.validateFunc(ok) }) } } func (s *ValidationPublicTestSuite) TestCronSchedule() { tests := []struct { - name string - field string - wantOK bool - contains []string + name string + field string + contains []string + validateFunc func(string, bool) }{ // Valid expressions { - name: "when every minute", - field: "* * * * *", - wantOK: true, + name: "when every minute", + field: "* * * * *", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when daily at 2am", - field: "0 2 * * *", - wantOK: true, + name: "when daily at 2am", + field: "0 2 * * *", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when every 5 minutes", - field: "*/5 * * * *", - wantOK: true, + name: "when every 5 minutes", + field: "*/5 * * * *", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when weekdays at 9am", - field: "0 9 * * 1-5", - wantOK: true, + name: "when weekdays at 9am", + field: "0 9 * * 1-5", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when first of month at midnight", - field: "0 0 1 * *", - wantOK: true, + name: "when first of month at midnight", + field: "0 0 1 * *", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when multiple hours", - field: "0 2,14 * * *", - wantOK: true, + name: "when multiple hours", + field: "0 2,14 * * *", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when range with step", - field: "0-30/5 * * * *", - wantOK: true, + name: "when range with step", + field: "0-30/5 * * * *", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when month and day names", - field: "0 0 * jan-mar mon", - wantOK: true, + name: "when month and day names", + field: "0 0 * jan-mar mon", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, // Invalid expressions { - name: "when empty string", - field: "", - wantOK: false, + name: "when empty string", + field: "", + validateFunc: func(_ string, ok bool) { + s.False(ok) + }, }, { - name: "when random text", - field: "not a cron expression", - wantOK: false, + name: "when random text", + field: "not a cron expression", + validateFunc: func(_ string, ok bool) { + s.False(ok) + }, }, { - name: "when too few fields", - field: "* * *", - wantOK: false, + name: "when too few fields", + field: "* * *", + validateFunc: func(_ string, ok bool) { + s.False(ok) + }, }, { - name: "when too many fields (6 fields)", - field: "* * * * * *", - wantOK: false, + name: "when too many fields (6 fields)", + field: "* * * * * *", + validateFunc: func(_ string, ok bool) { + s.False(ok) + }, }, { - name: "when minute out of range", - field: "60 * * * *", - wantOK: false, + name: "when minute out of range", + field: "60 * * * *", + validateFunc: func(_ string, ok bool) { + s.False(ok) + }, }, { - name: "when hour out of range", - field: "0 25 * * *", - wantOK: false, + name: "when hour out of range", + field: "0 25 * * *", + validateFunc: func(_ string, ok bool) { + s.False(ok) + }, }, { - name: "when day of month out of range", - field: "0 0 32 * *", - wantOK: false, + name: "when day of month out of range", + field: "0 0 32 * *", + validateFunc: func(_ string, ok bool) { + s.False(ok) + }, }, { - name: "when month out of range", - field: "0 0 * 13 *", - wantOK: false, + name: "when month out of range", + field: "0 0 * 13 *", + validateFunc: func(_ string, ok bool) { + s.False(ok) + }, }, { - name: "when day of week out of range", - field: "0 0 * * 8", - wantOK: false, + name: "when day of week out of range", + field: "0 0 * * 8", + validateFunc: func(_ string, ok bool) { + s.False(ok) + }, }, { - name: "when invalid character", - field: "0 0 * * abc", - wantOK: false, + name: "when invalid character", + field: "0 0 * * abc", + validateFunc: func(_ string, ok bool) { + s.False(ok) + }, }, { - name: "when invalid expression shows hint in struct validation", - field: "bad", - wantOK: false, + name: "when invalid expression shows hint in struct validation", + field: "bad", contains: []string{ "cron_schedule", "is not a valid cron expression", }, + validateFunc: func(errMsg string, ok bool) { + s.False(ok) + s.Contains(errMsg, "cron_schedule") + s.Contains(errMsg, "is not a valid cron expression") + }, }, } @@ -373,14 +451,10 @@ func (s *ValidationPublicTestSuite) TestCronSchedule() { type cronReq struct { Schedule string `validate:"required,cron_schedule"` } - errMsg, ok := validation.Struct(cronReq{Schedule: tt.field}) - s.Equal(tt.wantOK, ok) - for _, c := range tt.contains { - s.Contains(errMsg, c) - } + + tt.validateFunc(validation.Struct(cronReq{Schedule: tt.field})) } else { - _, ok := validation.Var(tt.field, "cron_schedule") - s.Equal(tt.wantOK, ok) + tt.validateFunc(validation.Var(tt.field, "cron_schedule")) } }) } @@ -388,45 +462,59 @@ func (s *ValidationPublicTestSuite) TestCronSchedule() { func (s *ValidationPublicTestSuite) TestGoDuration() { tests := []struct { - name string - field string - wantOK bool - contains []string + name string + field string + contains []string + validateFunc func(string, bool) }{ { - name: "when valid duration 30s passes", - field: "30s", - wantOK: true, + name: "when valid duration 30s passes", + field: "30s", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when valid duration 5m passes", - field: "5m", - wantOK: true, + name: "when valid duration 5m passes", + field: "5m", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when valid duration 1h passes", - field: "1h", - wantOK: true, + name: "when valid duration 1h passes", + field: "1h", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when valid duration 720h passes", - field: "720h", - wantOK: true, + name: "when valid duration 720h passes", + field: "720h", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when invalid duration 7d fails", - field: "7d", - wantOK: false, + name: "when invalid duration 7d fails", + field: "7d", + validateFunc: func(_ string, ok bool) { + s.False(ok) + }, }, { - name: "when invalid duration abc fails", - field: "abc", - wantOK: false, + name: "when invalid duration abc fails", + field: "abc", + validateFunc: func(_ string, ok bool) { + s.False(ok) + }, }, { - name: "when empty string passes with omitempty", - field: "", - wantOK: true, + name: "when empty string passes with omitempty", + field: "", + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { name: "when invalid duration shows hint in struct validation", @@ -435,6 +523,11 @@ func (s *ValidationPublicTestSuite) TestGoDuration() { "go_duration", "is not a valid Go duration", }, + validateFunc: func(errMsg string, ok bool) { + s.False(ok) + s.Contains(errMsg, "go_duration") + s.Contains(errMsg, "is not a valid Go duration") + }, }, } @@ -445,18 +538,13 @@ func (s *ValidationPublicTestSuite) TestGoDuration() { type durationReq struct { MaxAge string `validate:"required,go_duration"` } - errMsg, ok := validation.Struct(durationReq{MaxAge: tt.field}) - s.False(ok) - for _, c := range tt.contains { - s.Contains(errMsg, c) - } + + tt.validateFunc(validation.Struct(durationReq{MaxAge: tt.field})) } else if tt.field == "" { // Test empty string with omitempty — validation should pass. - _, ok := validation.Var(tt.field, "omitempty,go_duration") - s.Equal(tt.wantOK, ok) + tt.validateFunc(validation.Var(tt.field, "omitempty,go_duration")) } else { - _, ok := validation.Var(tt.field, "go_duration") - s.Equal(tt.wantOK, ok) + tt.validateFunc(validation.Var(tt.field, "go_duration")) } }) } @@ -493,112 +581,138 @@ func (s *ValidationPublicTestSuite) TestAtLeastOneField() { groups := []string{"admin"} tests := []struct { - name string - input any - wantOK bool - wantErrMsg string + name string + input any + validateFunc func(string, bool) }{ { - name: "when one pointer field is non-nil", - input: allPointers{Shell: &str}, - wantOK: true, + name: "when one pointer field is non-nil", + input: allPointers{Shell: &str}, + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when slice pointer field is non-nil", - input: allPointers{Groups: &groups}, - wantOK: true, + name: "when slice pointer field is non-nil", + input: allPointers{Groups: &groups}, + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when all pointer fields are nil", - input: allPointers{}, - wantOK: false, - wantErrMsg: "at least one field must be provided", + name: "when all pointer fields are nil", + input: allPointers{}, + validateFunc: func(errMsg string, ok bool) { + s.False(ok) + s.Equal("at least one field must be provided", errMsg) + }, }, { - name: "when non-pointer field is non-zero", - input: withNonPointer{Name: "test"}, - wantOK: true, + name: "when non-pointer field is non-zero", + input: withNonPointer{Name: "test"}, + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when bool field is true", - input: withNonPointer{Enabled: true}, - wantOK: true, + name: "when bool field is true", + input: withNonPointer{Enabled: true}, + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when all fields are zero", - input: withNonPointer{}, - wantOK: false, - wantErrMsg: "at least one field must be provided", + name: "when all fields are zero", + input: withNonPointer{}, + validateFunc: func(errMsg string, ok bool) { + s.False(ok) + s.Equal("at least one field must be provided", errMsg) + }, }, { - name: "when slice field is non-nil", - input: withSlice{Items: []string{"a"}}, - wantOK: true, + name: "when slice field is non-nil", + input: withSlice{Items: []string{"a"}}, + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when slice field is nil", - input: withSlice{}, - wantOK: false, - wantErrMsg: "at least one field must be provided", + name: "when slice field is nil", + input: withSlice{}, + validateFunc: func(errMsg string, ok bool) { + s.False(ok) + s.Equal("at least one field must be provided", errMsg) + }, }, { - name: "when map field is non-nil", - input: withMap{Labels: map[string]string{"env": "dev"}}, - wantOK: true, + name: "when map field is non-nil", + input: withMap{Labels: map[string]string{"env": "dev"}}, + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when map field is nil", - input: withMap{}, - wantOK: false, - wantErrMsg: "at least one field must be provided", + name: "when map field is nil", + input: withMap{}, + validateFunc: func(errMsg string, ok bool) { + s.False(ok) + s.Equal("at least one field must be provided", errMsg) + }, }, { - name: "when only unexported fields", - input: unexportedOnly{}, - wantOK: false, - wantErrMsg: "at least one field must be provided", + name: "when only unexported fields", + input: unexportedOnly{}, + validateFunc: func(errMsg string, ok bool) { + s.False(ok) + s.Equal("at least one field must be provided", errMsg) + }, }, { - name: "when pointer to struct is passed", - input: &allPointers{Shell: &str}, - wantOK: true, + name: "when pointer to struct is passed", + input: &allPointers{Shell: &str}, + validateFunc: func(_ string, ok bool) { + s.True(ok) + }, }, { - name: "when non-struct is passed", - input: "not a struct", - wantOK: false, - wantErrMsg: "expected struct", + name: "when non-struct is passed", + input: "not a struct", + validateFunc: func(errMsg string, ok bool) { + s.False(ok) + s.Equal("expected struct", errMsg) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - errMsg, ok := validation.AtLeastOneField(tt.input) - s.Equal(tt.wantOK, ok) - if !ok { - s.Equal(tt.wantErrMsg, errMsg) - } + tt.validateFunc(validation.AtLeastOneField(tt.input)) }) } } func (s *ValidationPublicTestSuite) TestInstance() { tests := []struct { - name string + name string + validateFunc func(*validator.Validate) }{ { name: "when returns shared validator instance", + validateFunc: func(v *validator.Validate) { + s.NotNil(v) + }, }, } for _, tt := range tests { s.Run(tt.name, func() { - v := validation.Instance() - s.NotNil(v) + tt.validateFunc(validation.Instance()) }) } } -func TestValidationPublicTestSuite(t *testing.T) { +func TestValidationPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ValidationPublicTestSuite)) } diff --git a/pkg/sdk/client/agent_public_test.go b/pkg/sdk/client/agent_public_test.go index dc03a18ec..f228339be 100644 --- a/pkg/sdk/client/agent_public_test.go +++ b/pkg/sdk/client/agent_public_test.go @@ -720,6 +720,8 @@ func (suite *AgentPublicTestSuite) TestReject() { } } -func TestAgentPublicTestSuite(t *testing.T) { +func TestAgentPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentPublicTestSuite)) } diff --git a/pkg/sdk/client/agent_types_public_test.go b/pkg/sdk/client/agent_types_public_test.go index 1c8df24d8..ddf3b22a0 100644 --- a/pkg/sdk/client/agent_types_public_test.go +++ b/pkg/sdk/client/agent_types_public_test.go @@ -329,6 +329,8 @@ func (suite *AgentTypesPublicTestSuite) TestAgentListFromGen() { } } -func TestAgentTypesPublicTestSuite(t *testing.T) { +func TestAgentTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AgentTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/audit_public_test.go b/pkg/sdk/client/audit_public_test.go index 8abfc9b0a..5961cb389 100644 --- a/pkg/sdk/client/audit_public_test.go +++ b/pkg/sdk/client/audit_public_test.go @@ -336,6 +336,8 @@ func (suite *AuditPublicTestSuite) TestExport() { } } -func TestAuditPublicTestSuite(t *testing.T) { +func TestAuditPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AuditPublicTestSuite)) } diff --git a/pkg/sdk/client/audit_types_public_test.go b/pkg/sdk/client/audit_types_public_test.go index 41e615b7b..1d5ca6a37 100644 --- a/pkg/sdk/client/audit_types_public_test.go +++ b/pkg/sdk/client/audit_types_public_test.go @@ -269,6 +269,8 @@ func (s *AuditTypesPublicTestSuite) TestAuditListFromGen() { } } -func TestAuditTypesPublicTestSuite(t *testing.T) { +func TestAuditTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(AuditTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/certificate_public_test.go b/pkg/sdk/client/certificate_public_test.go index 62392bbbd..038d4b375 100644 --- a/pkg/sdk/client/certificate_public_test.go +++ b/pkg/sdk/client/certificate_public_test.go @@ -841,6 +841,8 @@ func (suite *CertificatePublicTestSuite) TestCertificateDelete() { } } -func TestCertificatePublicTestSuite(t *testing.T) { +func TestCertificatePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CertificatePublicTestSuite)) } diff --git a/pkg/sdk/client/certificate_types_public_test.go b/pkg/sdk/client/certificate_types_public_test.go index fa8319812..23b5e220c 100644 --- a/pkg/sdk/client/certificate_types_public_test.go +++ b/pkg/sdk/client/certificate_types_public_test.go @@ -375,6 +375,8 @@ func (suite *CertificateTypesPublicTestSuite) TestCertificateCAMutationCollectio } } -func TestCertificateTypesPublicTestSuite(t *testing.T) { +func TestCertificateTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CertificateTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/check_error_public_test.go b/pkg/sdk/client/check_error_public_test.go index b8def8d88..3b80e920c 100644 --- a/pkg/sdk/client/check_error_public_test.go +++ b/pkg/sdk/client/check_error_public_test.go @@ -204,6 +204,8 @@ func (suite *CheckErrorPublicTestSuite) TestCheckErrorMessages() { } } -func TestCheckErrorPublicTestSuite(t *testing.T) { +func TestCheckErrorPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CheckErrorPublicTestSuite)) } diff --git a/pkg/sdk/client/collection_public_test.go b/pkg/sdk/client/collection_public_test.go index 278cb4963..c7d61b46b 100644 --- a/pkg/sdk/client/collection_public_test.go +++ b/pkg/sdk/client/collection_public_test.go @@ -89,6 +89,8 @@ func (suite *CollectionPublicTestSuite) TestCollectionFirst() { } } -func TestCollectionPublicTestSuite(t *testing.T) { +func TestCollectionPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CollectionPublicTestSuite)) } diff --git a/pkg/sdk/client/command_public_test.go b/pkg/sdk/client/command_public_test.go index 48cdea714..0a9e93266 100644 --- a/pkg/sdk/client/command_public_test.go +++ b/pkg/sdk/client/command_public_test.go @@ -314,6 +314,8 @@ func (suite *CommandPublicTestSuite) TestShell() { } } -func TestCommandPublicTestSuite(t *testing.T) { +func TestCommandPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CommandPublicTestSuite)) } diff --git a/pkg/sdk/client/cron_public_test.go b/pkg/sdk/client/cron_public_test.go index 819ccac05..170a00f25 100644 --- a/pkg/sdk/client/cron_public_test.go +++ b/pkg/sdk/client/cron_public_test.go @@ -1021,6 +1021,8 @@ func (suite *CronPublicTestSuite) TestCronDelete() { } } -func TestCronPublicTestSuite(t *testing.T) { +func TestCronPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(CronPublicTestSuite)) } diff --git a/pkg/sdk/client/disk_public_test.go b/pkg/sdk/client/disk_public_test.go index 606baedc9..0c0fda92e 100644 --- a/pkg/sdk/client/disk_public_test.go +++ b/pkg/sdk/client/disk_public_test.go @@ -140,6 +140,8 @@ func (suite *DiskPublicTestSuite) TestGet() { } } -func TestDiskPublicTestSuite(t *testing.T) { +func TestDiskPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DiskPublicTestSuite)) } diff --git a/pkg/sdk/client/disk_types_public_test.go b/pkg/sdk/client/disk_types_public_test.go index d71c6819c..b249b909e 100644 --- a/pkg/sdk/client/disk_types_public_test.go +++ b/pkg/sdk/client/disk_types_public_test.go @@ -97,6 +97,8 @@ func (suite *DiskTypesPublicTestSuite) TestDisksFromGen() { } } -func TestDiskTypesPublicTestSuite(t *testing.T) { +func TestDiskTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DiskTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/dns_public_test.go b/pkg/sdk/client/dns_public_test.go index a239c638f..1f947a7ea 100644 --- a/pkg/sdk/client/dns_public_test.go +++ b/pkg/sdk/client/dns_public_test.go @@ -492,6 +492,8 @@ func (suite *DNSPublicTestSuite) TestDelete() { } } -func TestDNSPublicTestSuite(t *testing.T) { +func TestDNSPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DNSPublicTestSuite)) } diff --git a/pkg/sdk/client/dns_types_public_test.go b/pkg/sdk/client/dns_types_public_test.go index 568399104..4c8e14aa1 100644 --- a/pkg/sdk/client/dns_types_public_test.go +++ b/pkg/sdk/client/dns_types_public_test.go @@ -143,6 +143,8 @@ func (suite *DNSTypesPublicTestSuite) TestDNSUpdateCollectionFromGen() { } } -func TestDNSTypesPublicTestSuite(t *testing.T) { +func TestDNSTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DNSTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/docker_public_test.go b/pkg/sdk/client/docker_public_test.go index 0c1457e3b..d69be2471 100644 --- a/pkg/sdk/client/docker_public_test.go +++ b/pkg/sdk/client/docker_public_test.go @@ -1416,6 +1416,8 @@ func (suite *DockerPublicTestSuite) TestImageRemove() { } } -func TestDockerPublicTestSuite(t *testing.T) { +func TestDockerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(DockerPublicTestSuite)) } diff --git a/pkg/sdk/client/errors_public_test.go b/pkg/sdk/client/errors_public_test.go index be1d251cd..ee2028b96 100644 --- a/pkg/sdk/client/errors_public_test.go +++ b/pkg/sdk/client/errors_public_test.go @@ -362,6 +362,8 @@ func (suite *ErrorsPublicTestSuite) TestErrorsAsAPIError() { } } -func TestErrorsPublicTestSuite(t *testing.T) { +func TestErrorsPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ErrorsPublicTestSuite)) } diff --git a/pkg/sdk/client/file_deploy_public_test.go b/pkg/sdk/client/file_deploy_public_test.go index d103b5685..8f915ec2f 100644 --- a/pkg/sdk/client/file_deploy_public_test.go +++ b/pkg/sdk/client/file_deploy_public_test.go @@ -492,6 +492,8 @@ func (suite *FileDeployPublicTestSuite) TestUndeploy() { } } -func TestFileDeployPublicTestSuite(t *testing.T) { +func TestFileDeployPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FileDeployPublicTestSuite)) } diff --git a/pkg/sdk/client/file_public_test.go b/pkg/sdk/client/file_public_test.go index 2baab5217..d11e1f0b3 100644 --- a/pkg/sdk/client/file_public_test.go +++ b/pkg/sdk/client/file_public_test.go @@ -943,6 +943,8 @@ func (r *errReader) Read( return 0, r.err } -func TestFilePublicTestSuite(t *testing.T) { +func TestFilePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(FilePublicTestSuite)) } diff --git a/pkg/sdk/client/group_public_test.go b/pkg/sdk/client/group_public_test.go index cc77b7df9..cac55b2da 100644 --- a/pkg/sdk/client/group_public_test.go +++ b/pkg/sdk/client/group_public_test.go @@ -723,7 +723,9 @@ func (suite *GroupPublicTestSuite) TestGroupDelete() { } } -func TestGroupPublicTestSuite(t *testing.T) { +func TestGroupPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(GroupPublicTestSuite)) } diff --git a/pkg/sdk/client/group_types_public_test.go b/pkg/sdk/client/group_types_public_test.go index e8e03dd28..e9acfd996 100644 --- a/pkg/sdk/client/group_types_public_test.go +++ b/pkg/sdk/client/group_types_public_test.go @@ -345,7 +345,9 @@ func (suite *GroupTypesPublicTestSuite) TestGroupMutationCollectionFromDelete() } } -func TestGroupTypesPublicTestSuite(t *testing.T) { +func TestGroupTypesPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(GroupTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/health_public_test.go b/pkg/sdk/client/health_public_test.go index a398bab22..04680cf33 100644 --- a/pkg/sdk/client/health_public_test.go +++ b/pkg/sdk/client/health_public_test.go @@ -368,6 +368,8 @@ func (suite *HealthPublicTestSuite) TestStatus() { } } -func TestHealthPublicTestSuite(t *testing.T) { +func TestHealthPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HealthPublicTestSuite)) } diff --git a/pkg/sdk/client/health_types_public_test.go b/pkg/sdk/client/health_types_public_test.go index 3333be7a5..405ebb298 100644 --- a/pkg/sdk/client/health_types_public_test.go +++ b/pkg/sdk/client/health_types_public_test.go @@ -362,6 +362,8 @@ func (suite *HealthTypesPublicTestSuite) TestSystemStatusFromGen() { } } -func TestHealthTypesPublicTestSuite(t *testing.T) { +func TestHealthTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HealthTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/hostname_public_test.go b/pkg/sdk/client/hostname_public_test.go index 80a6cbe70..516709eaa 100644 --- a/pkg/sdk/client/hostname_public_test.go +++ b/pkg/sdk/client/hostname_public_test.go @@ -254,6 +254,8 @@ func (suite *HostnamePublicTestSuite) TestUpdate() { } } -func TestHostnamePublicTestSuite(t *testing.T) { +func TestHostnamePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HostnamePublicTestSuite)) } diff --git a/pkg/sdk/client/hostname_types_public_test.go b/pkg/sdk/client/hostname_types_public_test.go index 581f15a75..3c5021035 100644 --- a/pkg/sdk/client/hostname_types_public_test.go +++ b/pkg/sdk/client/hostname_types_public_test.go @@ -109,6 +109,8 @@ func (suite *HostnameTypesPublicTestSuite) TestHostnameCollectionFromGen() { } } -func TestHostnameTypesPublicTestSuite(t *testing.T) { +func TestHostnameTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(HostnameTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/interface_public_test.go b/pkg/sdk/client/interface_public_test.go index 11c627fa6..26221a608 100644 --- a/pkg/sdk/client/interface_public_test.go +++ b/pkg/sdk/client/interface_public_test.go @@ -794,6 +794,8 @@ func (suite *InterfacePublicTestSuite) TestDelete() { } } -func TestInterfacePublicTestSuite(t *testing.T) { +func TestInterfacePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(InterfacePublicTestSuite)) } diff --git a/pkg/sdk/client/interface_types_public_test.go b/pkg/sdk/client/interface_types_public_test.go index 77a5b54c4..c4a434c56 100644 --- a/pkg/sdk/client/interface_types_public_test.go +++ b/pkg/sdk/client/interface_types_public_test.go @@ -418,6 +418,8 @@ func (suite *InterfaceTypesPublicTestSuite) TestInterfaceMutationCollectionFromD } } -func TestInterfaceTypesPublicTestSuite(t *testing.T) { +func TestInterfaceTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(InterfaceTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/job_public_test.go b/pkg/sdk/client/job_public_test.go index 7a8265553..8314db672 100644 --- a/pkg/sdk/client/job_public_test.go +++ b/pkg/sdk/client/job_public_test.go @@ -495,6 +495,8 @@ func (suite *JobPublicTestSuite) TestRetry() { } } -func TestJobPublicTestSuite(t *testing.T) { +func TestJobPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(JobPublicTestSuite)) } diff --git a/pkg/sdk/client/job_types_public_test.go b/pkg/sdk/client/job_types_public_test.go index 0fc78f9e5..5a5cb25e4 100644 --- a/pkg/sdk/client/job_types_public_test.go +++ b/pkg/sdk/client/job_types_public_test.go @@ -315,6 +315,8 @@ func (suite *JobTypesPublicTestSuite) TestJobListFromGen() { } } -func TestJobTypesPublicTestSuite(t *testing.T) { +func TestJobTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(JobTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/load_public_test.go b/pkg/sdk/client/load_public_test.go index b7bc0cc4a..604e63db4 100644 --- a/pkg/sdk/client/load_public_test.go +++ b/pkg/sdk/client/load_public_test.go @@ -140,6 +140,8 @@ func (suite *LoadPublicTestSuite) TestGet() { } } -func TestLoadPublicTestSuite(t *testing.T) { +func TestLoadPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LoadPublicTestSuite)) } diff --git a/pkg/sdk/client/load_types_public_test.go b/pkg/sdk/client/load_types_public_test.go index 8344ea52d..60f5c585c 100644 --- a/pkg/sdk/client/load_types_public_test.go +++ b/pkg/sdk/client/load_types_public_test.go @@ -70,6 +70,8 @@ func (suite *LoadTypesPublicTestSuite) TestLoadAverageFromGen() { } } -func TestLoadTypesPublicTestSuite(t *testing.T) { +func TestLoadTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LoadTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/log_public_test.go b/pkg/sdk/client/log_public_test.go index 6fab5f863..7731fa486 100644 --- a/pkg/sdk/client/log_public_test.go +++ b/pkg/sdk/client/log_public_test.go @@ -595,6 +595,8 @@ func (suite *LogPublicTestSuite) TestSources() { } } -func TestLogPublicTestSuite(t *testing.T) { +func TestLogPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LogPublicTestSuite)) } diff --git a/pkg/sdk/client/log_types_public_test.go b/pkg/sdk/client/log_types_public_test.go index 9d8d6998c..cea60f123 100644 --- a/pkg/sdk/client/log_types_public_test.go +++ b/pkg/sdk/client/log_types_public_test.go @@ -231,6 +231,8 @@ func (suite *LogTypesPublicTestSuite) TestLogEntryInfoFromGen() { } } -func TestLogTypesPublicTestSuite(t *testing.T) { +func TestLogTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(LogTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/memory_public_test.go b/pkg/sdk/client/memory_public_test.go index 8588100ea..78c2f952b 100644 --- a/pkg/sdk/client/memory_public_test.go +++ b/pkg/sdk/client/memory_public_test.go @@ -140,6 +140,8 @@ func (suite *MemoryPublicTestSuite) TestGet() { } } -func TestMemoryPublicTestSuite(t *testing.T) { +func TestMemoryPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(MemoryPublicTestSuite)) } diff --git a/pkg/sdk/client/memory_types_public_test.go b/pkg/sdk/client/memory_types_public_test.go index 83373deef..a8dfcd12e 100644 --- a/pkg/sdk/client/memory_types_public_test.go +++ b/pkg/sdk/client/memory_types_public_test.go @@ -70,6 +70,8 @@ func (suite *MemoryTypesPublicTestSuite) TestMemoryFromGen() { } } -func TestMemoryTypesPublicTestSuite(t *testing.T) { +func TestMemoryTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(MemoryTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/ntp_public_test.go b/pkg/sdk/client/ntp_public_test.go index 574f00e2f..5d0588fad 100644 --- a/pkg/sdk/client/ntp_public_test.go +++ b/pkg/sdk/client/ntp_public_test.go @@ -771,6 +771,8 @@ func (suite *NTPPublicTestSuite) TestNtpDelete() { } } -func TestNTPPublicTestSuite(t *testing.T) { +func TestNTPPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NTPPublicTestSuite)) } diff --git a/pkg/sdk/client/ntp_types_public_test.go b/pkg/sdk/client/ntp_types_public_test.go index d824e9d7c..36cc78eae 100644 --- a/pkg/sdk/client/ntp_types_public_test.go +++ b/pkg/sdk/client/ntp_types_public_test.go @@ -372,6 +372,8 @@ func (suite *NTPTypesPublicTestSuite) TestNtpMutationCollectionFromDelete() { } } -func TestNTPTypesPublicTestSuite(t *testing.T) { +func TestNTPTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(NTPTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/os_public_test.go b/pkg/sdk/client/os_public_test.go index 0e8defe20..e58283b4e 100644 --- a/pkg/sdk/client/os_public_test.go +++ b/pkg/sdk/client/os_public_test.go @@ -140,6 +140,8 @@ func (suite *OSPublicTestSuite) TestGet() { } } -func TestOSPublicTestSuite(t *testing.T) { +func TestOSPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(OSPublicTestSuite)) } diff --git a/pkg/sdk/client/os_types_public_test.go b/pkg/sdk/client/os_types_public_test.go index 0df1a3fa1..00520e85b 100644 --- a/pkg/sdk/client/os_types_public_test.go +++ b/pkg/sdk/client/os_types_public_test.go @@ -68,6 +68,8 @@ func (suite *OSTypesPublicTestSuite) TestOSInfoFromGen() { } } -func TestOSTypesPublicTestSuite(t *testing.T) { +func TestOSTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(OSTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/package_public_test.go b/pkg/sdk/client/package_public_test.go index 28226a973..166f0b86e 100644 --- a/pkg/sdk/client/package_public_test.go +++ b/pkg/sdk/client/package_public_test.go @@ -952,6 +952,8 @@ func (suite *PackagePublicTestSuite) TestPackageListUpdates() { } } -func TestPackagePublicTestSuite(t *testing.T) { +func TestPackagePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PackagePublicTestSuite)) } diff --git a/pkg/sdk/client/package_types_public_test.go b/pkg/sdk/client/package_types_public_test.go index f4acac306..7f25a2061 100644 --- a/pkg/sdk/client/package_types_public_test.go +++ b/pkg/sdk/client/package_types_public_test.go @@ -556,6 +556,8 @@ func (suite *PackageTypesPublicTestSuite) TestUpdateInfosFromGen() { } } -func TestPackageTypesPublicTestSuite(t *testing.T) { +func TestPackageTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PackageTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/ping_public_test.go b/pkg/sdk/client/ping_public_test.go index bb44b3083..1500798b8 100644 --- a/pkg/sdk/client/ping_public_test.go +++ b/pkg/sdk/client/ping_public_test.go @@ -150,6 +150,8 @@ func (suite *PingPublicTestSuite) TestDo() { } } -func TestPingPublicTestSuite(t *testing.T) { +func TestPingPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PingPublicTestSuite)) } diff --git a/pkg/sdk/client/power_public_test.go b/pkg/sdk/client/power_public_test.go index 4b202d589..306db3942 100644 --- a/pkg/sdk/client/power_public_test.go +++ b/pkg/sdk/client/power_public_test.go @@ -447,6 +447,8 @@ func (suite *PowerPublicTestSuite) TestShutdown() { } } -func TestPowerPublicTestSuite(t *testing.T) { +func TestPowerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PowerPublicTestSuite)) } diff --git a/pkg/sdk/client/power_types_public_test.go b/pkg/sdk/client/power_types_public_test.go index 46f5f925d..5dc2ebe45 100644 --- a/pkg/sdk/client/power_types_public_test.go +++ b/pkg/sdk/client/power_types_public_test.go @@ -224,6 +224,8 @@ func (suite *PowerTypesPublicTestSuite) TestPowerCollectionFromShutdown() { } } -func TestPowerTypesPublicTestSuite(t *testing.T) { +func TestPowerTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PowerTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/process_public_test.go b/pkg/sdk/client/process_public_test.go index 65637facc..088de6966 100644 --- a/pkg/sdk/client/process_public_test.go +++ b/pkg/sdk/client/process_public_test.go @@ -597,6 +597,8 @@ func (suite *ProcessPublicTestSuite) TestSignal() { } } -func TestProcessPublicTestSuite(t *testing.T) { +func TestProcessPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessPublicTestSuite)) } diff --git a/pkg/sdk/client/process_types_public_test.go b/pkg/sdk/client/process_types_public_test.go index 342b04e22..f92c253f0 100644 --- a/pkg/sdk/client/process_types_public_test.go +++ b/pkg/sdk/client/process_types_public_test.go @@ -370,6 +370,8 @@ func (suite *ProcessTypesPublicTestSuite) TestProcessSignalCollectionFromGen() { } } -func TestProcessTypesPublicTestSuite(t *testing.T) { +func TestProcessTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ProcessTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/response_public_test.go b/pkg/sdk/client/response_public_test.go index c04490824..d52823ac2 100644 --- a/pkg/sdk/client/response_public_test.go +++ b/pkg/sdk/client/response_public_test.go @@ -98,6 +98,8 @@ func (suite *ResponsePublicTestSuite) TestData() { } } -func TestResponsePublicTestSuite(t *testing.T) { +func TestResponsePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ResponsePublicTestSuite)) } diff --git a/pkg/sdk/client/route_public_test.go b/pkg/sdk/client/route_public_test.go index e830a86b4..14b90f3a7 100644 --- a/pkg/sdk/client/route_public_test.go +++ b/pkg/sdk/client/route_public_test.go @@ -814,6 +814,8 @@ func (suite *RoutePublicTestSuite) TestDelete() { } } -func TestRoutePublicTestSuite(t *testing.T) { +func TestRoutePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(RoutePublicTestSuite)) } diff --git a/pkg/sdk/client/route_types_public_test.go b/pkg/sdk/client/route_types_public_test.go index c41882a59..56e6c4a4b 100644 --- a/pkg/sdk/client/route_types_public_test.go +++ b/pkg/sdk/client/route_types_public_test.go @@ -399,6 +399,8 @@ func (suite *RouteTypesPublicTestSuite) TestRouteMutationCollectionFromDelete() } } -func TestRouteTypesPublicTestSuite(t *testing.T) { +func TestRouteTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(RouteTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/service_public_test.go b/pkg/sdk/client/service_public_test.go index 1a852a40a..4dd239469 100644 --- a/pkg/sdk/client/service_public_test.go +++ b/pkg/sdk/client/service_public_test.go @@ -1739,6 +1739,8 @@ func (suite *ServicePublicTestSuite) TestServiceDisable() { } } -func TestServicePublicTestSuite(t *testing.T) { +func TestServicePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServicePublicTestSuite)) } diff --git a/pkg/sdk/client/service_types_public_test.go b/pkg/sdk/client/service_types_public_test.go index 820cbcdcc..5cc7f25ec 100644 --- a/pkg/sdk/client/service_types_public_test.go +++ b/pkg/sdk/client/service_types_public_test.go @@ -514,6 +514,8 @@ func (suite *ServiceTypesPublicTestSuite) TestServiceMutationCollectionFromGen() } } -func TestServiceTypesPublicTestSuite(t *testing.T) { +func TestServiceTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ServiceTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/status_public_test.go b/pkg/sdk/client/status_public_test.go index ffd07d8a1..51f3c3f8c 100644 --- a/pkg/sdk/client/status_public_test.go +++ b/pkg/sdk/client/status_public_test.go @@ -140,6 +140,8 @@ func (suite *StatusPublicTestSuite) TestGet() { } } -func TestStatusPublicTestSuite(t *testing.T) { +func TestStatusPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(StatusPublicTestSuite)) } diff --git a/pkg/sdk/client/sysctl_public_test.go b/pkg/sdk/client/sysctl_public_test.go index 24b1f3be8..470224b9e 100644 --- a/pkg/sdk/client/sysctl_public_test.go +++ b/pkg/sdk/client/sysctl_public_test.go @@ -927,6 +927,8 @@ func (suite *SysctlPublicTestSuite) TestSysctlDelete() { } } -func TestSysctlPublicTestSuite(t *testing.T) { +func TestSysctlPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SysctlPublicTestSuite)) } diff --git a/pkg/sdk/client/sysctl_types_public_test.go b/pkg/sdk/client/sysctl_types_public_test.go index cd142d030..6886e0d82 100644 --- a/pkg/sdk/client/sysctl_types_public_test.go +++ b/pkg/sdk/client/sysctl_types_public_test.go @@ -449,6 +449,8 @@ func (suite *SysctlTypesPublicTestSuite) TestSysctlMutationCollectionFromDelete( } } -func TestSysctlTypesPublicTestSuite(t *testing.T) { +func TestSysctlTypesPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(SysctlTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/timezone_public_test.go b/pkg/sdk/client/timezone_public_test.go index 09702f61d..09d115423 100644 --- a/pkg/sdk/client/timezone_public_test.go +++ b/pkg/sdk/client/timezone_public_test.go @@ -427,6 +427,8 @@ func (suite *TimezonePublicTestSuite) TestTimezoneUpdate() { } } -func TestTimezonePublicTestSuite(t *testing.T) { +func TestTimezonePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(TimezonePublicTestSuite)) } diff --git a/pkg/sdk/client/transport_public_test.go b/pkg/sdk/client/transport_public_test.go index 38e375c60..3606db189 100644 --- a/pkg/sdk/client/transport_public_test.go +++ b/pkg/sdk/client/transport_public_test.go @@ -77,6 +77,8 @@ func (s *TransportPublicTestSuite) TestRoundTripError() { } } -func TestTransportPublicTestSuite(t *testing.T) { +func TestTransportPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(TransportPublicTestSuite)) } diff --git a/pkg/sdk/client/uptime_public_test.go b/pkg/sdk/client/uptime_public_test.go index aa60360ab..09dcbf525 100644 --- a/pkg/sdk/client/uptime_public_test.go +++ b/pkg/sdk/client/uptime_public_test.go @@ -143,6 +143,8 @@ func (suite *UptimePublicTestSuite) TestGet() { } } -func TestUptimePublicTestSuite(t *testing.T) { +func TestUptimePublicTestSuite( + t *testing.T, +) { suite.Run(t, new(UptimePublicTestSuite)) } diff --git a/pkg/sdk/client/user_public_test.go b/pkg/sdk/client/user_public_test.go index 3c7a7f91c..7407673fd 100644 --- a/pkg/sdk/client/user_public_test.go +++ b/pkg/sdk/client/user_public_test.go @@ -873,7 +873,9 @@ func (suite *UserPublicTestSuite) TestUserChangePassword() { } } -func TestUserPublicTestSuite(t *testing.T) { +func TestUserPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(UserPublicTestSuite)) } diff --git a/pkg/sdk/client/user_ssh_key_public_test.go b/pkg/sdk/client/user_ssh_key_public_test.go index 07062eb77..1cda5fdce 100644 --- a/pkg/sdk/client/user_ssh_key_public_test.go +++ b/pkg/sdk/client/user_ssh_key_public_test.go @@ -514,7 +514,9 @@ func (suite *UserSSHKeyPublicTestSuite) TestRemoveKey() { } } -func TestUserSSHKeyPublicTestSuite(t *testing.T) { +func TestUserSSHKeyPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(UserSSHKeyPublicTestSuite)) } diff --git a/pkg/sdk/client/user_ssh_key_types_public_test.go b/pkg/sdk/client/user_ssh_key_types_public_test.go index 83a2ff0f5..6d16c2f1e 100644 --- a/pkg/sdk/client/user_ssh_key_types_public_test.go +++ b/pkg/sdk/client/user_ssh_key_types_public_test.go @@ -375,7 +375,9 @@ func (suite *UserSSHKeyTypesPublicTestSuite) TestSSHKeyMutationResultFromGen() { } } -func TestUserSSHKeyTypesPublicTestSuite(t *testing.T) { +func TestUserSSHKeyTypesPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(UserSSHKeyTypesPublicTestSuite)) } diff --git a/pkg/sdk/client/user_types_public_test.go b/pkg/sdk/client/user_types_public_test.go index e390af326..21a70103b 100644 --- a/pkg/sdk/client/user_types_public_test.go +++ b/pkg/sdk/client/user_types_public_test.go @@ -395,7 +395,9 @@ func (suite *UserTypesPublicTestSuite) TestUserMutationCollectionFromPassword() } } -func TestUserTypesPublicTestSuite(t *testing.T) { +func TestUserTypesPublicTestSuite( + t *testing.T, +) { t.Parallel() suite.Run(t, new(UserTypesPublicTestSuite)) } diff --git a/pkg/sdk/platform/container_public_test.go b/pkg/sdk/platform/container_public_test.go index e8f487899..93f949480 100644 --- a/pkg/sdk/platform/container_public_test.go +++ b/pkg/sdk/platform/container_public_test.go @@ -39,9 +39,9 @@ func (s *ContainerPublicTestSuite) TearDownSubTest() { func (s *ContainerPublicTestSuite) TestIsContainer() { tests := []struct { - name string - setupFS func() - want bool + name string + setupFS func() + validateFunc func(bool) }{ { name: "when /.dockerenv exists", @@ -50,7 +50,9 @@ func (s *ContainerPublicTestSuite) TestIsContainer() { _ = fs.WriteFile("/.dockerenv", []byte(""), 0o644) platform.SetContainerFS(fs) }, - want: true, + validateFunc: func(got bool) { + s.Equal(true, got) + }, }, { name: "when /.dockerenv does not exist", @@ -58,7 +60,9 @@ func (s *ContainerPublicTestSuite) TestIsContainer() { fs := memfs.New() platform.SetContainerFS(fs) }, - want: false, + validateFunc: func(got bool) { + s.Equal(false, got) + }, }, } @@ -68,11 +72,13 @@ func (s *ContainerPublicTestSuite) TestIsContainer() { got := platform.IsContainer() - s.Equal(tc.want, got) + tc.validateFunc(got) }) } } -func TestContainerPublicTestSuite(t *testing.T) { +func TestContainerPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(ContainerPublicTestSuite)) } diff --git a/pkg/sdk/platform/export_test.go b/pkg/sdk/platform/export_test.go index 21074ab38..ea6aadaf8 100644 --- a/pkg/sdk/platform/export_test.go +++ b/pkg/sdk/platform/export_test.go @@ -27,7 +27,9 @@ import ( // SetContainerFS overrides the filesystem used for container detection. // Pass nil to restore the default (osfs). -func SetContainerFS(fs avfs.VFS) { +func SetContainerFS( + fs avfs.VFS, +) { if fs == nil { containerFS = osfs.New() return diff --git a/pkg/sdk/platform/platform_public_test.go b/pkg/sdk/platform/platform_public_test.go index 4dc9ed063..8d9738f7b 100644 --- a/pkg/sdk/platform/platform_public_test.go +++ b/pkg/sdk/platform/platform_public_test.go @@ -35,57 +35,71 @@ type PlatformPublicTestSuite struct { suite.Suite } -func TestPlatformPublicTestSuite(t *testing.T) { +func TestPlatformPublicTestSuite( + t *testing.T, +) { suite.Run(t, new(PlatformPublicTestSuite)) } func (suite *PlatformPublicTestSuite) TestDetect() { tests := []struct { - name string - infoFn func() (*host.InfoStat, error) - expected string + name string + infoFn func() (*host.InfoStat, error) + validateFunc func(string) }{ { name: "returns debian family when platform is Ubuntu", infoFn: func() (*host.InfoStat, error) { return &host.InfoStat{Platform: "Ubuntu"}, nil }, - expected: "debian", + validateFunc: func(got string) { + assert.Equal(suite.T(), "debian", got) + }, }, { name: "returns debian family when platform is debian", infoFn: func() (*host.InfoStat, error) { return &host.InfoStat{Platform: "debian"}, nil }, - expected: "debian", + validateFunc: func(got string) { + assert.Equal(suite.T(), "debian", got) + }, }, { name: "returns darwin when platform is empty and OS is darwin", infoFn: func() (*host.InfoStat, error) { return &host.InfoStat{Platform: "", OS: "darwin"}, nil }, - expected: "darwin", + validateFunc: func(got string) { + assert.Equal(suite.T(), "darwin", got) + }, }, { name: "returns centos for centos platform", infoFn: func() (*host.InfoStat, error) { return &host.InfoStat{Platform: "centos"}, nil }, - expected: "centos", + validateFunc: func(got string) { + assert.Equal(suite.T(), "centos", got) + }, }, { name: "returns empty string when info is nil", infoFn: func() (*host.InfoStat, error) { return nil, fmt.Errorf("no host info") }, - expected: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, { name: "returns empty string when platform and OS are empty", infoFn: func() (*host.InfoStat, error) { return &host.InfoStat{}, nil }, - expected: "", + validateFunc: func(got string) { + assert.Equal(suite.T(), "", got) + }, }, } @@ -97,7 +111,7 @@ func (suite *PlatformPublicTestSuite) TestDetect() { platform.HostInfoFn = tc.infoFn result := platform.Detect() - assert.Equal(suite.T(), tc.expected, result) + tc.validateFunc(result) }) } }