mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-04 03:03:14 -05:00 
			
		
		
		
	* multisocket plugin improves performance in multiprocessor systems Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com> * - refactoring - update doc Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com> * remove port from reuseport plugin README Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com> * rename reuseport plugin to numsockets plugin Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com> * Add Recommendations to numsockets README Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com> * added numsockets test; made NUM_SOCKETS mandatory in doc Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com> * restart and whoami tests for numsockets plugin Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com> * default value for numsockets Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com> * caddy up Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com> * add numsockets to plugin.cfg Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com> * - rename numsockets plugin to multisocket - default as GOMAXPROCS - update README Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com> * resolve conflicts Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com> --------- Signed-off-by: Viktor Rodionov <33463837+Shmillerov@users.noreply.github.com>
		
			
				
	
	
		
			170 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package test
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"net"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/miekg/dns"
 | 
						|
)
 | 
						|
 | 
						|
// These tests need a fixed port, because :0 selects a random port for each socket, but we need all sockets to be on
 | 
						|
// the same port.
 | 
						|
 | 
						|
func TestMultisocket(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		name            string
 | 
						|
		corefile        string
 | 
						|
		expectedServers int
 | 
						|
		expectedErr     string
 | 
						|
		expectedPort    string
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			name: "no multisocket",
 | 
						|
			corefile: `.:5054 {
 | 
						|
			}`,
 | 
						|
			expectedServers: 1,
 | 
						|
			expectedPort:    "5054",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "multisocket 1",
 | 
						|
			corefile: `.:5055 {
 | 
						|
				multisocket 1
 | 
						|
			}`,
 | 
						|
			expectedServers: 1,
 | 
						|
			expectedPort:    "5055",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "multisocket 2",
 | 
						|
			corefile: `.:5056 {
 | 
						|
				multisocket 2
 | 
						|
			}`,
 | 
						|
			expectedServers: 2,
 | 
						|
			expectedPort:    "5056",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "multisocket 100",
 | 
						|
			corefile: `.:5057 {
 | 
						|
				multisocket 100
 | 
						|
			}`,
 | 
						|
			expectedServers: 100,
 | 
						|
			expectedPort:    "5057",
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, test := range tests {
 | 
						|
		t.Run(test.name, func(t *testing.T) {
 | 
						|
			s, err := CoreDNSServer(test.corefile)
 | 
						|
			defer s.Stop()
 | 
						|
			if err != nil {
 | 
						|
				t.Fatalf("Could not get CoreDNS serving instance: %s", err)
 | 
						|
			}
 | 
						|
			// check number of servers
 | 
						|
			if len(s.Servers()) != test.expectedServers {
 | 
						|
				t.Fatalf("Expected %d servers, got %d", test.expectedServers, len(s.Servers()))
 | 
						|
			}
 | 
						|
 | 
						|
			// check that ports are the same
 | 
						|
			for _, listener := range s.Servers() {
 | 
						|
				if listener.Addr().String() != listener.LocalAddr().String() {
 | 
						|
					t.Fatalf("Expected tcp address %s to be on the same port as udp address %s",
 | 
						|
						listener.LocalAddr().String(), listener.Addr().String())
 | 
						|
				}
 | 
						|
				_, port, err := net.SplitHostPort(listener.Addr().String())
 | 
						|
				if err != nil {
 | 
						|
					t.Fatalf("Could not get port from listener addr: %s", err)
 | 
						|
				}
 | 
						|
				if port != test.expectedPort {
 | 
						|
					t.Fatalf("Expected port %s, got %s", test.expectedPort, port)
 | 
						|
				}
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestMultisocket_Restart(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		name             string
 | 
						|
		numSocketsBefore int
 | 
						|
		numSocketsAfter  int
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			name:             "increase",
 | 
						|
			numSocketsBefore: 1,
 | 
						|
			numSocketsAfter:  2,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:             "decrease",
 | 
						|
			numSocketsBefore: 2,
 | 
						|
			numSocketsAfter:  1,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:             "no changes",
 | 
						|
			numSocketsBefore: 2,
 | 
						|
			numSocketsAfter:  2,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, test := range tests {
 | 
						|
		t.Run(test.name, func(t *testing.T) {
 | 
						|
			corefile := `.:5058 {
 | 
						|
				multisocket %d
 | 
						|
			}`
 | 
						|
			srv, err := CoreDNSServer(fmt.Sprintf(corefile, test.numSocketsBefore))
 | 
						|
			if err != nil {
 | 
						|
				t.Fatalf("Could not get CoreDNS serving instance: %s", err)
 | 
						|
			}
 | 
						|
			if test.numSocketsBefore != len(srv.Servers()) {
 | 
						|
				t.Fatalf("Expected %d servers, got %d", test.numSocketsBefore, len(srv.Servers()))
 | 
						|
			}
 | 
						|
 | 
						|
			newSrv, err := srv.Restart(NewInput(fmt.Sprintf(corefile, test.numSocketsAfter)))
 | 
						|
			if err != nil {
 | 
						|
				t.Fatalf("Could not get CoreDNS serving instance: %s", err)
 | 
						|
			}
 | 
						|
			if test.numSocketsAfter != len(newSrv.Servers()) {
 | 
						|
				t.Fatalf("Expected %d servers, got %d", test.numSocketsAfter, len(newSrv.Servers()))
 | 
						|
			}
 | 
						|
			newSrv.Stop()
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Just check that server with multisocket works
 | 
						|
func TestMultisocket_WhoAmI(t *testing.T) {
 | 
						|
	corefile := `.:5059 {
 | 
						|
		multisocket
 | 
						|
		whoami
 | 
						|
	}`
 | 
						|
	s, udp, tcp, err := CoreDNSServerAndPorts(corefile)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Could not get CoreDNS serving instance: %s", err)
 | 
						|
	}
 | 
						|
	defer s.Stop()
 | 
						|
 | 
						|
	m := new(dns.Msg)
 | 
						|
	m.SetQuestion("whoami.example.org.", dns.TypeA)
 | 
						|
 | 
						|
	// check udp
 | 
						|
	cl := dns.Client{Net: "udp"}
 | 
						|
	udpResp, err := dns.Exchange(m, udp)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Expected to receive reply, but didn't: %v", err)
 | 
						|
	}
 | 
						|
	// check tcp
 | 
						|
	cl.Net = "tcp"
 | 
						|
	tcpResp, _, err := cl.Exchange(m, tcp)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Expected to receive reply, but didn't: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	for _, resp := range []*dns.Msg{udpResp, tcpResp} {
 | 
						|
		if resp.Rcode != dns.RcodeSuccess {
 | 
						|
			t.Fatalf("Expected RcodeSuccess, got %v", resp.Rcode)
 | 
						|
		}
 | 
						|
		if len(resp.Extra) != 2 {
 | 
						|
			t.Errorf("Expected 2 RRs in additional section, got %d", len(resp.Extra))
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |