diff --git a/.golangci.yaml b/.golangci.yaml index cb00402f..c1237245 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -21,29 +21,33 @@ linters-settings: revive: rules: - name: unused-parameter - severity: warning - disabled: true + arguments: + - allowRegex: "^_" linters: enable-all: true disable: - - cyclop # The linter can detect complicated code, but it never leads to actual code changes - deadcode # deprecated - - depguard # This is useless. I already carefully documented all non-Google libraries - exhaustivestruct # deprecated; replaced by exhaustruct - - gocognit # The linter can detect complicated code, but it never lead to actual code changes - golint # deprecated; replaced by revive - - gosmopolitan # The idea is interesting but is useless for this project - ifshort # deprecated - interfacer # deprecated - - ireturn # ireturn works poorly for the style with private types and public interfaces - - maintidx # The linter can detect complicated code, but it never lead to actual code changes - maligned # deprecated, and I value readability over bytes saved by alignment - - nlreturn # I don't agree with the style enforced by nlreturn - - nonamedreturns # named returns are needed in the internal updater package - - nosnakecase # revive's var-naming check seems to be better + - nosnakecase # deprecated; revive's var-naming check seems to be better - scopelint # deprecated; replaced by exportloopref - structcheck # deprecated - varcheck # deprecated - - varnamelen # varnamelen complains too much, in my opinion + + - cyclop # can detect complicated code, but never leads to actual code changes + - gocognit # can detect complicated code, but never leads to actual code changes + - maintidx # can detect complicated code, but never leads to actual code changes + + - depguard # useless; I do not introduce a dependency carelessly + - gosmopolitan # interesting for i18n checking, useless for this project + + - nlreturn # I don't agree with the style enforced by nlreturn + - varnamelen # I don't agree with the style enforced by varnamelen - wsl # I don't agree with the style enforced by wsl + + - ireturn # doesn't work for private struct types; see https://github.com/butuzov/ireturn/issues/31 + - nonamedreturns # named returns are needed in the internal updater package diff --git a/internal/config/config_print_test.go b/internal/config/config_print_test.go index f93d5146..a8739966 100644 --- a/internal/config/config_print_test.go +++ b/internal/config/config_print_test.go @@ -48,6 +48,10 @@ func Some(xs ...any) gomock.Matcher { return someMatcher{ms} } +func printItem(ppfmt *mocks.MockPP, key string, value any) *mocks.PPInfofCall { + return ppfmt.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, key, value) +} + //nolint:paralleltest // changing the environment variable TZ func TestPrintDefault(t *testing.T) { mockCtrl := gomock.NewController(t) @@ -62,21 +66,21 @@ func TestPrintDefault(t *testing.T) { mockPP.EXPECT().IncIndent().Return(mockPP), mockPP.EXPECT().IncIndent().Return(innerMockPP), mockPP.EXPECT().Infof(pp.EmojiConfig, "Domains and IP providers:"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "IPv4 domains:", "(none)"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "IPv4 provider:", "cloudflare.trace"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "IPv6 domains:", "(none)"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "IPv6 provider:", "cloudflare.trace"), + printItem(innerMockPP, "IPv4 domains:", "(none)"), + printItem(innerMockPP, "IPv4 provider:", "cloudflare.trace"), + printItem(innerMockPP, "IPv6 domains:", "(none)"), + printItem(innerMockPP, "IPv6 provider:", "cloudflare.trace"), mockPP.EXPECT().Infof(pp.EmojiConfig, "Scheduling:"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Timezone:", Some("UTC (UTC+00 now)", "Local (UTC+00 now)")), //nolint:lll - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Update frequency:", "@every 5m"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Update on start?", "true"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Delete on stop?", "false"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Cache expiration:", "6h0m0s"), + printItem(innerMockPP, "Timezone:", Some("UTC (UTC+00 now)", "Local (UTC+00 now)")), + printItem(innerMockPP, "Update frequency:", "@every 5m"), + printItem(innerMockPP, "Update on start?", "true"), + printItem(innerMockPP, "Delete on stop?", "false"), + printItem(innerMockPP, "Cache expiration:", "6h0m0s"), mockPP.EXPECT().Infof(pp.EmojiConfig, "New DNS records:"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "TTL:", "1 (auto)"), + printItem(innerMockPP, "TTL:", "1 (auto)"), mockPP.EXPECT().Infof(pp.EmojiConfig, "Timeouts:"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "IP detection:", "5s"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Record updating:", "30s"), + printItem(innerMockPP, "IP detection:", "5s"), + printItem(innerMockPP, "Record updating:", "30s"), ) config.Default().Print(mockPP) } @@ -95,25 +99,25 @@ func TestPrintMaps(t *testing.T) { mockPP.EXPECT().IncIndent().Return(mockPP), mockPP.EXPECT().IncIndent().Return(innerMockPP), mockPP.EXPECT().Infof(pp.EmojiConfig, "Domains and IP providers:"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "IPv4 domains:", "test4.org, *.test4.org"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "IPv4 provider:", "cloudflare.trace"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "IPv6 domains:", "test6.org, *.test6.org"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "IPv6 provider:", "cloudflare.trace"), + printItem(innerMockPP, "IPv4 domains:", "test4.org, *.test4.org"), + printItem(innerMockPP, "IPv4 provider:", "cloudflare.trace"), + printItem(innerMockPP, "IPv6 domains:", "test6.org, *.test6.org"), + printItem(innerMockPP, "IPv6 provider:", "cloudflare.trace"), mockPP.EXPECT().Infof(pp.EmojiConfig, "Scheduling:"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Timezone:", Some("UTC (UTC+00 now)", "Local (UTC+00 now)")), //nolint:lll - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Update frequency:", "@every 5m"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Update on start?", "true"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Delete on stop?", "false"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Cache expiration:", "6h0m0s"), + printItem(innerMockPP, "Timezone:", Some("UTC (UTC+00 now)", "Local (UTC+00 now)")), + printItem(innerMockPP, "Update frequency:", "@every 5m"), + printItem(innerMockPP, "Update on start?", "true"), + printItem(innerMockPP, "Delete on stop?", "false"), + printItem(innerMockPP, "Cache expiration:", "6h0m0s"), mockPP.EXPECT().Infof(pp.EmojiConfig, "New DNS records:"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "TTL:", "30000"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Proxied domains:", "a, b"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Unproxied domains:", "c, d"), + printItem(innerMockPP, "TTL:", "30000"), + printItem(innerMockPP, "Proxied domains:", "a, b"), + printItem(innerMockPP, "Unproxied domains:", "c, d"), mockPP.EXPECT().Infof(pp.EmojiConfig, "Timeouts:"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "IP detection:", "5s"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Record updating:", "30s"), + printItem(innerMockPP, "IP detection:", "5s"), + printItem(innerMockPP, "Record updating:", "30s"), mockPP.EXPECT().Infof(pp.EmojiConfig, "Monitors:"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Healthchecks:", "(URL redacted)"), + printItem(innerMockPP, "Healthchecks:", "(URL redacted)"), ) c := config.Default() @@ -151,16 +155,16 @@ func TestPrintEmpty(t *testing.T) { mockPP.EXPECT().IncIndent().Return(innerMockPP), mockPP.EXPECT().Infof(pp.EmojiConfig, "Domains and IP providers:"), mockPP.EXPECT().Infof(pp.EmojiConfig, "Scheduling:"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Timezone:", Some("UTC (UTC+00 now)", "Local (UTC+00 now)")), //nolint:lll - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Update frequency:", "@once"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Update on start?", "false"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Delete on stop?", "false"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Cache expiration:", "0s"), + printItem(innerMockPP, "Timezone:", Some("UTC (UTC+00 now)", "Local (UTC+00 now)")), + printItem(innerMockPP, "Update frequency:", "@once"), + printItem(innerMockPP, "Update on start?", "false"), + printItem(innerMockPP, "Delete on stop?", "false"), + printItem(innerMockPP, "Cache expiration:", "0s"), mockPP.EXPECT().Infof(pp.EmojiConfig, "New DNS records:"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "TTL:", "0"), + printItem(innerMockPP, "TTL:", "0"), mockPP.EXPECT().Infof(pp.EmojiConfig, "Timeouts:"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "IP detection:", "0s"), - innerMockPP.EXPECT().Infof(pp.EmojiBullet, "%-*s %s", 24, "Record updating:", "0s"), + printItem(innerMockPP, "IP detection:", "0s"), + printItem(innerMockPP, "Record updating:", "0s"), ) var cfg config.Config cfg.Print(mockPP) diff --git a/internal/monitor/uptimekuma_test.go b/internal/monitor/uptimekuma_test.go index 9d64aa08..e88b186a 100644 --- a/internal/monitor/uptimekuma_test.go +++ b/internal/monitor/uptimekuma_test.go @@ -16,6 +16,8 @@ import ( "github.com/favonia/cloudflare-ddns/internal/pp" ) +const httpUnsafeMsg string = "The Uptime Kuma URL (redacted) uses HTTP; please consider using HTTPS" + func TestNewUptimeKuma(t *testing.T) { t.Parallel() @@ -97,6 +99,13 @@ func TestUptimeKumaEndPoints(t *testing.T) { ActionFail ) + successPP := func(m *mocks.MockPP) { + gomock.InOrder( + m.EXPECT().Warningf(pp.EmojiUserWarning, httpUnsafeMsg), + m.EXPECT().Infof(pp.EmojiNotification, "Successfully pinged Uptime Kuma"), + ) + } + for name, tc := range map[string]struct { endpoint func(pp.PP, monitor.Monitor) bool url string @@ -117,12 +126,7 @@ func TestUptimeKumaEndPoints(t *testing.T) { []action{ActionOk}, ActionAbort, true, true, - func(m *mocks.MockPP) { - gomock.InOrder( - m.EXPECT().Warningf(pp.EmojiUserWarning, "The Uptime Kuma URL (redacted) uses HTTP; please consider using HTTPS"), - m.EXPECT().Infof(pp.EmojiNotification, "Successfully pinged Uptime Kuma"), - ) - }, + successPP, }, "success/not-ok": { func(ppfmt pp.PP, m monitor.Monitor) bool { @@ -134,7 +138,7 @@ func TestUptimeKumaEndPoints(t *testing.T) { false, func(m *mocks.MockPP) { gomock.InOrder( - m.EXPECT().Warningf(pp.EmojiUserWarning, "The Uptime Kuma URL (redacted) uses HTTP; please consider using HTTPS"), + m.EXPECT().Warningf(pp.EmojiUserWarning, httpUnsafeMsg), m.EXPECT().Warningf(pp.EmojiError, "Failed to ping Uptime Kuma: %q", "bad"), ) }, @@ -149,7 +153,7 @@ func TestUptimeKumaEndPoints(t *testing.T) { false, func(m *mocks.MockPP) { gomock.InOrder( - m.EXPECT().Warningf(pp.EmojiUserWarning, "The Uptime Kuma URL (redacted) uses HTTP; please consider using HTTPS"), + m.EXPECT().Warningf(pp.EmojiUserWarning, httpUnsafeMsg), m.EXPECT().Warningf(pp.EmojiError, "Failed to parse the response from Uptime Kuma: %v", gomock.Any()), ) }, @@ -163,7 +167,7 @@ func TestUptimeKumaEndPoints(t *testing.T) { false, func(m *mocks.MockPP) { gomock.InOrder( - m.EXPECT().Warningf(pp.EmojiUserWarning, "The Uptime Kuma URL (redacted) uses HTTP; please consider using HTTPS"), + m.EXPECT().Warningf(pp.EmojiUserWarning, httpUnsafeMsg), m.EXPECT().Warningf(pp.EmojiError, "Failed to send HTTP(S) request to Uptime Kuma: %v", gomock.Any()), ) }, @@ -177,7 +181,7 @@ func TestUptimeKumaEndPoints(t *testing.T) { ActionAbort, false, true, func(m *mocks.MockPP) { - m.EXPECT().Warningf(pp.EmojiUserWarning, "The Uptime Kuma URL (redacted) uses HTTP; please consider using HTTPS") + m.EXPECT().Warningf(pp.EmojiUserWarning, httpUnsafeMsg) }, }, "failure": { @@ -188,12 +192,7 @@ func TestUptimeKumaEndPoints(t *testing.T) { []action{ActionOk}, ActionAbort, true, true, - func(m *mocks.MockPP) { - gomock.InOrder( - m.EXPECT().Warningf(pp.EmojiUserWarning, "The Uptime Kuma URL (redacted) uses HTTP; please consider using HTTPS"), - m.EXPECT().Infof(pp.EmojiNotification, "Successfully pinged Uptime Kuma"), - ) - }, + successPP, }, "failure/empty": { func(ppfmt pp.PP, m monitor.Monitor) bool { @@ -203,12 +202,7 @@ func TestUptimeKumaEndPoints(t *testing.T) { []action{ActionOk}, ActionAbort, true, true, - func(m *mocks.MockPP) { - gomock.InOrder( - m.EXPECT().Warningf(pp.EmojiUserWarning, "The Uptime Kuma URL (redacted) uses HTTP; please consider using HTTPS"), - m.EXPECT().Infof(pp.EmojiNotification, "Successfully pinged Uptime Kuma"), - ) - }, + successPP, }, "log": { func(ppfmt pp.PP, m monitor.Monitor) bool { @@ -219,7 +213,7 @@ func TestUptimeKumaEndPoints(t *testing.T) { ActionAbort, false, true, func(m *mocks.MockPP) { - m.EXPECT().Warningf(pp.EmojiUserWarning, "The Uptime Kuma URL (redacted) uses HTTP; please consider using HTTPS") + m.EXPECT().Warningf(pp.EmojiUserWarning, httpUnsafeMsg) }, }, "exitstatus/0": { @@ -231,7 +225,7 @@ func TestUptimeKumaEndPoints(t *testing.T) { ActionAbort, false, true, func(m *mocks.MockPP) { - m.EXPECT().Warningf(pp.EmojiUserWarning, "The Uptime Kuma URL (redacted) uses HTTP; please consider using HTTPS") + m.EXPECT().Warningf(pp.EmojiUserWarning, httpUnsafeMsg) }, }, "exitstatus/1": { @@ -242,12 +236,7 @@ func TestUptimeKumaEndPoints(t *testing.T) { []action{ActionOk}, ActionAbort, true, true, - func(m *mocks.MockPP) { - gomock.InOrder( - m.EXPECT().Warningf(pp.EmojiUserWarning, "The Uptime Kuma URL (redacted) uses HTTP; please consider using HTTPS"), - m.EXPECT().Infof(pp.EmojiNotification, "Successfully pinged Uptime Kuma"), - ) - }, + successPP, }, "exitstatus/-1": { func(ppfmt pp.PP, m monitor.Monitor) bool { @@ -257,12 +246,7 @@ func TestUptimeKumaEndPoints(t *testing.T) { []action{ActionOk}, ActionAbort, true, true, - func(m *mocks.MockPP) { - gomock.InOrder( - m.EXPECT().Warningf(pp.EmojiUserWarning, "The Uptime Kuma URL (redacted) uses HTTP; please consider using HTTPS"), - m.EXPECT().Infof(pp.EmojiNotification, "Successfully pinged Uptime Kuma"), - ) - }, + successPP, }, } { tc := tc