mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 02:03:20 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			205 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package nomad
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"net/http"
 | |
| 	"net/http/httptest"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/coredns/coredns/plugin/pkg/dnstest"
 | |
| 	"github.com/coredns/coredns/plugin/test"
 | |
| 
 | |
| 	nomad "github.com/hashicorp/nomad/api"
 | |
| 	"github.com/miekg/dns"
 | |
| )
 | |
| 
 | |
| func TestNomad(t *testing.T) {
 | |
| 	var demoNomad = Nomad{
 | |
| 		Next:    test.ErrorHandler(),
 | |
| 		ttl:     uint32(defaultTTL),
 | |
| 		Zone:    "service.nomad",
 | |
| 		clients: make([]*nomad.Client, 0),
 | |
| 	}
 | |
| 
 | |
| 	var cases = []test.Case{
 | |
| 		{
 | |
| 			Qname: "example.default.service.nomad.",
 | |
| 			Qtype: dns.TypeA,
 | |
| 			Rcode: dns.RcodeSuccess,
 | |
| 			Answer: []dns.RR{
 | |
| 				test.A("example.default.service.nomad.	30	IN	A	1.2.3.4"),
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			Qname:  "example.default.service.nomad.",
 | |
| 			Qtype:  dns.TypeAAAA,
 | |
| 			Rcode:  dns.RcodeSuccess,
 | |
| 			Answer: []dns.RR{},
 | |
| 		},
 | |
| 		{
 | |
| 			Qname: "fakeipv6.default.service.nomad.",
 | |
| 			Qtype: dns.TypeAAAA,
 | |
| 			Rcode: dns.RcodeSuccess,
 | |
| 			Answer: []dns.RR{
 | |
| 				test.AAAA("fakeipv6.default.service.nomad.	30	IN	AAAA	1:2:3::4"),
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			Qname:  "fakeipv6.default.service.nomad.",
 | |
| 			Qtype:  dns.TypeA,
 | |
| 			Rcode:  dns.RcodeSuccess,
 | |
| 			Answer: []dns.RR{},
 | |
| 		},
 | |
| 		{
 | |
| 			Qname: "multi.default.service.nomad.",
 | |
| 			Qtype: dns.TypeA,
 | |
| 			Rcode: dns.RcodeSuccess,
 | |
| 			Answer: []dns.RR{
 | |
| 				test.A("multi.default.service.nomad.	30	IN	A	1.2.3.4"),
 | |
| 				test.A("multi.default.service.nomad.	30	IN	A	1.2.3.5"),
 | |
| 				test.A("multi.default.service.nomad.	30	IN	A	1.2.3.6"),
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			Qname: "nonexistent.default.service.nomad.",
 | |
| 			Qtype: dns.TypeA,
 | |
| 			Rcode: dns.RcodeNameError,
 | |
| 			Answer: []dns.RR{
 | |
| 				test.SOA("nonexistent.default.service.nomad.	30	IN	SOA	ns1.nonexistent.default.service.nomad. hostmaster.service.nomad. 0 3600 600 86400 30"),
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			Qname:  "example.default.service.nomad.",
 | |
| 			Qtype:  dns.TypeSRV,
 | |
| 			Rcode:  dns.RcodeSuccess,
 | |
| 			Answer: []dns.RR{test.SRV("example.default.service.nomad.	30	IN	SRV	10 10 23202 example.default.service.nomad.")},
 | |
| 			Extra:  []dns.RR{test.A("example.default.service.nomad.  30       IN      A       1.2.3.4")},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	ctx := context.Background()
 | |
| 
 | |
| 	// Setup a fake Nomad servers.
 | |
| 	nomadServer1 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | |
| 		switch r.URL.Path {
 | |
| 		case "/v1/service/example":
 | |
| 			w.Write([]byte(`[{"Address":"1.2.3.4","Namespace":"default","Port":23202,"ServiceName":"example"}]`))
 | |
| 		case "/v1/service/fakeipv6":
 | |
| 			w.Write([]byte(`[{"Address":"1:2:3::4","Namespace":"default","Port":8000,"ServiceName":"fakeipv6"}]`))
 | |
| 		case "/v1/service/multi":
 | |
| 			w.Write([]byte(`[{"Address":"1.2.3.4","Namespace":"default","Port":25395,"ServiceName":"multi"},{"Address":"1.2.3.5","Namespace":"default","Port":20888,"ServiceName":"multi"},{"Address":"1.2.3.6","Namespace":"default","Port":26292,"ServiceName":"multi"}]`))
 | |
| 		case "/v1/service/nonexistent":
 | |
| 			w.Write([]byte(`[]`))
 | |
| 		case "/v1/agent/self":
 | |
| 			w.Write([]byte(`{"Member":{"Name":"foobar1"}}`))
 | |
| 		}
 | |
| 	}))
 | |
| 	defer nomadServer1.Close()
 | |
| 	nomadServer2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | |
| 		switch r.URL.Path {
 | |
| 		case "/v1/service/example":
 | |
| 			w.Write([]byte(`[{"Address":"1.2.3.4","Namespace":"default","Port":23202,"ServiceName":"example"}]`))
 | |
| 		case "/v1/service/fakeipv6":
 | |
| 			w.Write([]byte(`[{"Address":"1:2:3::4","Namespace":"default","Port":8000,"ServiceName":"fakeipv6"}]`))
 | |
| 		case "/v1/service/multi":
 | |
| 			w.Write([]byte(`[{"Address":"1.2.3.4","Namespace":"default","Port":25395,"ServiceName":"multi"},{"Address":"1.2.3.5","Namespace":"default","Port":20888,"ServiceName":"multi"},{"Address":"1.2.3.6","Namespace":"default","Port":26292,"ServiceName":"multi"}]`))
 | |
| 		case "/v1/service/nonexistent":
 | |
| 			w.Write([]byte(`[]`))
 | |
| 		case "/v1/agent/self":
 | |
| 			w.Write([]byte(`{"Member":{"Name":"foobar2"}}`))
 | |
| 		}
 | |
| 	}))
 | |
| 	defer nomadServer2.Close()
 | |
| 	nomadServer3 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | |
| 		switch r.URL.Path {
 | |
| 		case "/v1/service/example":
 | |
| 			w.Write([]byte(`[{"Address":"1.2.3.4","Namespace":"default","Port":23202,"ServiceName":"example"}]`))
 | |
| 		case "/v1/service/fakeipv6":
 | |
| 			w.Write([]byte(`[{"Address":"1:2:3::4","Namespace":"default","Port":8000,"ServiceName":"fakeipv6"}]`))
 | |
| 		case "/v1/service/multi":
 | |
| 			w.Write([]byte(`[{"Address":"1.2.3.4","Namespace":"default","Port":25395,"ServiceName":"multi"},{"Address":"1.2.3.5","Namespace":"default","Port":20888,"ServiceName":"multi"},{"Address":"1.2.3.6","Namespace":"default","Port":26292,"ServiceName":"multi"}]`))
 | |
| 		case "/v1/service/nonexistent":
 | |
| 			w.Write([]byte(`[]`))
 | |
| 		case "/v1/agent/self":
 | |
| 			w.Write([]byte(`{"Member":{"Name":"foobar3"}}`))
 | |
| 		}
 | |
| 	}))
 | |
| 	defer nomadServer3.Close()
 | |
| 
 | |
| 	// Configure the plugin to use the fake Nomad server.
 | |
| 	cfg := nomad.DefaultConfig()
 | |
| 	cfg.Address = nomadServer1.URL
 | |
| 	client1, err := nomad.NewClient(cfg)
 | |
| 	if err != nil {
 | |
| 		t.Errorf("Failed to create Nomad client: %v", err)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	demoNomad.clients = append(demoNomad.clients, client1)
 | |
| 
 | |
| 	cfg = nomad.DefaultConfig()
 | |
| 	cfg.Address = nomadServer2.URL
 | |
| 	client2, err := nomad.NewClient(cfg)
 | |
| 	if err != nil {
 | |
| 		t.Errorf("Failed to create Nomad client: %v", err)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	demoNomad.clients = append(demoNomad.clients, client2)
 | |
| 
 | |
| 	cfg = nomad.DefaultConfig()
 | |
| 	cfg.Address = nomadServer3.URL
 | |
| 	client3, err := nomad.NewClient(cfg)
 | |
| 	if err != nil {
 | |
| 		t.Errorf("Failed to create Nomad client: %v", err)
 | |
| 		return
 | |
| 	}
 | |
| 	demoNomad.clients = append(demoNomad.clients, client3)
 | |
| 
 | |
| 	client, _ := demoNomad.getClient()
 | |
| 	if client != client1 {
 | |
| 		t.Errorf("Expected client1")
 | |
| 	}
 | |
| 
 | |
| 	nomadServer1.Close()
 | |
| 
 | |
| 	client, _ = demoNomad.getClient()
 | |
| 	if client == client1 {
 | |
| 		t.Errorf("Expected client2")
 | |
| 	}
 | |
| 
 | |
| 	client, err = demoNomad.getClient()
 | |
| 	if err != nil {
 | |
| 		t.Errorf("Expected no error, but got %v", err)
 | |
| 	}
 | |
| 	if client == nil {
 | |
| 		t.Errorf("Expected client2 but got nil")
 | |
| 	}
 | |
| 	if client != client2 {
 | |
| 		t.Errorf("Expected client2")
 | |
| 	}
 | |
| 
 | |
| 	runTests(ctx, t, &demoNomad, cases)
 | |
| }
 | |
| 
 | |
| func runTests(ctx context.Context, t *testing.T, n *Nomad, cases []test.Case) {
 | |
| 	t.Helper()
 | |
| 	for i, tc := range cases {
 | |
| 		r := tc.Msg()
 | |
| 		w := dnstest.NewRecorder(&test.ResponseWriter{})
 | |
| 
 | |
| 		_, err := n.ServeDNS(ctx, w, r)
 | |
| 		if err != tc.Error {
 | |
| 			t.Errorf("Test %d: %v (%v) (%v)", i, err, w, r)
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		if w.Msg == nil {
 | |
| 			t.Errorf("Test %d: nil message", i)
 | |
| 		}
 | |
| 		if err := test.SortAndCheck(w.Msg, tc); err != nil {
 | |
| 			t.Errorf("Test %d: %v", i, err)
 | |
| 		}
 | |
| 	}
 | |
| }
 |