From 148f1f49e1c5230e565b5296becb31e37bbbfbd4 Mon Sep 17 00:00:00 2001 From: timflannagan Date: Fri, 9 Oct 2026 16:01:32 -0400 Subject: [PATCH 1/3] internal: Fix DNS relay tests on macOS Keep the portable DNS relay implementation available to unit tests on every supported development platform. Previously, relay.go referenced Linux-only network namespace APIs, so the DNS package did not compile when make test ran on macOS. Now the namespace-serving method lives in a Linux-tagged file while relay construction and socket-level tests remain portable. Signed-off-by: timflannagan --- internal/ateomnet/dns/relay.go | 40 ------------------ internal/ateomnet/dns/relay_linux.go | 63 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 40 deletions(-) create mode 100644 internal/ateomnet/dns/relay_linux.go diff --git a/internal/ateomnet/dns/relay.go b/internal/ateomnet/dns/relay.go index 81e2854399..e7f421342e 100644 --- a/internal/ateomnet/dns/relay.go +++ b/internal/ateomnet/dns/relay.go @@ -20,10 +20,7 @@ import ( "log/slog" "net" "net/netip" - "strconv" "time" - - "github.com/agent-substrate/substrate/internal/ateomnet/netns" ) const ( @@ -99,43 +96,6 @@ func NewRelayForUpstreams(upstreams []string) (*Relay, error) { }, nil } -// Serve serves UDP and TCP DNS in the sandbox's local gateway namespace. -func (r *Relay) Serve(ctx context.Context, ns netns.Handle) (*Server, error) { - // Bind the wildcard because the microVM tap's gateway address is added later. - address := net.JoinHostPort("0.0.0.0", strconv.Itoa(dnsPort)) - - netC := netConn{ - dialer: *r.dialer, - } - - if err := netns.Do(ctx, ns, func(context.Context) error { - pc, err := net.ListenPacket("udp", address) - if err != nil { - return fmt.Errorf("while opening the actor DNS socket: %w", err) - } - netC.udp = pc - l, err := net.Listen("tcp", address) - if err != nil { - _ = pc.Close() - return fmt.Errorf("while opening the actor DNS listener: %w", err) - } - netC.tcpListener = l - return nil - }); err != nil { - return nil, err - } - - egressUDP, err := net.ListenPacket("udp", ":0") - if err != nil { - _ = netC.udp.Close() - _ = netC.tcpListener.Close() - return nil, fmt.Errorf("while opening the worker DNS egress socket: %w", err) - } - netC.egressUDP = egressUDP - - return r.serveOn(ctx, &netC) -} - // serveOn serves DNS on netC's sockets, which the caller has already bound, // and dials upstreams with netC's dialer. func (r *Relay) serveOn(ctx context.Context, netC *netConn) (*Server, error) { diff --git a/internal/ateomnet/dns/relay_linux.go b/internal/ateomnet/dns/relay_linux.go new file mode 100644 index 0000000000..82e6f43d5b --- /dev/null +++ b/internal/ateomnet/dns/relay_linux.go @@ -0,0 +1,63 @@ +//go:build linux + +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dns + +import ( + "context" + "fmt" + "net" + "strconv" + + "github.com/agent-substrate/substrate/internal/ateomnet/netns" +) + +// Serve serves UDP and TCP DNS in the sandbox's local gateway namespace. +func (r *Relay) Serve(ctx context.Context, ns netns.Handle) (*Server, error) { + // Bind the wildcard because the microVM tap's gateway address is added later. + address := net.JoinHostPort("0.0.0.0", strconv.Itoa(dnsPort)) + + netC := netConn{ + dialer: *r.dialer, + } + + if err := netns.Do(ctx, ns, func(context.Context) error { + pc, err := net.ListenPacket("udp", address) + if err != nil { + return fmt.Errorf("while opening the actor DNS socket: %w", err) + } + netC.udp = pc + l, err := net.Listen("tcp", address) + if err != nil { + _ = pc.Close() + return fmt.Errorf("while opening the actor DNS listener: %w", err) + } + netC.tcpListener = l + return nil + }); err != nil { + return nil, err + } + + egressUDP, err := net.ListenPacket("udp", ":0") + if err != nil { + _ = netC.udp.Close() + _ = netC.tcpListener.Close() + return nil, fmt.Errorf("while opening the worker DNS egress socket: %w", err) + } + netC.egressUDP = egressUDP + + return r.serveOn(ctx, &netC) +} From 39667ba16f6648f24d287c3357c4f657e1224994 Mon Sep 17 00:00:00 2001 From: timflannagan Date: Fri, 9 Oct 2026 16:01:32 -0400 Subject: [PATCH 2/3] pkg: Isolate object storage tests from AWS profiles Prevent developer AWS profile settings from changing object storage unit test behavior. Previously, TestNewFromEnv redirected AWS config files but still inherited AWS_PROFILE and AWS_DEFAULT_PROFILE. An exported profile could make the AWS SDK reject the intentionally missing test configuration. Now the test clears both profile selectors before constructing the S3 client. Signed-off-by: timflannagan --- pkg/objectstorage/env_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/objectstorage/env_test.go b/pkg/objectstorage/env_test.go index 5b9b9e7e4e..ee02d368cc 100644 --- a/pkg/objectstorage/env_test.go +++ b/pkg/objectstorage/env_test.go @@ -41,6 +41,8 @@ func TestNewFromEnv(t *testing.T) { missing := filepath.Join(t.TempDir(), "missing") t.Setenv("AWS_CONFIG_FILE", missing) t.Setenv("AWS_SHARED_CREDENTIALS_FILE", missing) + t.Setenv("AWS_PROFILE", "") + t.Setenv("AWS_DEFAULT_PROFILE", "") t.Setenv("AWS_REGION", "us-east-1") t.Setenv("ATE_STORAGE_BACKEND", tc.backend) t.Setenv("AWS_S3_USE_PATH_STYLE", tc.pathStyle) From 76694dbd30c817e0666d9846a5b64e2a688125d0 Mon Sep 17 00:00:00 2001 From: timflannagan Date: Fri, 9 Oct 2026 16:40:20 -0400 Subject: [PATCH 3/3] internal: Fix DNS relay license header Correct the Apache license URL so the boilerplate verifier recognizes the header in the Linux DNS relay. Previously, the header used the HTTPS form while the verifier requires the repository's exact HTTP boilerplate and reported the header as missing. Now the relay uses the standard boilerplate and passes license verification. Signed-off-by: timflannagan --- internal/ateomnet/dns/relay_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ateomnet/dns/relay_linux.go b/internal/ateomnet/dns/relay_linux.go index 82e6f43d5b..53f0185b3f 100644 --- a/internal/ateomnet/dns/relay_linux.go +++ b/internal/ateomnet/dns/relay_linux.go @@ -6,7 +6,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS,