From 83525f3424f02cc1465d287bf4ee5896c03acfef Mon Sep 17 00:00:00 2001 From: Aaron Gable Date: Wed, 22 Apr 2026 18:31:57 -0700 Subject: [PATCH 1/2] Update go.mod to go1.26 Also update tests that now fail due to updated runtime. --- go.mod | 2 +- .../resolver/dns/dns_resolver_test.go | 63 +++++++++---------- observer/probers/http/http_conf.go | 5 +- wfe2/wfe_test.go | 2 +- 4 files changed, 35 insertions(+), 37 deletions(-) diff --git a/go.mod b/go.mod index 1d5bfca1635..3da16a1833a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/letsencrypt/boulder -go 1.25.0 +go 1.26.0 require ( github.com/aws/aws-sdk-go-v2 v1.41.5 diff --git a/grpc/internal/resolver/dns/dns_resolver_test.go b/grpc/internal/resolver/dns/dns_resolver_test.go index 51cb2ddffac..5ecf2d62edd 100644 --- a/grpc/internal/resolver/dns/dns_resolver_test.go +++ b/grpc/internal/resolver/dns/dns_resolver_test.go @@ -527,11 +527,6 @@ func TestCustomAuthority(t *testing.T) { "4.3.2.1:" + defaultDNSSvrPort, false, }, - { - "::1", - "[::1]:" + defaultDNSSvrPort, - false, - }, { "[::1]", "[::1]:" + defaultDNSSvrPort, @@ -574,40 +569,42 @@ func TestCustomAuthority(t *testing.T) { }() for _, a := range tests { - errChan := make(chan error, 1) - customAuthorityDialer = func(authority string) func(ctx context.Context, network, address string) (net.Conn, error) { - if authority != a.authorityWant { - errChan <- fmt.Errorf("wrong custom authority passed to resolver. input: %s expected: %s actual: %s", a.authority, a.authorityWant, authority) - } else { - errChan <- nil - } - return func(ctx context.Context, network, address string) (net.Conn, error) { - return nil, errors.New("no need to dial") + t.Run(a.authority, func(t *testing.T) { + errChan := make(chan error, 1) + customAuthorityDialer = func(authority string) func(ctx context.Context, network, address string) (net.Conn, error) { + if authority != a.authorityWant { + errChan <- fmt.Errorf("wrong custom authority passed to resolver. input: %s expected: %s actual: %s", a.authority, a.authorityWant, authority) + } else { + errChan <- nil + } + return func(ctx context.Context, network, address string) (net.Conn, error) { + return nil, errors.New("no need to dial") + } } - } - mockEndpointTarget := "foo.bar.com" - b := NewDefaultSRVBuilder() - cc := &testClientConn{target: mockEndpointTarget, errChan: make(chan error, 1)} - target := resolver.Target{ - URL: *testutils.MustParseURL(fmt.Sprintf("scheme://%s/%s", a.authority, mockEndpointTarget)), - } - r, err := b.Build(target, cc, resolver.BuildOptions{}) + mockEndpointTarget := "foo.bar.com" + b := NewDefaultSRVBuilder() + cc := &testClientConn{target: mockEndpointTarget, errChan: make(chan error, 1)} + target := resolver.Target{ + URL: *testutils.MustParseURL(fmt.Sprintf("scheme://%s/%s", a.authority, mockEndpointTarget)), + } + r, err := b.Build(target, cc, resolver.BuildOptions{}) - if err == nil { - r.Close() + if err == nil { + r.Close() - err = <-errChan - if err != nil { - t.Error(err.Error()) - } + err = <-errChan + if err != nil { + t.Error(err.Error()) + } - if a.expectError { - t.Errorf("custom authority should have caused an error: %s", a.authority) + if a.expectError { + t.Errorf("custom authority should have caused an error: %s", a.authority) + } + } else if !a.expectError { + t.Errorf("unexpected error using custom authority %s: %s", a.authority, err) } - } else if !a.expectError { - t.Errorf("unexpected error using custom authority %s: %s", a.authority, err) - } + }) } } diff --git a/observer/probers/http/http_conf.go b/observer/probers/http/http_conf.go index b40065be4fc..60a628e3328 100644 --- a/observer/probers/http/http_conf.go +++ b/observer/probers/http/http_conf.go @@ -4,9 +4,10 @@ import ( "fmt" "net/url" + "github.com/prometheus/client_golang/prometheus" + "github.com/letsencrypt/boulder/observer/probers" "github.com/letsencrypt/boulder/strictyaml" - "github.com/prometheus/client_golang/prometheus" ) // HTTPConf is exported to receive YAML configuration. @@ -49,7 +50,7 @@ func (c HTTPConf) validateURL() error { func (c HTTPConf) validateRCodes() error { if len(c.RCodes) == 0 { return fmt.Errorf( - "invalid 'rcodes', got: %q, please specify at least one", c.RCodes) + "invalid 'rcodes', got: %v, please specify at least one", c.RCodes) } for _, c := range c.RCodes { // ensure rcode entry is in range 100-599 diff --git a/wfe2/wfe_test.go b/wfe2/wfe_test.go index e51d43a87cf..1370c2a87d6 100644 --- a/wfe2/wfe_test.go +++ b/wfe2/wfe_test.go @@ -282,7 +282,7 @@ func (ra *MockRegistrationAuthority) GetAuthorization(_ context.Context, in *rap }, nil } - return nil, berrors.NotFoundError("no authorization found with id %q", in.Id) + return nil, berrors.NotFoundError("no authorization found with id %d", in.Id) } func (ra *MockRegistrationAuthority) DeactivateAuthorization(context.Context, *corepb.Authorization, ...grpc.CallOption) (*emptypb.Empty, error) { From 8b9b50df2b97053fa576fb70372d2d5b7798ead4 Mon Sep 17 00:00:00 2001 From: Aaron Gable Date: Wed, 22 Apr 2026 19:07:16 -0700 Subject: [PATCH 2/2] Clean up 'non-constant format string' errors in log package --- log/log.go | 38 ++++++++++++++++-------------------- log/mock.go | 4 ++-- log/validator/tail_logger.go | 8 ++++---- 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/log/log.go b/log/log.go index e69e0c1c0e1..90988e0cc3a 100644 --- a/log/log.go +++ b/log/log.go @@ -25,6 +25,7 @@ import ( // NewMock(). Any additions to this interface with format strings should be // added to the govet configuration in .golangci.yml type Logger interface { + Err(msg string) Errf(format string, a ...any) Warning(msg string) Warningf(format string, a ...any) @@ -133,7 +134,7 @@ func Get() Logger { } type writer interface { - logAtLevel(syslog.Priority, string, ...any) + logAtLevel(syslog.Priority, string) } // bothWriter implements writer and writes to both syslog and stdout. @@ -173,14 +174,9 @@ func checkSummed(msg string) string { // logAtLevel logs the provided message at the appropriate level, writing to // both stdout and the Logger -func (w *bothWriter) logAtLevel(level syslog.Priority, msg string, a ...any) { +func (w *bothWriter) logAtLevel(level syslog.Priority, msg string) { var err error - // Apply conditional formatting for f functions - if a != nil { - msg = fmt.Sprintf(msg, a...) - } - // Since messages are delimited by newlines, we have to escape any internal or // trailing newlines before generating the checksum or outputting the message. msg = strings.ReplaceAll(msg, "\n", "\\n") @@ -217,18 +213,13 @@ func (w *bothWriter) logAtLevel(level syslog.Priority, msg string, a ...any) { } // logAtLevel logs the provided message to stdout, or stderr if it is at Warning or Error level. -func (w *stdoutWriter) logAtLevel(level syslog.Priority, msg string, a ...any) { +func (w *stdoutWriter) logAtLevel(level syslog.Priority, msg string) { if int(level) <= w.level { output := w.stdout if int(level) <= int(syslog.LOG_WARNING) { output = w.stderr } - // Apply conditional formatting for f functions - if a != nil { - msg = fmt.Sprintf(msg, a...) - } - msg = strings.ReplaceAll(msg, "\n", "\\n") var color string @@ -269,30 +260,36 @@ func (log *impl) auditAtLevel(level syslog.Priority, msg string) { log.w.logAtLevel(level, msg) } +// Err level messages are always marked with the audit tag, for special handling +// at the upstream system logger. +func (log *impl) Err(msg string) { + log.w.logAtLevel(syslog.LOG_ERR, msg) +} + // Errf level messages are always marked with the audit tag, for special handling // at the upstream system logger. func (log *impl) Errf(format string, a ...any) { - log.w.logAtLevel(syslog.LOG_ERR, format, a...) + log.w.logAtLevel(syslog.LOG_ERR, fmt.Sprintf(format, a...)) } // Warning level messages pass through normally. func (log *impl) Warning(msg string) { - log.Warningf(msg) + log.w.logAtLevel(syslog.LOG_WARNING, msg) } // Warningf level messages pass through normally. func (log *impl) Warningf(format string, a ...any) { - log.w.logAtLevel(syslog.LOG_WARNING, format, a...) + log.w.logAtLevel(syslog.LOG_WARNING, fmt.Sprintf(format, a...)) } // Info level messages pass through normally. func (log *impl) Info(msg string) { - log.Infof(msg) + log.w.logAtLevel(syslog.LOG_INFO, msg) } // Infof level messages pass through normally. func (log *impl) Infof(format string, a ...any) { - log.w.logAtLevel(syslog.LOG_INFO, format, a...) + log.w.logAtLevel(syslog.LOG_INFO, fmt.Sprintf(format, a...)) } // InfoObject logs an INFO level JSON-serialized object message. @@ -308,13 +305,12 @@ func (log *impl) InfoObject(msg string, obj any) { // Debug level messages pass through normally. func (log *impl) Debug(msg string) { - log.Debugf(msg) - + log.w.logAtLevel(syslog.LOG_DEBUG, msg) } // Debugf level messages pass through normally. func (log *impl) Debugf(format string, a ...any) { - log.w.logAtLevel(syslog.LOG_DEBUG, format, a...) + log.w.logAtLevel(syslog.LOG_DEBUG, fmt.Sprintf(format, a...)) } // AuditInfo sends an INFO-severity JSON-serialized object message that is prefixed diff --git a/log/mock.go b/log/mock.go index 289c09ec1af..4acf13d864a 100644 --- a/log/mock.go +++ b/log/mock.go @@ -48,8 +48,8 @@ var levelName = map[syslog.Priority]string{ syslog.LOG_DEBUG: "DEBUG", } -func (w *mockWriter) logAtLevel(p syslog.Priority, msg string, a ...any) { - w.msgChan <- fmt.Sprintf("%s: %s", levelName[p&7], fmt.Sprintf(msg, a...)) +func (w *mockWriter) logAtLevel(p syslog.Priority, msg string) { + w.msgChan <- fmt.Sprintf("%s: %s", levelName[p&7], msg) } // newMockWriter returns a new mockWriter diff --git a/log/validator/tail_logger.go b/log/validator/tail_logger.go index 0e1a9999274..697ac00e459 100644 --- a/log/validator/tail_logger.go +++ b/log/validator/tail_logger.go @@ -12,22 +12,22 @@ type tailLogger struct { } func (tl tailLogger) Fatal(v ...any) { - tl.Errf(fmt.Sprint(v...)) //nolint: govet // just passing through + tl.Err(fmt.Sprint(v...)) } func (tl tailLogger) Fatalf(format string, v ...any) { tl.Errf(format, v...) } func (tl tailLogger) Fatalln(v ...any) { - tl.Errf(fmt.Sprint(v...) + "\n") //nolint: govet // just passing through + tl.Err(fmt.Sprint(v...) + "\n") } func (tl tailLogger) Panic(v ...any) { - tl.Errf(fmt.Sprint(v...)) //nolint: govet // just passing through + tl.Err(fmt.Sprint(v...)) } func (tl tailLogger) Panicf(format string, v ...any) { tl.Errf(format, v...) } func (tl tailLogger) Panicln(v ...any) { - tl.Errf(fmt.Sprint(v...) + "\n") //nolint: govet // just passing through + tl.Err(fmt.Sprint(v...) + "\n") } func (tl tailLogger) Print(v ...any) { tl.Info(fmt.Sprint(v...))