mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-30 17:53:21 -04:00 
			
		
		
		
	multisocket plugin (#6882)
* 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>
This commit is contained in:
		
							
								
								
									
										169
									
								
								test/multisocket_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								test/multisocket_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,169 @@ | ||||
| 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)) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user