@@ -23,7 +23,6 @@ import (
2323 "crypto/x509"
2424 "fmt"
2525 "io"
26- "log"
2726 "math/rand"
2827 "net"
2928 "net/http"
@@ -36,7 +35,7 @@ import (
3635 dockerRegistry "github.com/distribution/distribution/v3/registry"
3736 _ "github.com/distribution/distribution/v3/registry/auth/htpasswd"
3837 _ "github.com/distribution/distribution/v3/registry/storage/driver/inmemory"
39- "github.com/foxcpp/go-mockdns "
38+ "github.com/miekg/dns "
4039 "github.com/phayes/freeport"
4140 "github.com/sirupsen/logrus"
4241 "golang.org/x/crypto/bcrypt"
@@ -123,7 +122,7 @@ type registryClientTestServer struct {
123122 registryHost string
124123 workspaceDir string
125124 registryClient * helmreg.Client
126- dnsServer * mockdns. Server
125+ registry * dockerRegistry. Registry
127126}
128127
129128type registryOptions struct {
@@ -157,23 +156,11 @@ func setupRegistryServer(ctx context.Context, workspaceDir string, opts registry
157156 }
158157
159158 // Change the registry host to a host which is not localhost and
160- // mock DNS to map example.com to 127.0.0.1.
159+ // TestMain() will create a DNS proxy to map example.com to 127.0.0.1.
161160 // This is required because Docker enforces HTTP if the registry
162161 // is hosted on localhost/127.0.0.1.
163162 if opts .withTLS {
164163 server .registryHost = fmt .Sprintf ("example.com:%d" , port )
165- // Disable DNS server logging as it is extremely chatty.
166- dnsLog := log .Default ()
167- dnsLog .SetOutput (io .Discard )
168- server .dnsServer , err = mockdns .NewServerWithLogger (map [string ]mockdns.Zone {
169- "example.com." : {
170- A : []string {"127.0.0.1" },
171- },
172- }, dnsLog , false )
173- if err != nil {
174- return nil , err
175- }
176- server .dnsServer .PatchNet (net .DefaultResolver )
177164 } else {
178165 server .registryHost = fmt .Sprintf ("127.0.0.1:%d" , port )
179166 }
@@ -230,6 +217,7 @@ func setupRegistryServer(ctx context.Context, workspaceDir string, opts registry
230217 if err != nil {
231218 return nil , fmt .Errorf ("failed to create docker registry: %w" , err )
232219 }
220+ server .registry = registry
233221
234222 // init test client
235223 helmClient , err := helmreg .NewClient (clientOpts ... )
@@ -239,7 +227,7 @@ func setupRegistryServer(ctx context.Context, workspaceDir string, opts registry
239227 server .registryClient = helmClient
240228
241229 // Start Docker registry
242- go registry .ListenAndServe ()
230+ go server . registry .ListenAndServe ()
243231
244232 return server , nil
245233}
@@ -267,23 +255,39 @@ func tlsConfiguredHTTPCLient() (*http.Client, error) {
267255}
268256
269257func (r * registryClientTestServer ) Close () {
270- if r .dnsServer != nil {
271- mockdns .UnpatchNet (net .DefaultResolver )
272- r .dnsServer .Close ()
258+ if r .registry != nil {
259+ _ = r .registry .Shutdown (ctx )
273260 }
274261}
275262
276263func TestMain (m * testing.M ) {
277264 initTestTLS ()
278265
266+ // Setup global test DNS proxy
267+ dnsServer , addr , err := startDNSProxy ("1.1.1.1:53" )
268+ if err != nil {
269+ panic (fmt .Sprintf ("failed to create test DNS proxy: %v" , err ))
270+ }
271+ defer dnsServer .Shutdown ()
272+
273+ origDial := net .DefaultResolver .Dial
274+ origPreferGo := net .DefaultResolver .PreferGo
275+ net .DefaultResolver .PreferGo = true
276+ net .DefaultResolver .Dial = func (ctx context.Context , network , address string ) (net.Conn , error ) {
277+ return net .Dial ("udp" , addr )
278+ }
279+ defer func () {
280+ net .DefaultResolver .Dial = origDial
281+ net .DefaultResolver .PreferGo = origPreferGo
282+ }()
283+
279284 utilruntime .Must (sourcev1 .AddToScheme (scheme .Scheme ))
280285
281286 testEnv = testenv .New (
282287 testenv .WithCRDPath (filepath .Join (".." , ".." , "config" , "crd" , "bases" )),
283288 testenv .WithMaxConcurrentReconciles (4 ),
284289 )
285290
286- var err error
287291 // Initialize a cacheless client for tests that need the latest objects.
288292 k8sClient , err = client .New (testEnv .Config , client.Options {Scheme : scheme .Scheme })
289293 if err != nil {
@@ -410,6 +414,44 @@ func TestMain(m *testing.M) {
410414 os .Exit (code )
411415}
412416
417+ func startDNSProxy (upstream string ) (* dns.Server , string , error ) {
418+ pc , err := net .ListenPacket ("udp" , "127.0.0.1:0" )
419+ if err != nil {
420+ return nil , "" , err
421+ }
422+
423+ server := & dns.Server {
424+ PacketConn : pc ,
425+ Handler : dns .HandlerFunc (func (w dns.ResponseWriter , r * dns.Msg ) {
426+ m := new (dns.Msg )
427+ m .SetReply (r )
428+ m .RecursionAvailable = true
429+
430+ for _ , q := range r .Question {
431+ if q .Name == "example.com." && q .Qtype == dns .TypeA {
432+ rr , _ := dns .NewRR ("example.com. 3600 IN A 127.0.0.1" )
433+ m .Answer = append (m .Answer , rr )
434+ } else {
435+ // Forward
436+ c := new (dns.Client )
437+ in , _ , err := c .Exchange (r , upstream )
438+ if err == nil {
439+ m .Answer = append (m .Answer , in .Answer ... )
440+ m .Ns = append (m .Ns , in .Ns ... )
441+ m .Extra = append (m .Extra , in .Extra ... )
442+ m .Rcode = in .Rcode
443+ } else {
444+ m .Rcode = dns .RcodeServerFailure
445+ }
446+ }
447+ }
448+ w .WriteMsg (m )
449+ }),
450+ }
451+ go server .ActivateAndServe ()
452+ return server , pc .LocalAddr ().String (), nil
453+ }
454+
413455func initTestTLS () {
414456 var err error
415457 tlsPublicKey , err = os .ReadFile ("testdata/certs/server.pem" )
0 commit comments