diff --git a/.golangci.yml b/.golangci.yml index c82f8c22..81cf2acf 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -20,6 +20,7 @@ linters: - goprintffuncname # checks that printf-like functions are named with f at the end - gosec # inspects source code for security problems - govet # reports suspicious constructs (go vet) + - importas # enforces one alias per import path (uber-go: Import Aliasing) - ineffassign # detects when assignments to existing variables are not used - lll # reports long lines - loggercheck # checks key-value pairs for common logger libraries (zap, zerolog, ...) @@ -70,6 +71,33 @@ linters: govet: enable: - shadow # reports shadowed variables (disabled by default) + importas: + # Conflict-only map: every entry below is an import path the tree already + # aliases two or more different ways, pinned to the alias the majority of + # call sites already use. Packages with a single consistent alias are left + # out on purpose — listing them would add no findings today and only risk + # a version-stamped path (go.opentelemetry.io/otel/semconv/v1.NN.0) going + # stale and silently matching nothing after the next bump. + # + # `no-unaliased` and `no-extra-aliases` stay OFF: either one turns this + # 11-site cleanup into a ~40-file sweep over imports that read fine. + # + # net/http is deliberately absent — 56 unaliased sites against 7 nethttp + # and 6 stdhttp is not a convention to ratchet, it is a decision nobody + # has made yet. + alias: + - pkg: github.com/gaborage/go-bricks/database/testing + alias: dbtesting + - pkg: github.com/gaborage/go-bricks/jose/testing + alias: jositest + - pkg: github.com/go-jose/go-jose/v4 + alias: jose + - pkg: github.com/rabbitmq/amqp091-go + alias: amqp + # metricznoop (3 sites) outnumbered metricnoop (2) and otelnoop (2), but + # it is a typo — the extra findings buy its deletion. + - pkg: go.opentelemetry.io/otel/metric/noop + alias: metricnoop lll: line-length: 215 misspell: @@ -119,6 +147,7 @@ linters: - name: atomic # non-atomic assignment to an atomic value - name: bare-return # "Avoid Naked Returns" - name: confusing-results # unnamed same-type multi-returns + - name: deep-exit # "Exit in Main": os.Exit/log.Fatal outside main/init - name: early-return # "Reduce Nesting" - name: defer # defer in loop, recover, return-in-defer - name: identical-branches # if/else with identical bodies @@ -178,6 +207,54 @@ linters: - revive path: "trace/" text: "var-naming: avoid package names" + # cmd/seal-payload is the only file set that imports BOTH go-jose/v4 (whose + # package name is `jose`) and github.com/gaborage/go-bricks/jose. One of + # them must be aliased away, and the go-bricks package is the dominant one + # here — so the vendor import keeps `gojose`, which is exactly the + # collision-avoidance case uber-go's "Import Aliasing" prescribes. The + # importas entry still holds everywhere else. + - linters: + - importas + path: ^cmd/seal-payload/ + text: 'go-jose/go-jose/v4' + paths: + - third_party$ + - builtin$ +# Formatters are a separate top-level block in golangci-lint v2 — listing gofumpt +# or gci under `linters.enable` is a hard config error ("can't load config: +# gofumpt is a formatter"). `golangci-lint run` still reports their output as +# ordinary issues ("File is not properly formatted (gci)"), so `make fmt` must +# invoke `golangci-lint fmt`; `go fmt` cannot fix either of these. +formatters: + enable: + - gci # uber-go: "Import Grouping" + - gofumpt # uber-go: "Group Similar Declarations" and the rest of gofmt's stricter superset + settings: + gci: + # Section ORDER is the decision here, and it is deliberate. gci's natural + # order already puts `default` (third party) ahead of a `prefix` group, + # which is how most of this tree was written by hand. Measured against the + # pre-adoption tree at v2.12.2: + # standard, default, prefix(go-bricks) -> 70 files / 290 lines + # standard, default (no prefix section) -> 138 files / 589 lines + # standard, prefix(go-bricks), default -> 199 files / 806 lines + # (that third one needs custom-order: true; without it gci normalises + # the sections straight back to the first order) + # Dropping the prefix section is not merely 2x the churn: re-running the + # no-prefix order against the formatted tree rewrites 197 files, MERGING + # third-party imports back into the go-bricks block in every one. Do not + # "simplify" this by removing the prefix section or hoisting it above + # default. + sections: + - standard + - default + - prefix(github.com/gaborage/go-bricks) + gofumpt: + # extra-rules was measured (+24 lines over the base rules) and rejected: it + # implements no rule the uber-go guide asks for. + extra-rules: false + exclusions: + generated: lax paths: - third_party$ - builtin$ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e3680317..a2c4414f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,7 +36,7 @@ Thank you for your interest in contributing to GoBricks! This document provides ### Code Quality Standards -- **Formatting**: Use `make fmt` to format code with `go fmt` +- **Formatting**: Use `make fmt` to format code with `golangci-lint fmt` (gofmt + gofumpt + gci) - **Linting**: Code must pass `make lint` (golangci-lint) - **Testing**: Add tests for new functionality and ensure `make test` passes - **Security**: Code must pass `gosec` security checks diff --git a/Makefile b/Makefile index ad763e14..cb353587 100644 --- a/Makefile +++ b/Makefile @@ -120,8 +120,17 @@ lint: ## Run golangci-lint (pinned + GOWORK=off, mirroring CI; LINT_CLEAN=1 wipe lint-md: ## Run markdownlint-cli2 on Markdown files (pinned; globs and ignores come from .markdownlint-cli2.jsonc) npx --yes markdownlint-cli2@$(MARKDOWNLINT_VERSION) -fmt: ## Format Go code - go fmt ./... +# `golangci-lint fmt`, not `go fmt`: .golangci.yml declares a formatters block +# (gofumpt + gci) and `golangci-lint run` reports its output as ordinary issues +# ("File is not properly formatted (gci)"). `go fmt` cannot fix either one, so +# with it here `make check` — which is `fmt lint ...` — would reformat and then +# fail lint anyway. Same pinned binary as the `lint` target so both agree on the +# rules — but NOT on the file set: `fmt` reaches //go:build integration files +# (5 needed reformatting at adoption) while `run` does not, neither here nor in +# CI, since no lint job passes -tags=integration. So `run` never fails on drift +# in those files and this target is the only thing that keeps them formatted. +fmt: ## Format Go code (gofmt + gofumpt + gci, per .golangci.yml's formatters block) + GOWORK=off go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) fmt update: ## Update dependencies to latest versions go get -u ./... diff --git a/app/app.go b/app/app.go index de8c7892..d07a7a4f 100644 --- a/app/app.go +++ b/app/app.go @@ -226,7 +226,6 @@ func NewWithConfig(cfg *config.Config, opts *Options) (*App, logger.Logger, erro RegisterClosers(). RegisterReadyHandler(). Build() - if err != nil { // Return the logger from builder if available, otherwise create bootstrap logger if log == nil { diff --git a/app/app_builder_test.go b/app/app_builder_test.go index 713a482e..ef8ab77f 100644 --- a/app/app_builder_test.go +++ b/app/app_builder_test.go @@ -7,6 +7,9 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/cache" cachetesting "github.com/gaborage/go-bricks/cache/testing" "github.com/gaborage/go-bricks/config" @@ -14,8 +17,6 @@ import ( "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/messaging" testmocks "github.com/gaborage/go-bricks/testing/mocks" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) const ( diff --git a/app/app_test.go b/app/app_test.go index ebafc152..2abd6c5a 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -320,8 +320,10 @@ func (m *MockSchedulerModule) MonthlyAt(jobID string, job any, dayOfMonth int, l return m.Called(jobID, job, dayOfMonth, localTime).Error(0) } -var _ Module = (*MockSchedulerModule)(nil) -var _ JobRegistrar = (*MockSchedulerModule)(nil) +var ( + _ Module = (*MockSchedulerModule)(nil) + _ JobRegistrar = (*MockSchedulerModule)(nil) +) // MockJobProviderModule implements Module + JobProvider for testing job registration type MockJobProviderModule struct { @@ -349,8 +351,10 @@ func (m *MockJobProviderModule) RegisterJobs(registrar JobRegistrar) error { return m.Called(registrar).Error(0) } -var _ Module = (*MockJobProviderModule)(nil) -var _ JobProvider = (*MockJobProviderModule)(nil) +var ( + _ Module = (*MockJobProviderModule)(nil) + _ JobProvider = (*MockJobProviderModule)(nil) +) // MockKeyStoreModule implements Module + KeyStoreProvider for testing keystore wiring type MockKeyStoreModule struct { @@ -379,8 +383,10 @@ func (m *MockKeyStoreModule) KeyStore() KeyStore { return m.keyStore } -var _ Module = (*MockKeyStoreModule)(nil) -var _ KeyStoreProvider = (*MockKeyStoreModule)(nil) +var ( + _ Module = (*MockKeyStoreModule)(nil) + _ KeyStoreProvider = (*MockKeyStoreModule)(nil) +) // stubKeyStore is a minimal KeyStore implementation for testing wiring only type stubKeyStore struct{} @@ -686,8 +692,10 @@ func (m *sharedResolverModule) SetSharedResolvers( m.msg = msg } -var _ Module = (*sharedResolverModule)(nil) -var _ sharedResolverSetter = (*sharedResolverModule)(nil) +var ( + _ Module = (*sharedResolverModule)(nil) + _ sharedResolverSetter = (*sharedResolverModule)(nil) +) // TestRegisterModuleInjectsSharedResolvers pins the Step-3 wiring: RegisterModule // must inject non-nil shared ("" key) DB/messaging resolvers into any module @@ -1714,6 +1722,7 @@ func (m *describerModule) DescribeModule() ModuleDescriptor { Version: "1.0.0", } } + func (m *describerModule) DescribeRoutes() []server.RouteDescriptor { return []server.RouteDescriptor{} } diff --git a/app/bootstrap_test.go b/app/bootstrap_test.go index 66cd2835..d366d23a 100644 --- a/app/bootstrap_test.go +++ b/app/bootstrap_test.go @@ -9,9 +9,6 @@ import ( "testing" "time" - "github.com/gaborage/go-bricks/config" - "github.com/gaborage/go-bricks/logger" - "github.com/gaborage/go-bricks/observability" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/metric" @@ -19,6 +16,10 @@ import ( sdklog "go.opentelemetry.io/otel/sdk/log" "go.opentelemetry.io/otel/trace" tracenoop "go.opentelemetry.io/otel/trace/noop" + + "github.com/gaborage/go-bricks/config" + "github.com/gaborage/go-bricks/logger" + "github.com/gaborage/go-bricks/observability" ) const ( @@ -158,6 +159,7 @@ type mockLogEvent struct{} func (e *mockLogEvent) Msg(string) { // No-op } + func (e *mockLogEvent) Msgf(string, ...any) { // No-op } @@ -279,7 +281,7 @@ observability: // Create temporary directory and config file tmpDir := t.TempDir() configPath := filepath.Join(tmpDir, testConfigFile) - err := os.WriteFile(configPath, []byte(yamlContent), 0600) + err := os.WriteFile(configPath, []byte(yamlContent), 0o600) require.NoError(t, err) // Change to temp directory to load config @@ -379,7 +381,7 @@ observability: // Create temporary directory and config file tmpDir := t.TempDir() configPath := filepath.Join(tmpDir, testConfigFile) - err := os.WriteFile(configPath, []byte(yamlContent), 0600) + err := os.WriteFile(configPath, []byte(yamlContent), 0o600) require.NoError(t, err) // Set environment variables to override config @@ -466,7 +468,7 @@ observability: // Create temporary directory and config file tmpDir := t.TempDir() configPath := filepath.Join(tmpDir, testConfigFile) - err := os.WriteFile(configPath, []byte(yamlContent), 0600) + err := os.WriteFile(configPath, []byte(yamlContent), 0o600) require.NoError(t, err) // Change to temp directory to load config @@ -525,7 +527,7 @@ debug: // Create temporary directory and config file tmpDir := t.TempDir() configPath := filepath.Join(tmpDir, testConfigFile) - err := os.WriteFile(configPath, []byte(yamlContent), 0600) + err := os.WriteFile(configPath, []byte(yamlContent), 0o600) require.NoError(t, err) // Change to temp directory to load config diff --git a/app/debug_health_test.go b/app/debug_health_test.go index ab3f3c71..2e45ab7a 100644 --- a/app/debug_health_test.go +++ b/app/debug_health_test.go @@ -15,7 +15,7 @@ import ( "github.com/gaborage/go-bricks/cache" "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database" - dbtest "github.com/gaborage/go-bricks/database/testing" + dbtesting "github.com/gaborage/go-bricks/database/testing" "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/messaging" "github.com/gaborage/go-bricks/server" @@ -472,7 +472,7 @@ func TestHealthDebugKeepsPooledConnectionKeysWhileReadyOmitsThem(t *testing.T) { log := &recLogger{} connector := func(*config.DatabaseConfig, logger.Logger) (database.Interface, error) { - return dbtest.NewTestDB(dbTypePostgres), nil + return dbtesting.NewTestDB(dbTypePostgres), nil } dbManager := database.NewDbManager(&stubTenantResource{}, log, database.DbManagerOptions{MaxSize: 5, IdleTTL: time.Hour}, connector) diff --git a/app/factory_resolver_integration_test.go b/app/factory_resolver_integration_test.go index 8b827b3c..6f3198dc 100644 --- a/app/factory_resolver_integration_test.go +++ b/app/factory_resolver_integration_test.go @@ -7,12 +7,13 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + cachepkg "github.com/gaborage/go-bricks/cache" "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/testing/containers" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // TestFactoryResolverRedisConnectorIntegration tests the Redis cache connector diff --git a/app/factory_resolver_test.go b/app/factory_resolver_test.go index 5fa462bc..2126f107 100644 --- a/app/factory_resolver_test.go +++ b/app/factory_resolver_test.go @@ -5,10 +5,11 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/gaborage/go-bricks/cache" "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/logger" - "github.com/stretchr/testify/assert" ) const ( diff --git a/app/health_test.go b/app/health_test.go index d2f485af..68a01141 100644 --- a/app/health_test.go +++ b/app/health_test.go @@ -7,6 +7,9 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/cache" cachetesting "github.com/gaborage/go-bricks/cache/testing" "github.com/gaborage/go-bricks/config" @@ -15,8 +18,6 @@ import ( "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/messaging" testmocks "github.com/gaborage/go-bricks/testing/mocks" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // Note: Since the health probe functions work with concrete types (*database.DbManager, *messaging.Manager), diff --git a/app/lifecycle_test.go b/app/lifecycle_test.go index 20e3ffbe..60dea458 100644 --- a/app/lifecycle_test.go +++ b/app/lifecycle_test.go @@ -15,7 +15,7 @@ import ( "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database" - dbtest "github.com/gaborage/go-bricks/database/testing" + dbtesting "github.com/gaborage/go-bricks/database/testing" "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/messaging" "github.com/gaborage/go-bricks/server" @@ -506,7 +506,7 @@ func TestStartMaintenanceLoopsUsesConfiguredDatabaseCleanupInterval(t *testing.T log := logger.New("error", false) connector := func(*config.DatabaseConfig, logger.Logger) (database.Interface, error) { - return dbtest.NewTestDB("postgresql"), nil + return dbtesting.NewTestDB("postgresql"), nil } dbManager := database.NewDbManager(&stubTenantResource{}, log, database.DbManagerOptions{MaxSize: 5, IdleTTL: 10 * time.Millisecond}, connector) defer func() { _ = dbManager.Close() }() diff --git a/app/managers_test.go b/app/managers_test.go index 3c293d33..e249bb56 100644 --- a/app/managers_test.go +++ b/app/managers_test.go @@ -6,14 +6,15 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/cache" "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database" "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/messaging" testmocks "github.com/gaborage/go-bricks/testing/mocks" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) const ( diff --git a/app/module.go b/app/module.go index 1505da7a..6efa4da1 100644 --- a/app/module.go +++ b/app/module.go @@ -5,6 +5,9 @@ import ( "crypto/rsa" "time" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/trace" + "github.com/gaborage/go-bricks/cache" "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database" @@ -12,8 +15,6 @@ import ( "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/messaging" "github.com/gaborage/go-bricks/server" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/trace" ) // Module defines the core interface that all application modules must implement. diff --git a/app/module_registry_test.go b/app/module_registry_test.go index dfcf9a03..ecce59a1 100644 --- a/app/module_registry_test.go +++ b/app/module_registry_test.go @@ -293,14 +293,20 @@ func TestRegisterAcceptsModulesWhenDatabaseRequirementDoesNotApply(t *testing.T) module Module rootDBAbsent bool }{ - {name: "requirer_with_database_present", rootDBAbsent: false, - module: &fakeDBRequiringModule{name: "payments", requires: true}}, + { + name: "requirer_with_database_present", rootDBAbsent: false, + module: &fakeDBRequiringModule{name: "payments", requires: true}, + }, // A module may implement the interface and still decline, gating the // requirement on its own construction-time config. - {name: "requirer_declines_requirement", rootDBAbsent: true, - module: &fakeDBRequiringModule{name: "payments", requires: false}}, - {name: "module_never_declares_requirement", rootDBAbsent: true, - module: &minimalModule{name: "forwarder"}}, + { + name: "requirer_declines_requirement", rootDBAbsent: true, + module: &fakeDBRequiringModule{name: "payments", requires: false}, + }, + { + name: "module_never_declares_requirement", rootDBAbsent: true, + module: &minimalModule{name: "forwarder"}, + }, } for _, tt := range tests { diff --git a/cache/errors_test.go b/cache/errors_test.go index 81bdd24b..a5b7db9c 100644 --- a/cache/errors_test.go +++ b/cache/errors_test.go @@ -4,8 +4,9 @@ import ( "errors" "testing" - "github.com/gaborage/go-bricks/internal/testutil" "github.com/stretchr/testify/assert" + + "github.com/gaborage/go-bricks/internal/testutil" ) const ( diff --git a/cache/manager_test.go b/cache/manager_test.go index f4f704c1..992879c0 100644 --- a/cache/manager_test.go +++ b/cache/manager_test.go @@ -9,9 +9,10 @@ import ( "testing" "time" - "github.com/gaborage/go-bricks/cache" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/cache" ) const ( diff --git a/cmd/seal-payload/main.go b/cmd/seal-payload/main.go index 0de7212d..137189f7 100644 --- a/cmd/seal-payload/main.go +++ b/cmd/seal-payload/main.go @@ -25,9 +25,10 @@ import ( "io" "os" + gojose "github.com/go-jose/go-jose/v4" + "github.com/gaborage/go-bricks/internal/keymaterial" jose "github.com/gaborage/go-bricks/jose" - gojose "github.com/go-jose/go-jose/v4" ) // errUsage marks flag-parse failures whose message the FlagSet already diff --git a/config/config_test.go b/config/config_test.go index 4c7c53fa..bbc09d98 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1154,7 +1154,7 @@ server: port: 9000 ` tmpFile := testConfigFile - err := os.WriteFile(tmpFile, []byte(content), 0644) + err := os.WriteFile(tmpFile, []byte(content), 0o644) require.NoError(t, err) defer os.Remove(tmpFile) @@ -1184,11 +1184,11 @@ app: yamlFile := testConfigFileYAML ymlFile := testConfigFile - err := os.WriteFile(yamlFile, []byte(yamlContent), 0644) + err := os.WriteFile(yamlFile, []byte(yamlContent), 0o644) require.NoError(t, err) defer os.Remove(yamlFile) - err = os.WriteFile(ymlFile, []byte(ymlContent), 0644) + err = os.WriteFile(ymlFile, []byte(ymlContent), 0o644) require.NoError(t, err) defer os.Remove(ymlFile) @@ -1210,7 +1210,7 @@ app: env: production ` baseFile := testConfigFile - err := os.WriteFile(baseFile, []byte(baseContent), 0644) + err := os.WriteFile(baseFile, []byte(baseContent), 0o644) require.NoError(t, err) defer os.Remove(baseFile) @@ -1222,7 +1222,7 @@ server: port: 8090 ` envFile := "config.production.yml" - err = os.WriteFile(envFile, []byte(envContent), 0644) + err = os.WriteFile(envFile, []byte(envContent), 0o644) require.NoError(t, err) defer os.Remove(envFile) @@ -1254,11 +1254,11 @@ server: yamlFile := "config.development.yaml" ymlFile := "config.development.yml" - err := os.WriteFile(yamlFile, []byte(yamlContent), 0644) + err := os.WriteFile(yamlFile, []byte(yamlContent), 0o644) require.NoError(t, err) defer os.Remove(yamlFile) - err = os.WriteFile(ymlFile, []byte(ymlContent), 0644) + err = os.WriteFile(ymlFile, []byte(ymlContent), 0o644) require.NoError(t, err) defer os.Remove(ymlFile) @@ -1297,7 +1297,7 @@ app: version: v1.0.0 ` tmpFile := testConfigFileYAML - err := os.WriteFile(tmpFile, []byte(invalidYAML), 0644) + err := os.WriteFile(tmpFile, []byte(invalidYAML), 0o644) require.NoError(t, err) defer os.Remove(tmpFile) @@ -1319,7 +1319,7 @@ app: env: production ` baseFile := testConfigFileYAML - err := os.WriteFile(baseFile, []byte(validYAML), 0644) + err := os.WriteFile(baseFile, []byte(validYAML), 0o644) require.NoError(t, err) defer os.Remove(baseFile) @@ -1330,7 +1330,7 @@ app: broken: [unclosed bracket ` envFile := "config.production.yaml" - err = os.WriteFile(envFile, []byte(invalidEnvYAML), 0644) + err = os.WriteFile(envFile, []byte(invalidEnvYAML), 0o644) require.NoError(t, err) defer os.Remove(envFile) diff --git a/config/errors_test.go b/config/errors_test.go index 116d71ea..e88f7edc 100644 --- a/config/errors_test.go +++ b/config/errors_test.go @@ -4,8 +4,9 @@ import ( "errors" "testing" - "github.com/gaborage/go-bricks/internal/testutil" "github.com/stretchr/testify/assert" + + "github.com/gaborage/go-bricks/internal/testutil" ) const ( diff --git a/config/tenant_store_test.go b/config/tenant_store_test.go index 89562f1b..5024ec0e 100644 --- a/config/tenant_store_test.go +++ b/config/tenant_store_test.go @@ -511,7 +511,6 @@ func TestTenantStoreDBConfigTenantAndNamedKeysStayLoud(t *testing.T) { for _, key := range []string{tenantA, NamedDatabasePrefix + "reporting"} { t.Run(key, func(t *testing.T) { got, err := store.DBConfig(context.Background(), key) - if err != nil { assert.False(t, IsNotConfigured(err), "a malformed %s must not read as absent", key) return diff --git a/database/errors_integration_test.go b/database/errors_integration_test.go index f780ea08..53187a08 100644 --- a/database/errors_integration_test.go +++ b/database/errors_integration_test.go @@ -7,11 +7,12 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database/internal/dbtestlog" "github.com/gaborage/go-bricks/testing/containers" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // These tests prove the constraint classifiers in errors.go diff --git a/database/execute_test.go b/database/execute_test.go index a41a3c44..1478be5e 100644 --- a/database/execute_test.go +++ b/database/execute_test.go @@ -8,11 +8,12 @@ import ( "io" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/database" dbtesting "github.com/gaborage/go-bricks/database/testing" dbtypes "github.com/gaborage/go-bricks/database/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // Compile-time proof every builder and Raw() satisfy SQLProvider. diff --git a/database/internal/builder/filter.go b/database/internal/builder/filter.go index 1994aa14..e77b8cb7 100644 --- a/database/internal/builder/filter.go +++ b/database/internal/builder/filter.go @@ -4,6 +4,7 @@ import ( "reflect" "github.com/Masterminds/squirrel" + dbtypes "github.com/gaborage/go-bricks/database/types" ) diff --git a/database/internal/builder/filter_test.go b/database/internal/builder/filter_test.go index 342bde92..e485abe2 100644 --- a/database/internal/builder/filter_test.go +++ b/database/internal/builder/filter_test.go @@ -5,9 +5,10 @@ import ( "errors" "testing" - dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + dbtypes "github.com/gaborage/go-bricks/database/types" ) const ( diff --git a/database/internal/builder/join_filter.go b/database/internal/builder/join_filter.go index 746f1c20..da3fecef 100644 --- a/database/internal/builder/join_filter.go +++ b/database/internal/builder/join_filter.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/Masterminds/squirrel" + dbtypes "github.com/gaborage/go-bricks/database/types" ) diff --git a/database/internal/builder/join_filter_test.go b/database/internal/builder/join_filter_test.go index c51110db..f6420eb7 100644 --- a/database/internal/builder/join_filter_test.go +++ b/database/internal/builder/join_filter_test.go @@ -3,9 +3,10 @@ package builder import ( "testing" - dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + dbtypes "github.com/gaborage/go-bricks/database/types" ) const ( diff --git a/database/internal/builder/query_builder.go b/database/internal/builder/query_builder.go index ea5ac344..7cf440b0 100644 --- a/database/internal/builder/query_builder.go +++ b/database/internal/builder/query_builder.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/Masterminds/squirrel" + colreg "github.com/gaborage/go-bricks/database/internal/columns" dbtypes "github.com/gaborage/go-bricks/database/types" ) diff --git a/database/internal/builder/query_builder_test.go b/database/internal/builder/query_builder_test.go index 6bb4fac6..5baed4e4 100644 --- a/database/internal/builder/query_builder_test.go +++ b/database/internal/builder/query_builder_test.go @@ -7,10 +7,11 @@ import ( "testing" "github.com/Masterminds/squirrel" - "github.com/gaborage/go-bricks/database/internal/columns" - dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/database/internal/columns" + dbtypes "github.com/gaborage/go-bricks/database/types" ) // TestNewQueryBuilderConcurrentSharedBuilders exercises the per-vendor package-level @@ -982,6 +983,7 @@ func TestTableAliasInvalidTypes(t *testing.T) { }) }) } + func TestSelectExpressions(t *testing.T) { t.Run("Simple expression without alias", func(t *testing.T) { qb := NewQueryBuilder(dbtypes.Oracle) diff --git a/database/internal/columns/parser_test.go b/database/internal/columns/parser_test.go index f1dabc70..f7c2de5b 100644 --- a/database/internal/columns/parser_test.go +++ b/database/internal/columns/parser_test.go @@ -4,10 +4,11 @@ import ( "reflect" "testing" - "github.com/gaborage/go-bricks/database/internal/sqllex" - dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/database/internal/sqllex" + dbtypes "github.com/gaborage/go-bricks/database/types" ) const ( diff --git a/database/internal/columns/registry_test.go b/database/internal/columns/registry_test.go index 66b87c1e..a204aab7 100644 --- a/database/internal/columns/registry_test.go +++ b/database/internal/columns/registry_test.go @@ -4,9 +4,10 @@ import ( "sync" "testing" - dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + dbtypes "github.com/gaborage/go-bricks/database/types" ) // Test structs for registry tests diff --git a/database/internal/tracking/metrics.go b/database/internal/tracking/metrics.go index 55426b5f..fa41b0cd 100644 --- a/database/internal/tracking/metrics.go +++ b/database/internal/tracking/metrics.go @@ -517,7 +517,8 @@ func (r *poolMetricsRegistration) observePoolStats(_ context.Context, observer m // with others and provides partial metrics coverage. func RegisterConnectionPoolMetrics(conn interface { Stats() (map[string]any, error) -}, vendor, serverAddress string, serverPort int, namespace string) func() { +}, vendor, serverAddress string, serverPort int, namespace string, +) func() { meter := getDBMeter() if meter == nil { return noOpCleanup() diff --git a/database/oracle/connection.go b/database/oracle/connection.go index de99379f..2929dbbf 100644 --- a/database/oracle/connection.go +++ b/database/oracle/connection.go @@ -438,8 +438,10 @@ func logConnectionSuccess(log logger.Logger, cfg *config.DatabaseConfig) { } // Oracle re-exports the vendor-agnostic wrappers; see database/internal/wrapper. -type Statement = wrapper.Statement -type Transaction = wrapper.Transaction +type ( + Statement = wrapper.Statement + Transaction = wrapper.Transaction +) // Query, QueryRow, Exec, Prepare, Begin, BeginTx, Health, Stats, Close are // inherited from the embedded *wrapper.Connection — see database/internal/wrapper. diff --git a/database/oracle/connection_integration_test.go b/database/oracle/connection_integration_test.go index 99bda3e2..c98bcb9d 100644 --- a/database/oracle/connection_integration_test.go +++ b/database/oracle/connection_integration_test.go @@ -10,11 +10,11 @@ import ( "time" go_ora "github.com/sijms/go-ora/v2" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database/internal/dbtestlog" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) const ( diff --git a/database/oracle/connection_test.go b/database/oracle/connection_test.go index 24ad95be..ad8e99bb 100644 --- a/database/oracle/connection_test.go +++ b/database/oracle/connection_test.go @@ -1424,7 +1424,6 @@ func TestConnectionRegisterType(t *testing.T) { // Register without collection type err := c.RegisterType("PRODUCT_TYPE", "", Product{}) - // Method should exist and handle gracefully (may fail without real Oracle) if err != nil { t.Logf("RegisterType returned error (expected without Oracle): %v", err) @@ -1436,7 +1435,6 @@ func TestConnectionRegisterType(t *testing.T) { // Primary use case: register collection type err := c.RegisterType("PRODUCT_TYPE", "PRODUCT_TABLE", Product{}) - if err != nil { t.Logf("RegisterType with collection returned error: %v", err) } @@ -1461,7 +1459,6 @@ func TestConnectionRegisterTypeWithOwner(t *testing.T) { }() err := c.RegisterTypeWithOwner("SHARED_SCHEMA", "CUSTOMER_TYPE", "", Customer{}) - if err != nil { t.Logf("RegisterTypeWithOwner returned error: %v", err) } @@ -1478,7 +1475,6 @@ func TestConnectionRegisterTypeWithOwner(t *testing.T) { }() err := c.RegisterTypeWithOwner("SHARED_SCHEMA", "CUSTOMER_TYPE", "CUSTOMER_TABLE", Customer{}) - if err != nil { t.Logf("RegisterTypeWithOwner with collection returned error: %v", err) } diff --git a/database/postgresql/connection.go b/database/postgresql/connection.go index 5651024b..03af3e7b 100644 --- a/database/postgresql/connection.go +++ b/database/postgresql/connection.go @@ -218,8 +218,10 @@ func NewConnection(cfg *config.DatabaseConfig, log logger.Logger) (types.Interfa } // PostgreSQL re-exports the vendor-agnostic wrappers; see database/internal/wrapper. -type Statement = wrapper.Statement -type Transaction = wrapper.Transaction +type ( + Statement = wrapper.Statement + Transaction = wrapper.Transaction +) // DatabaseType returns the database type func (c *Connection) DatabaseType() string { diff --git a/database/postgresql/connection_integration_test.go b/database/postgresql/connection_integration_test.go index 014122d0..70ad46e1 100644 --- a/database/postgresql/connection_integration_test.go +++ b/database/postgresql/connection_integration_test.go @@ -9,11 +9,12 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database/internal/dbtestlog" "github.com/gaborage/go-bricks/testing/containers" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) const ( diff --git a/database/postgresql/connection_test.go b/database/postgresql/connection_test.go index 46c95d44..62437eff 100644 --- a/database/postgresql/connection_test.go +++ b/database/postgresql/connection_test.go @@ -11,13 +11,13 @@ import ( "time" sqlmock "github.com/DATA-DOG/go-sqlmock" + "github.com/jackc/pgx/v5" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database/internal/dbtestlog" "github.com/gaborage/go-bricks/database/internal/wrapper" - "github.com/jackc/pgx/v5" ) const ( diff --git a/database/testing/fake_db_test.go b/database/testing/fake_db_test.go index 54a8c4f9..60b2f367 100644 --- a/database/testing/fake_db_test.go +++ b/database/testing/fake_db_test.go @@ -6,8 +6,9 @@ import ( "testing" "time" - dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/stretchr/testify/assert" + + dbtypes "github.com/gaborage/go-bricks/database/types" ) const ( diff --git a/database/testing/null_scan_test.go b/database/testing/null_scan_test.go index c5a79b7b..46d02972 100644 --- a/database/testing/null_scan_test.go +++ b/database/testing/null_scan_test.go @@ -4,8 +4,9 @@ import ( "context" "testing" - dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/stretchr/testify/assert" + + dbtypes "github.com/gaborage/go-bricks/database/types" ) // TestNullScanBehavior verifies that TestDB matches database/sql behavior for NULL scans. diff --git a/database/transaction_test.go b/database/transaction_test.go index fa597cdf..cb1ba511 100644 --- a/database/transaction_test.go +++ b/database/transaction_test.go @@ -6,11 +6,12 @@ import ( "errors" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/database" dbtesting "github.com/gaborage/go-bricks/database/testing" dbtypes "github.com/gaborage/go-bricks/database/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestWithTxCommitsOnSuccess(t *testing.T) { diff --git a/database/types/subquery_test.go b/database/types/subquery_test.go index f6a6c883..90c44a1a 100644 --- a/database/types/subquery_test.go +++ b/database/types/subquery_test.go @@ -19,9 +19,11 @@ func (m *mockValidSubquery) JoinOn(_ any, _ JoinFilter) SelectQueryBuilder { ret func (m *mockValidSubquery) LeftJoinOn(_ any, _ JoinFilter) SelectQueryBuilder { return m } + func (m *mockValidSubquery) RightJoinOn(_ any, _ JoinFilter) SelectQueryBuilder { return m } + func (m *mockValidSubquery) InnerJoinOn(_ any, _ JoinFilter) SelectQueryBuilder { return m } @@ -46,9 +48,11 @@ func (m *mockInvalidSubquery) JoinOn(_ any, _ JoinFilter) SelectQueryBuilder { r func (m *mockInvalidSubquery) LeftJoinOn(_ any, _ JoinFilter) SelectQueryBuilder { return m } + func (m *mockInvalidSubquery) RightJoinOn(_ any, _ JoinFilter) SelectQueryBuilder { return m } + func (m *mockInvalidSubquery) InnerJoinOn(_ any, _ JoinFilter) SelectQueryBuilder { return m } @@ -73,9 +77,11 @@ func (m *mockEmptySubquery) JoinOn(_ any, _ JoinFilter) SelectQueryBuilder { ret func (m *mockEmptySubquery) LeftJoinOn(_ any, _ JoinFilter) SelectQueryBuilder { return m } + func (m *mockEmptySubquery) RightJoinOn(_ any, _ JoinFilter) SelectQueryBuilder { return m } + func (m *mockEmptySubquery) InnerJoinOn(_ any, _ JoinFilter) SelectQueryBuilder { return m } diff --git a/httpclient/client.go b/httpclient/client.go index 42d181b8..30e12c3b 100644 --- a/httpclient/client.go +++ b/httpclient/client.go @@ -20,14 +20,13 @@ import ( "sync/atomic" "time" - "github.com/gaborage/go-bricks/jose" - "github.com/gaborage/go-bricks/logger" - - "github.com/gaborage/go-bricks/httpclient/internal/tracking" - "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/trace" + + "github.com/gaborage/go-bricks/httpclient/internal/tracking" + "github.com/gaborage/go-bricks/jose" + "github.com/gaborage/go-bricks/logger" ) const ( diff --git a/httpclient/client_test.go b/httpclient/client_test.go index b04686b4..e1e90715 100644 --- a/httpclient/client_test.go +++ b/httpclient/client_test.go @@ -25,12 +25,11 @@ import ( "go.opentelemetry.io/otel/sdk/trace/tracetest" tracenoop "go.opentelemetry.io/otel/trace/noop" - obtest "github.com/gaborage/go-bricks/observability/testing" - "github.com/gaborage/go-bricks/httpclient/internal/tracking" "github.com/gaborage/go-bricks/jose" jositest "github.com/gaborage/go-bricks/jose/testing" "github.com/gaborage/go-bricks/logger" + obtest "github.com/gaborage/go-bricks/observability/testing" ) // Test constants to avoid string duplication diff --git a/httpclient/logging_test.go b/httpclient/logging_test.go index 1bfc7d5c..6ea8fa36 100644 --- a/httpclient/logging_test.go +++ b/httpclient/logging_test.go @@ -557,7 +557,6 @@ func TestLoggingIntegration(t *testing.T) { // Test that logging methods work req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "http://test.com", http.NoBody) - if err != nil { t.Fatalf("failed to create request: %v", err) } @@ -582,7 +581,6 @@ func TestLoggingIntegration(t *testing.T) { } req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, "http://test.com", http.NoBody) - if err != nil { t.Fatalf("failed to create request: %v", err) } diff --git a/httpclient/tls_test.go b/httpclient/tls_test.go index 53b78f02..91fcf244 100644 --- a/httpclient/tls_test.go +++ b/httpclient/tls_test.go @@ -25,9 +25,10 @@ import ( "testing" "time" - "github.com/gaborage/go-bricks/internal/secretfile" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/internal/secretfile" ) const testServerName = "partner.example.com" diff --git a/inbox/config_test.go b/inbox/config_test.go index 71e92936..93fc23f8 100644 --- a/inbox/config_test.go +++ b/inbox/config_test.go @@ -4,9 +4,10 @@ import ( "testing" "time" - "github.com/gaborage/go-bricks/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/config" ) func TestApplyDefaults(t *testing.T) { diff --git a/inbox/coverage_test.go b/inbox/coverage_test.go index 3db06b82..0f97aa10 100644 --- a/inbox/coverage_test.go +++ b/inbox/coverage_test.go @@ -6,14 +6,15 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/config" dbtesting "github.com/gaborage/go-bricks/database/testing" dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/messaging" "github.com/gaborage/go-bricks/multitenant" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // captureStore records the tenant present in the context of each DeleteProcessed call, diff --git a/inbox/inbox_test.go b/inbox/inbox_test.go index 57d670ac..46100187 100644 --- a/inbox/inbox_test.go +++ b/inbox/inbox_test.go @@ -5,14 +5,15 @@ import ( "errors" "testing" + amqp "github.com/rabbitmq/amqp091-go" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/config" dbtesting "github.com/gaborage/go-bricks/database/testing" dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/gaborage/go-bricks/messaging" "github.com/gaborage/go-bricks/outbox" - amqp "github.com/rabbitmq/amqp091-go" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // newTestInbox builds an Inbox whose module resolves to the given test DB. diff --git a/inbox/module_test.go b/inbox/module_test.go index 5e5a386c..599adc74 100644 --- a/inbox/module_test.go +++ b/inbox/module_test.go @@ -6,13 +6,14 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/app" "github.com/gaborage/go-bricks/config" dbtesting "github.com/gaborage/go-bricks/database/testing" dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/gaborage/go-bricks/logger" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // fakeRegistrar captures DailyAt registrations. Implements app.JobRegistrar. diff --git a/inbox/store_integration_test.go b/inbox/store_integration_test.go index 6edbef80..84a99263 100644 --- a/inbox/store_integration_test.go +++ b/inbox/store_integration_test.go @@ -7,13 +7,14 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database" "github.com/gaborage/go-bricks/logger" testconsts "github.com/gaborage/go-bricks/testing" "github.com/gaborage/go-bricks/testing/containers" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // These tests prove the inbox ledger Store works end to end against REAL diff --git a/inbox/store_oracle_test.go b/inbox/store_oracle_test.go index cd17a8c8..42e4a714 100644 --- a/inbox/store_oracle_test.go +++ b/inbox/store_oracle_test.go @@ -5,11 +5,12 @@ import ( "testing" "time" - dbtesting "github.com/gaborage/go-bricks/database/testing" - dbtypes "github.com/gaborage/go-bricks/database/types" oranet "github.com/sijms/go-ora/v2/network" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + dbtesting "github.com/gaborage/go-bricks/database/testing" + dbtypes "github.com/gaborage/go-bricks/database/types" ) const oracleTestTable = "gobricks_inbox" diff --git a/inbox/store_postgres_test.go b/inbox/store_postgres_test.go index ded03d34..f12e3a53 100644 --- a/inbox/store_postgres_test.go +++ b/inbox/store_postgres_test.go @@ -6,10 +6,11 @@ import ( "testing" "time" - dbtesting "github.com/gaborage/go-bricks/database/testing" - dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + dbtesting "github.com/gaborage/go-bricks/database/testing" + dbtypes "github.com/gaborage/go-bricks/database/types" ) const pgTestTable = "gobricks_inbox" diff --git a/inbox/testing/mock_inbox_test.go b/inbox/testing/mock_inbox_test.go index 198032f0..60f02c8c 100644 --- a/inbox/testing/mock_inbox_test.go +++ b/inbox/testing/mock_inbox_test.go @@ -5,11 +5,12 @@ import ( "errors" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/app" dbtypes "github.com/gaborage/go-bricks/database/types" inboxtest "github.com/gaborage/go-bricks/inbox/testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // Compile-time guard: MockInbox satisfies the production interface. diff --git a/internal/resourcepool/resourcepool_test.go b/internal/resourcepool/resourcepool_test.go index 5296a25b..ea62db0a 100644 --- a/internal/resourcepool/resourcepool_test.go +++ b/internal/resourcepool/resourcepool_test.go @@ -227,7 +227,8 @@ type leaseResult struct { // immediately, so machine load cannot flake it. unblock lets the in-flight create drain if we do // give up. func getOrCreateBounded(ctx context.Context, t *testing.T, p *Pool[*fakeResource], key string, - create func(context.Context) (*fakeResource, error), unblock func()) leaseResult { + create func(context.Context) (*fakeResource, error), unblock func(), +) leaseResult { t.Helper() out := make(chan leaseResult, 1) go func() { diff --git a/internal/tenantstore/tenantstore_test.go b/internal/tenantstore/tenantstore_test.go index a2e2517d..e27bbd61 100644 --- a/internal/tenantstore/tenantstore_test.go +++ b/internal/tenantstore/tenantstore_test.go @@ -8,13 +8,14 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/config" dbtesting "github.com/gaborage/go-bricks/database/testing" dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/multitenant" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // fakeStore implements TableCreator with a controllable CreateTable outcome. @@ -322,20 +323,28 @@ func TestStartupCheckApplies(t *testing.T) { }{ {name: "nil_config", cfg: nil, sharedLedger: false, want: false}, {name: "single_tenant_static_source", cfg: &config.Config{}, sharedLedger: false, want: true}, - {name: "dynamic_source_skips", + { + name: "dynamic_source_skips", cfg: &config.Config{Source: config.SourceConfig{Type: config.SourceTypeDynamic}}, - sharedLedger: false, want: false}, - {name: "per_tenant_multitenant_skips", + sharedLedger: false, want: false, + }, + { + name: "per_tenant_multitenant_skips", cfg: &config.Config{Multitenant: config.MultitenantConfig{Enabled: true}}, - sharedLedger: false, want: false}, - {name: "shared_ledger_multitenant_applies", + sharedLedger: false, want: false, + }, + { + name: "shared_ledger_multitenant_applies", cfg: &config.Config{Multitenant: config.MultitenantConfig{Enabled: true}}, - sharedLedger: true, want: true}, - {name: "shared_ledger_dynamic_source_skips", + sharedLedger: true, want: true, + }, + { + name: "shared_ledger_dynamic_source_skips", cfg: &config.Config{ Multitenant: config.MultitenantConfig{Enabled: true}, Source: config.SourceConfig{Type: config.SourceTypeDynamic}, - }, sharedLedger: true, want: false}, + }, sharedLedger: true, want: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/jose/jose_properties_test.go b/jose/jose_properties_test.go index 8d91201c..e1c7898c 100644 --- a/jose/jose_properties_test.go +++ b/jose/jose_properties_test.go @@ -11,11 +11,11 @@ import ( "pgregory.net/rapid" "github.com/gaborage/go-bricks/jose" - josetest "github.com/gaborage/go-bricks/jose/testing" + jositest "github.com/gaborage/go-bricks/jose/testing" ) func TestSealOpenRoundTripProperty(t *testing.T) { - fx := josetest.NewBidirectionalFixture(t) // keygen once; iterations reuse + fx := jositest.NewBidirectionalFixture(t) // keygen once; iterations reuse rapid.Check(t, func(rt *rapid.T) { payload := rapid.SliceOfN(rapid.Byte(), 1, 4096).Draw(rt, "payload") sealed, err := jose.Seal(payload, fx.ClientOutbound, fx.Resolver) @@ -36,9 +36,9 @@ func TestSealOpenRoundTripProperty(t *testing.T) { // swap can decode identically. It is: Open never succeeds with plaintext // different from the original. func TestOpenTamperNeverAltersPayloadProperty(t *testing.T) { - fx := josetest.NewBidirectionalFixture(t) + fx := jositest.NewBidirectionalFixture(t) payload := []byte(`{"amount":"100.00","currency":"USD"}`) - sealed := josetest.SealForTest(t, payload, fx.ClientOutbound, fx.Resolver) + sealed := jositest.SealForTest(t, payload, fx.ClientOutbound, fx.Resolver) const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" rapid.Check(t, func(rt *rapid.T) { @@ -61,9 +61,9 @@ func TestOpenTamperNeverAltersPayloadProperty(t *testing.T) { // cryptographic input — header is AAD, key/IV/ciphertext/tag feed OAEP or // GCM — so Open must always fail. func TestOpenSemanticTamperAlwaysFailsProperty(t *testing.T) { - fx := josetest.NewBidirectionalFixture(t) + fx := jositest.NewBidirectionalFixture(t) payload := []byte(`{"amount":"100.00","currency":"USD"}`) - sealed := josetest.SealForTest(t, payload, fx.ClientOutbound, fx.Resolver) + sealed := jositest.SealForTest(t, payload, fx.ClientOutbound, fx.Resolver) parts := strings.Split(sealed, ".") rapid.Check(t, func(rt *rapid.T) { diff --git a/jose/opener_test.go b/jose/opener_test.go index 2e7735b5..cab54b35 100644 --- a/jose/opener_test.go +++ b/jose/opener_test.go @@ -4,9 +4,10 @@ import ( "errors" "testing" - "github.com/gaborage/go-bricks/jose/internal/cryptoadapter" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/jose/internal/cryptoadapter" ) // Direct unit tests for mapDecryptError / mapVerifyError. The end-to-end roundtrip diff --git a/jose/resolver_test.go b/jose/resolver_test.go index cde8dc2d..f22b4e06 100644 --- a/jose/resolver_test.go +++ b/jose/resolver_test.go @@ -6,9 +6,10 @@ import ( "fmt" "testing" - "github.com/gaborage/go-bricks/jose" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/jose" ) // fakeKS is a minimal in-test stub satisfying jose.KeyStoreLike. Inlined here rather diff --git a/jose/testing/helpers_test.go b/jose/testing/helpers_test.go index 29eb5c3b..abd7fdc4 100644 --- a/jose/testing/helpers_test.go +++ b/jose/testing/helpers_test.go @@ -3,10 +3,11 @@ package testing_test import ( "testing" - "github.com/gaborage/go-bricks/jose" - jositest "github.com/gaborage/go-bricks/jose/testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/jose" + jositest "github.com/gaborage/go-bricks/jose/testing" ) func TestSealOpenRoundtripViaHelpers(t *testing.T) { diff --git a/keystore/keystore_test.go b/keystore/keystore_test.go index 5d491e3c..8e1ea957 100644 --- a/keystore/keystore_test.go +++ b/keystore/keystore_test.go @@ -14,10 +14,11 @@ import ( "strings" "testing" - "github.com/gaborage/go-bricks/config" - "github.com/gaborage/go-bricks/internal/secretfile" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/config" + "github.com/gaborage/go-bricks/internal/secretfile" ) // generateTestKeys creates a fresh RSA key pair for testing. diff --git a/keystore/module_test.go b/keystore/module_test.go index 243682f7..955aec60 100644 --- a/keystore/module_test.go +++ b/keystore/module_test.go @@ -7,11 +7,12 @@ import ( "encoding/base64" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/app" "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/logger" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func newTestDeps(t *testing.T, cfg config.KeyStoreConfig) *app.ModuleDeps { diff --git a/keystore/testing/assertions.go b/keystore/testing/assertions.go index 547551c9..0118a638 100644 --- a/keystore/testing/assertions.go +++ b/keystore/testing/assertions.go @@ -3,9 +3,10 @@ package testing import ( "testing" - "github.com/gaborage/go-bricks/app" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/app" ) // AssertPublicKeyAvailable verifies that a public key with the given name diff --git a/logger/adapter_test.go b/logger/adapter_test.go index 863187ab..d12eb9d9 100644 --- a/logger/adapter_test.go +++ b/logger/adapter_test.go @@ -8,10 +8,11 @@ import ( "testing" "time" - "github.com/gaborage/go-bricks/internal/testutil" "github.com/rs/zerolog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/internal/testutil" ) // createTestLogger creates a logger that outputs to a buffer for testing diff --git a/logger/logger_test.go b/logger/logger_test.go index 08315947..430d1f46 100644 --- a/logger/logger_test.go +++ b/logger/logger_test.go @@ -8,12 +8,13 @@ import ( "testing" "time" - "github.com/gaborage/go-bricks/internal/testutil" "github.com/rs/zerolog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" sdklog "go.opentelemetry.io/otel/sdk/log" "go.opentelemetry.io/otel/trace" + + "github.com/gaborage/go-bricks/internal/testutil" ) const ( diff --git a/messaging/amqp_client.go b/messaging/amqp_client.go index 2d0f8cc7..4f352770 100644 --- a/messaging/amqp_client.go +++ b/messaging/amqp_client.go @@ -9,6 +9,7 @@ import ( "sync" "time" + "github.com/google/uuid" amqp "github.com/rabbitmq/amqp091-go" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" @@ -19,7 +20,6 @@ import ( "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/messaging/internal/tracking" gobrickstrace "github.com/gaborage/go-bricks/trace" - "github.com/google/uuid" ) // Interfaces and dialer are defined in amqp_adapters.go diff --git a/messaging/amqp_client_test.go b/messaging/amqp_client_test.go index 1ffac5d2..797c5f16 100644 --- a/messaging/amqp_client_test.go +++ b/messaging/amqp_client_test.go @@ -8,11 +8,12 @@ import ( "testing" "time" - "github.com/gaborage/go-bricks/logger" - gobrickstrace "github.com/gaborage/go-bricks/trace" amqp "github.com/rabbitmq/amqp091-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/logger" + gobrickstrace "github.com/gaborage/go-bricks/trace" ) const ( @@ -30,6 +31,7 @@ type fakeConnAdapter struct { func (f *fakeConnAdapter) Channel() (*amqp.Channel, error) { return nil, errors.New("adapter does not return *amqp.Channel") } + func (f *fakeConnAdapter) NotifyClose(c chan *amqp.Error) chan *amqp.Error { f.notifyCloseCh = c return c @@ -132,19 +134,23 @@ func (f *fakeChannel) PublishWithContext(_ context.Context, exchange, key string f.mu.Unlock() return err } + func (f *fakeChannel) Consume(_, _ string, _, _, _, _ bool, _ amqp.Table) (<-chan amqp.Delivery, error) { return f.consumeCh, f.consumeErr } + func (f *fakeChannel) QueueDeclare(name string, _, _, _, _ bool, args amqp.Table) (amqp.Queue, error) { f.declaredQueue = name f.gotQueueArgs = args return amqp.Queue{Name: name}, f.qDeclareErr } + func (f *fakeChannel) ExchangeDeclare(name, _ string, _, _, _, _ bool, args amqp.Table) error { f.declaredExchange = name f.gotExchangeArgs = args return f.exDeclareErr } + func (f *fakeChannel) QueueBind(name, key, exchange string, _ bool, args amqp.Table) error { f.boundQueue = struct{ q, ex, rk string }{name, exchange, key} f.gotBindingArgs = args diff --git a/messaging/amqp_test.go b/messaging/amqp_test.go index 6cebf218..cee70e13 100644 --- a/messaging/amqp_test.go +++ b/messaging/amqp_test.go @@ -8,12 +8,13 @@ import ( "testing" "time" - "github.com/gaborage/go-bricks/logger" - gobrickstrace "github.com/gaborage/go-bricks/trace" "github.com/google/uuid" amqp "github.com/rabbitmq/amqp091-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/logger" + gobrickstrace "github.com/gaborage/go-bricks/trace" ) // ============================================================================= @@ -390,6 +391,7 @@ func (e *stubEvent) Msg(msg string) { defer e.l.mu.Unlock() e.l.entries = append(e.l.entries, msg) } + func (e *stubEvent) Msgf(format string, args ...any) { e.l.mu.Lock() defer e.l.mu.Unlock() diff --git a/messaging/otel_test.go b/messaging/otel_test.go index e0cbd710..57bd1665 100644 --- a/messaging/otel_test.go +++ b/messaging/otel_test.go @@ -463,6 +463,7 @@ func (l *testLogger) Fatal() logger.LogEvent { return &testLogEvent{l.t, "FATAL" func (l *testLogger) WithContext(_ any) logger.Logger { return l } + func (l *testLogger) WithFields(_ map[string]any) logger.Logger { return l } diff --git a/messaging/tenant_publisher.go b/messaging/tenant_publisher.go index 107b59e9..91938209 100644 --- a/messaging/tenant_publisher.go +++ b/messaging/tenant_publisher.go @@ -2,7 +2,6 @@ package messaging import ( "context" - "maps" amqp "github.com/rabbitmq/amqp091-go" diff --git a/multitenant/cleanup_test.go b/multitenant/cleanup_test.go index d2008f73..005cee27 100644 --- a/multitenant/cleanup_test.go +++ b/multitenant/cleanup_test.go @@ -6,10 +6,11 @@ import ( "testing" "time" - dbtypes "github.com/gaborage/go-bricks/database/types" - "github.com/gaborage/go-bricks/logger" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + dbtypes "github.com/gaborage/go-bricks/database/types" + "github.com/gaborage/go-bricks/logger" ) // stubDB is a non-nil dbtypes.Interface whose methods are never called by diff --git a/observability/noop.go b/observability/noop.go index f6f88493..63519cb8 100644 --- a/observability/noop.go +++ b/observability/noop.go @@ -4,7 +4,7 @@ import ( "context" "go.opentelemetry.io/otel/metric" - metricznoop "go.opentelemetry.io/otel/metric/noop" + metricnoop "go.opentelemetry.io/otel/metric/noop" sdklog "go.opentelemetry.io/otel/sdk/log" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace/noop" @@ -22,7 +22,7 @@ type noopProvider struct { func newNoopProvider() *noopProvider { return &noopProvider{ tracerProvider: noop.NewTracerProvider(), - meterProvider: metricznoop.NewMeterProvider(), + meterProvider: metricnoop.NewMeterProvider(), } } diff --git a/observability/provider.go b/observability/provider.go index 99167d63..0c78b7cf 100644 --- a/observability/provider.go +++ b/observability/provider.go @@ -16,8 +16,9 @@ import ( "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/metric" - metricznoop "go.opentelemetry.io/otel/metric/noop" + metricnoop "go.opentelemetry.io/otel/metric/noop" "go.opentelemetry.io/otel/propagation" + sdklog "go.opentelemetry.io/otel/sdk/log" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" @@ -25,8 +26,6 @@ import ( "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace/noop" "google.golang.org/grpc/credentials/insecure" - - sdklog "go.opentelemetry.io/otel/sdk/log" ) // debugLogger is a simple logger for observability debugging. @@ -505,7 +504,7 @@ func (p *provider) TracerProvider() trace.TracerProvider { // MeterProvider returns the configured meter provider. func (p *provider) MeterProvider() metric.MeterProvider { if p.meterProvider == nil { - return metricznoop.NewMeterProvider() + return metricnoop.NewMeterProvider() } return p.meterProvider } diff --git a/observability/shutdown_test.go b/observability/shutdown_test.go index 8014b8f5..a0a795b9 100644 --- a/observability/shutdown_test.go +++ b/observability/shutdown_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "go.opentelemetry.io/otel/metric" - metricznoop "go.opentelemetry.io/otel/metric/noop" + metricnoop "go.opentelemetry.io/otel/metric/noop" sdklog "go.opentelemetry.io/otel/sdk/log" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace/noop" @@ -26,7 +26,7 @@ func (m *mockProvider) TracerProvider() trace.TracerProvider { } func (m *mockProvider) MeterProvider() metric.MeterProvider { - return metricznoop.NewMeterProvider() + return metricnoop.NewMeterProvider() } func (m *mockProvider) LoggerProvider() *sdklog.LoggerProvider { diff --git a/outbox/config_test.go b/outbox/config_test.go index fb6fbed4..6f942c50 100644 --- a/outbox/config_test.go +++ b/outbox/config_test.go @@ -4,8 +4,9 @@ import ( "testing" "time" - "github.com/gaborage/go-bricks/config" "github.com/stretchr/testify/assert" + + "github.com/gaborage/go-bricks/config" ) func TestApplyDefaultsAllZero(t *testing.T) { diff --git a/outbox/module_test.go b/outbox/module_test.go index b85b4862..16a4172f 100644 --- a/outbox/module_test.go +++ b/outbox/module_test.go @@ -6,6 +6,9 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/app" "github.com/gaborage/go-bricks/config" dbtesting "github.com/gaborage/go-bricks/database/testing" @@ -13,8 +16,6 @@ import ( "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/messaging" "github.com/gaborage/go-bricks/multitenant" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // fakeRegistrar captures FixedRate / DailyAt registrations and returns @@ -595,6 +596,7 @@ func TestModuleInitFailsFastForEmptyStaticMultitenant(t *testing.T) { // tenancy logic, so it must be satisfied via SetSharedResolvers even when the // test targets a later guard. func stubSharedDB(_ context.Context) (dbtypes.Interface, error) { return nil, nil } + func stubSharedMsg(_ context.Context) (messaging.AMQPClient, error) { return nil, nil } diff --git a/outbox/publisher.go b/outbox/publisher.go index e99f7aaa..3b8b33cf 100644 --- a/outbox/publisher.go +++ b/outbox/publisher.go @@ -8,10 +8,11 @@ import ( "maps" "time" + "github.com/google/uuid" + "github.com/gaborage/go-bricks/app" dbtypes "github.com/gaborage/go-bricks/database/types" gobrickstrace "github.com/gaborage/go-bricks/trace" - "github.com/google/uuid" ) // outboxPublisher implements app.OutboxPublisher by writing events to the outbox table diff --git a/outbox/publisher_test.go b/outbox/publisher_test.go index cd8d0da0..68e9cf26 100644 --- a/outbox/publisher_test.go +++ b/outbox/publisher_test.go @@ -8,13 +8,14 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/app" "github.com/gaborage/go-bricks/config" dbtesting "github.com/gaborage/go-bricks/database/testing" dbtypes "github.com/gaborage/go-bricks/database/types" gobrickstrace "github.com/gaborage/go-bricks/trace" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) const ( @@ -41,15 +42,19 @@ func (s *mockStore) Insert(_ context.Context, _ dbtypes.Tx, record *Record) erro func (s *mockStore) FetchPending(_ context.Context, _ dbtypes.Interface, _ int) ([]Record, error) { return nil, nil } + func (s *mockStore) MarkPublished(_ context.Context, _ dbtypes.Interface, _ string) error { return nil } + func (s *mockStore) MarkFailed(_ context.Context, _ dbtypes.Interface, _, _ string) error { return nil } + func (s *mockStore) MarkDeadLettered(_ context.Context, _ dbtypes.Interface, _, _ string) error { return nil } + func (s *mockStore) DeletePublished(_ context.Context, _ dbtypes.Interface, _ time.Time) (int64, error) { return 0, nil } diff --git a/outbox/store_oracle_test.go b/outbox/store_oracle_test.go index faea96c7..9242a002 100644 --- a/outbox/store_oracle_test.go +++ b/outbox/store_oracle_test.go @@ -5,10 +5,11 @@ import ( "testing" "time" - dbtesting "github.com/gaborage/go-bricks/database/testing" - dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + dbtesting "github.com/gaborage/go-bricks/database/testing" + dbtypes "github.com/gaborage/go-bricks/database/types" ) const oracleTestTable = "GOBRICKS_OUTBOX" diff --git a/outbox/store_postgres_test.go b/outbox/store_postgres_test.go index 2da0485c..ae1ef046 100644 --- a/outbox/store_postgres_test.go +++ b/outbox/store_postgres_test.go @@ -5,10 +5,11 @@ import ( "testing" "time" - dbtesting "github.com/gaborage/go-bricks/database/testing" - dbtypes "github.com/gaborage/go-bricks/database/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + dbtesting "github.com/gaborage/go-bricks/database/testing" + dbtypes "github.com/gaborage/go-bricks/database/types" ) const pgTestTable = "gobricks_outbox" diff --git a/outbox/test_helpers_test.go b/outbox/test_helpers_test.go index 1edd7f87..f9ef9e77 100644 --- a/outbox/test_helpers_test.go +++ b/outbox/test_helpers_test.go @@ -5,7 +5,7 @@ import ( "sync" "time" - amqp091 "github.com/rabbitmq/amqp091-go" + amqp "github.com/rabbitmq/amqp091-go" "github.com/gaborage/go-bricks/config" dbtypes "github.com/gaborage/go-bricks/database/types" @@ -214,11 +214,11 @@ func (f *fakeAMQP) PublishToExchange(ctx context.Context, opts messaging.Publish return err } -func (f *fakeAMQP) Consume(_ context.Context, _ string) (<-chan amqp091.Delivery, error) { +func (f *fakeAMQP) Consume(_ context.Context, _ string) (<-chan amqp.Delivery, error) { return nil, nil } -func (f *fakeAMQP) ConsumeFromQueue(_ context.Context, _ messaging.ConsumeOptions) (<-chan amqp091.Delivery, error) { +func (f *fakeAMQP) ConsumeFromQueue(_ context.Context, _ messaging.ConsumeOptions) (<-chan amqp.Delivery, error) { return nil, nil } diff --git a/outbox/testing/mock_outbox_test.go b/outbox/testing/mock_outbox_test.go index 1c66ee7b..3233dd2a 100644 --- a/outbox/testing/mock_outbox_test.go +++ b/outbox/testing/mock_outbox_test.go @@ -7,9 +7,10 @@ import ( "strconv" "testing" - "github.com/gaborage/go-bricks/app" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/app" ) func TestMockOutboxPublishRecordsEvent(t *testing.T) { diff --git a/scheduler/api_handlers_test.go b/scheduler/api_handlers_test.go index 1c60faa9..bc5571bc 100644 --- a/scheduler/api_handlers_test.go +++ b/scheduler/api_handlers_test.go @@ -5,10 +5,11 @@ import ( "testing" "time" - "github.com/gaborage/go-bricks/config" - "github.com/gaborage/go-bricks/server" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/gaborage/go-bricks/config" + "github.com/gaborage/go-bricks/server" ) const ( diff --git a/scheduler/cidr_middleware_test.go b/scheduler/cidr_middleware_test.go index 17c7e802..98f651e3 100644 --- a/scheduler/cidr_middleware_test.go +++ b/scheduler/cidr_middleware_test.go @@ -8,11 +8,12 @@ import ( "os" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/server" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) const ( diff --git a/scheduler/job_test.go b/scheduler/job_test.go index 4bf99030..b67a2383 100644 --- a/scheduler/job_test.go +++ b/scheduler/job_test.go @@ -5,11 +5,12 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database/types" "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/messaging" - "github.com/stretchr/testify/assert" ) // TestJobInterface verifies that Executor interface can be implemented diff --git a/scheduler/module.go b/scheduler/module.go index b9b548dc..6ee934cf 100644 --- a/scheduler/module.go +++ b/scheduler/module.go @@ -7,6 +7,12 @@ import ( "sync" "time" + "github.com/go-co-op/gocron/v2" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/trace" + "github.com/gaborage/go-bricks/app" "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database/types" @@ -15,11 +21,6 @@ import ( "github.com/gaborage/go-bricks/messaging" "github.com/gaborage/go-bricks/multitenant" "github.com/gaborage/go-bricks/server" - "github.com/go-co-op/gocron/v2" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/trace" ) // OpenTelemetry attribute names for job scheduler observability. diff --git a/scheduler/module_test.go b/scheduler/module_test.go index 731192c7..fc1db4a0 100644 --- a/scheduler/module_test.go +++ b/scheduler/module_test.go @@ -8,14 +8,15 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/trace" + "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database/types" "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/messaging" obtest "github.com/gaborage/go-bricks/observability/testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/trace" ) // TestSchedulerModuleName verifies the module name diff --git a/scheduler/test_helpers_test.go b/scheduler/test_helpers_test.go index b530ef4c..133bbc55 100644 --- a/scheduler/test_helpers_test.go +++ b/scheduler/test_helpers_test.go @@ -5,14 +5,15 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/trace" + "github.com/gaborage/go-bricks/app" "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/database/types" "github.com/gaborage/go-bricks/logger" "github.com/gaborage/go-bricks/messaging" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/trace" ) // assertWaitGroupDrains fails if module m's in-flight WaitGroup does not reach diff --git a/server/handler.go b/server/handler.go index 0eb20c3c..18ceb368 100644 --- a/server/handler.go +++ b/server/handler.go @@ -15,7 +15,6 @@ import ( "github.com/google/uuid" "github.com/labstack/echo/v5" - "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/trace" @@ -566,18 +565,21 @@ func (j *joseRouteConfig) inbound() *jose.Policy { } return j.Inbound } + func (j *joseRouteConfig) outbound() *jose.Policy { if j == nil { return nil } return j.Outbound } + func (j *joseRouteConfig) resolver() jose.KeyResolver { if j == nil { return nil } return j.Resolver } + func (j *joseRouteConfig) obs() *joseObservability { if j == nil { return nil diff --git a/server/jose.go b/server/jose.go index 2aed62c8..91126ee5 100644 --- a/server/jose.go +++ b/server/jose.go @@ -9,17 +9,17 @@ import ( "net/http" "time" + "github.com/labstack/echo/v5" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/metric" - otelnoop "go.opentelemetry.io/otel/metric/noop" + metricnoop "go.opentelemetry.io/otel/metric/noop" "go.opentelemetry.io/otel/trace" tracenoop "go.opentelemetry.io/otel/trace/noop" "github.com/gaborage/go-bricks/config" "github.com/gaborage/go-bricks/jose" "github.com/gaborage/go-bricks/logger" - "github.com/labstack/echo/v5" ) // maxJOSERequestBytes caps the inbound JOSE body read. It mirrors the value of @@ -119,7 +119,7 @@ func (o *joseObservability) recordDuration(ctx context.Context, operation string func newJOSEObservability(log logger.Logger, tracer trace.Tracer, mp metric.MeterProvider) *joseObservability { o := &joseObservability{logger: log, tracer: tracer} if mp == nil { - mp = otelnoop.NewMeterProvider() + mp = metricnoop.NewMeterProvider() } meter := mp.Meter("github.com/gaborage/go-bricks/jose") if c, err := meter.Int64Counter("jose.failures.total", diff --git a/server/jose_options_test.go b/server/jose_options_test.go index 33cad24c..25237a06 100644 --- a/server/jose_options_test.go +++ b/server/jose_options_test.go @@ -9,7 +9,7 @@ import ( "github.com/labstack/echo/v5" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - otelnoop "go.opentelemetry.io/otel/metric/noop" + metricnoop "go.opentelemetry.io/otel/metric/noop" tracenoop "go.opentelemetry.io/otel/trace/noop" "github.com/gaborage/go-bricks/config" @@ -31,7 +31,7 @@ func TestWithJOSETracerSetsField(t *testing.T) { } func TestWithJOSEMeterProviderSetsField(t *testing.T) { - mp := otelnoop.NewMeterProvider() + mp := metricnoop.NewMeterProvider() hr := NewHandlerRegistry(&config.Config{App: config.AppConfig{Env: "development"}}, WithJOSEMeterProvider(mp)) assert.NotNil(t, hr.joseMeterProvider) } diff --git a/server/logger_test.go b/server/logger_test.go index b40843fe..6be8af3f 100644 --- a/server/logger_test.go +++ b/server/logger_test.go @@ -60,15 +60,19 @@ func (r *recLogger) noop() logger.LogEvent { func (r *recLogger) Info() logger.LogEvent { return r.noop() } + func (r *recLogger) Error() logger.LogEvent { return r.noop() } + func (r *recLogger) Debug() logger.LogEvent { return r.noop() } + func (r *recLogger) Warn() logger.LogEvent { return r.noop() } + func (r *recLogger) Fatal() logger.LogEvent { return r.noop() } @@ -78,6 +82,7 @@ func (r *recLogger) WithFields(_ map[string]any) logger.Logger { return r } func (e *recEvent) Msg(msg string) { e.message = msg } + func (e *recEvent) Msgf(_ string, _ ...any) { // No-op (not used in tests) } diff --git a/server/request_enrich.go b/server/request_enrich.go index b2a38c6e..4859aef4 100644 --- a/server/request_enrich.go +++ b/server/request_enrich.go @@ -1,9 +1,10 @@ package server import ( + "github.com/labstack/echo/v5" + "github.com/gaborage/go-bricks/internal/leasescope" "github.com/gaborage/go-bricks/logger" - "github.com/labstack/echo/v5" ) // RequestEnrich combines the two adjacent pure-value request enrichers — diff --git a/server/server_test.go b/server/server_test.go index 7d2fba7a..bfddf5ee 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -67,6 +67,7 @@ func (l *testLogger) Fatal() logger.LogEvent { return &testLogEvent{logger: l, l func (l *testLogger) WithContext(any) logger.Logger { return l } + func (l *testLogger) WithFields(map[string]any) logger.Logger { return l } @@ -92,6 +93,7 @@ func (e *testLogEvent) Err(error) logger.LogEvent { e.fields = append(e.fields, "error") return e } + func (e *testLogEvent) Str(key, value string) logger.LogEvent { e.fields = append(e.fields, key) if e.logger.filter != nil { @@ -103,30 +105,37 @@ func (e *testLogEvent) Str(key, value string) logger.LogEvent { e.values[key] = value return e } + func (e *testLogEvent) Int(key string, _ int) logger.LogEvent { e.fields = append(e.fields, key) return e } + func (e *testLogEvent) Int64(key string, _ int64) logger.LogEvent { e.fields = append(e.fields, key) return e } + func (e *testLogEvent) Uint64(key string, _ uint64) logger.LogEvent { e.fields = append(e.fields, key) return e } + func (e *testLogEvent) Dur(key string, _ time.Duration) logger.LogEvent { e.fields = append(e.fields, key) return e } + func (e *testLogEvent) Interface(key string, _ any) logger.LogEvent { e.fields = append(e.fields, key) return e } + func (e *testLogEvent) Bytes(key string, _ []byte) logger.LogEvent { e.fields = append(e.fields, key) return e } + func (e *testLogEvent) Bool(key string, _ bool) logger.LogEvent { e.fields = append(e.fields, key) return e diff --git a/server/timeout_test.go b/server/timeout_test.go index 4bf4b91b..53c33b70 100644 --- a/server/timeout_test.go +++ b/server/timeout_test.go @@ -430,6 +430,7 @@ func (n *noopLogger) WithFields(_ map[string]any) logger.Logger { return n } func (e *noopLogEvent) Msg(_ string) { // No-op } + func (e *noopLogEvent) Msgf(_ string, _ ...any) { // No-op } diff --git a/server/trace_context.go b/server/trace_context.go index 85f92719..f07ebaa3 100644 --- a/server/trace_context.go +++ b/server/trace_context.go @@ -3,8 +3,9 @@ package server import ( "context" - gobrickshttp "github.com/gaborage/go-bricks/httpclient" "github.com/labstack/echo/v5" + + gobrickshttp "github.com/gaborage/go-bricks/httpclient" ) // enrichTraceContext returns the request's context with the resolved trace ID and diff --git a/testing/mocks/query_builder.go b/testing/mocks/query_builder.go index c88092d1..dc24a628 100644 --- a/testing/mocks/query_builder.go +++ b/testing/mocks/query_builder.go @@ -301,5 +301,7 @@ func (m *MockQueryBuilder) Where(filter types.Filter) types.SelectQueryBuilder { } // Compile-time verification that MockQueryBuilder implements the interface -var _ types.QueryBuilderInterface = (*MockQueryBuilder)(nil) -var _ types.SelectQueryBuilder = (*MockQueryBuilder)(nil) +var ( + _ types.QueryBuilderInterface = (*MockQueryBuilder)(nil) + _ types.SelectQueryBuilder = (*MockQueryBuilder)(nil) +) diff --git a/tools/migration/Makefile b/tools/migration/Makefile index c686dac3..f324d18c 100644 --- a/tools/migration/Makefile +++ b/tools/migration/Makefile @@ -33,8 +33,12 @@ test-coverage: ## Run tests with coverage lint: ## Run golangci-lint (pinned; identical to CI) go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) run -fmt: ## Format Go code - go fmt ./... +# Mirrors the root Makefile: golangci-lint resolves ../../.golangci.yml from +# here, so this module is held to the same formatters block (gofumpt + gci) and +# `go fmt` cannot fix those findings. See the root Makefile's `fmt` for the full +# rationale. +fmt: ## Format Go code (gofmt + gofumpt + gci, per the repo-root .golangci.yml) + go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) fmt update: ## Update dependencies to latest versions go get -u ./... diff --git a/tools/migration/internal/commands/builders_test.go b/tools/migration/internal/commands/builders_test.go index 66eb3e63..4f9196f3 100644 --- a/tools/migration/internal/commands/builders_test.go +++ b/tools/migration/internal/commands/builders_test.go @@ -182,5 +182,7 @@ func TestBuildConfigProviderAWSReturnsSecretsProvider(t *testing.T) { } // Compile-time guard that helps reviewers see the type even without running tests. -var _ = []*migration.SecretsProvider{nil} -var _ = (*config.TenantStore)(nil) +var ( + _ = []*migration.SecretsProvider{nil} + _ = (*config.TenantStore)(nil) +) diff --git a/tools/migration/internal/commands/quiesce_test.go b/tools/migration/internal/commands/quiesce_test.go index e543ce1a..35109bbc 100644 --- a/tools/migration/internal/commands/quiesce_test.go +++ b/tools/migration/internal/commands/quiesce_test.go @@ -213,9 +213,11 @@ func (e erroringController) IsSet(context.Context) (bool, error) { return false, func (e erroringController) Query(context.Context) (*migration.QuiesceStatus, error) { return nil, e.err } + func (e erroringController) Set(context.Context, migration.QuiesceSetOptions) (*migration.QuiesceStatus, error) { return nil, e.err } + func (e erroringController) Clear(context.Context, string) (*migration.QuiesceStatus, error) { return nil, e.err } diff --git a/trace/trace_test.go b/trace/trace_test.go index f6260333..997bf3cc 100644 --- a/trace/trace_test.go +++ b/trace/trace_test.go @@ -79,6 +79,7 @@ func (a *mapAccessor) Get(key string) any { } return a.m[key] } + func (a *mapAccessor) Set(key string, value any) { if a.m == nil { a.m = map[string]any{}