mirror of https://github.com/status-im/consul.git
Fix TestDNS_ServiceLookup_ARecordLimits so that it only creates test agents the minimal amount of time (#21608)
* get rid of unused column * get rid of duplicate section now that deletion of unused column makes the section duplicate.. * explicit set protocol rathern than infer it in checkDNSService * explicit have attribute for whether to set EDNS0 in the test cases rathern than infer it in checkDNSService * now modify so that test agents are only created for each unique configuration which is based on the a_record_limit. * Fix TestDNS_ServiceLookup_AnswerLimits so that it only creates test agents the minimal amount of time. (#21609) Fix TestDNS_ServiceLookup_AnswerLimits so that it only creates test agents the minimal amount of time
This commit is contained in:
parent
e2bb1b76cc
commit
f76da16000
|
@ -2919,62 +2919,8 @@ func TestDNS_ServiceLookup_LargeResponses(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func testDNSServiceLookupResponseLimits(t *testing.T, answerLimit int, qType uint16,
|
||||
expectedService, expectedQuery, expectedQueryID int, additionalHCL string) (bool, error) {
|
||||
a := NewTestAgent(t, `
|
||||
node_name = "test-node"
|
||||
dns_config {
|
||||
udp_answer_limit = `+fmt.Sprintf("%d", answerLimit)+`
|
||||
}
|
||||
`+additionalHCL)
|
||||
defer a.Shutdown()
|
||||
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
|
||||
|
||||
choices := perfectlyRandomChoices(generateNumNodes, pctNodesWithIPv6)
|
||||
for i := 0; i < generateNumNodes; i++ {
|
||||
nodeAddress := fmt.Sprintf("127.0.0.%d", i+1)
|
||||
if choices[i] {
|
||||
nodeAddress = fmt.Sprintf("fe80::%d", i+1)
|
||||
}
|
||||
args := &structs.RegisterRequest{
|
||||
Datacenter: "dc1",
|
||||
Node: fmt.Sprintf("foo%d", i),
|
||||
Address: nodeAddress,
|
||||
Service: &structs.NodeService{
|
||||
Service: "api-tier",
|
||||
Port: 8080,
|
||||
},
|
||||
}
|
||||
|
||||
var out struct{}
|
||||
if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil {
|
||||
return false, fmt.Errorf("err: %v", err)
|
||||
}
|
||||
}
|
||||
var id string
|
||||
{
|
||||
args := &structs.PreparedQueryRequest{
|
||||
Datacenter: "dc1",
|
||||
Op: structs.PreparedQueryCreate,
|
||||
Query: &structs.PreparedQuery{
|
||||
Name: "api-tier",
|
||||
Service: structs.ServiceQuery{
|
||||
Service: "api-tier",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil {
|
||||
return false, fmt.Errorf("err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Look up the service directly and via prepared query.
|
||||
questions := []string{
|
||||
"api-tier.service.consul.",
|
||||
"api-tier.query.consul.",
|
||||
id + ".query.consul.",
|
||||
}
|
||||
func testDNSServiceLookupResponseLimits(questions []string, answerLimit int, qType uint16,
|
||||
expectedService, expectedQuery, expectedQueryID int, a *TestAgent) (bool, error) {
|
||||
for idx, question := range questions {
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion(question, qType)
|
||||
|
@ -3011,78 +2957,24 @@ func testDNSServiceLookupResponseLimits(t *testing.T, answerLimit int, qType uin
|
|||
|
||||
func checkDNSService(
|
||||
t *testing.T,
|
||||
generateNumNodes int,
|
||||
aRecordLimit int,
|
||||
protocol string,
|
||||
questions []string,
|
||||
a *TestAgent,
|
||||
qType uint16,
|
||||
expectedResultsCount int,
|
||||
udpSize uint16,
|
||||
setEDNS0 bool,
|
||||
) {
|
||||
a := NewTestAgent(t, `
|
||||
node_name = "test-node"
|
||||
dns_config {
|
||||
a_record_limit = `+fmt.Sprintf("%d", aRecordLimit)+`
|
||||
udp_answer_limit = `+fmt.Sprintf("%d", aRecordLimit)+`
|
||||
}
|
||||
`)
|
||||
defer a.Shutdown()
|
||||
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
|
||||
|
||||
choices := perfectlyRandomChoices(generateNumNodes, pctNodesWithIPv6)
|
||||
for i := 0; i < generateNumNodes; i++ {
|
||||
nodeAddress := fmt.Sprintf("127.0.0.%d", i+1)
|
||||
if choices[i] {
|
||||
nodeAddress = fmt.Sprintf("fe80::%d", i+1)
|
||||
}
|
||||
args := &structs.RegisterRequest{
|
||||
Datacenter: "dc1",
|
||||
Node: fmt.Sprintf("foo%d", i),
|
||||
Address: nodeAddress,
|
||||
Service: &structs.NodeService{
|
||||
Service: "api-tier",
|
||||
Port: 8080,
|
||||
},
|
||||
}
|
||||
|
||||
var out struct{}
|
||||
require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out))
|
||||
}
|
||||
var id string
|
||||
{
|
||||
args := &structs.PreparedQueryRequest{
|
||||
Datacenter: "dc1",
|
||||
Op: structs.PreparedQueryCreate,
|
||||
Query: &structs.PreparedQuery{
|
||||
Name: "api-tier",
|
||||
Service: structs.ServiceQuery{
|
||||
Service: "api-tier",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, a.RPC(context.Background(), "PreparedQuery.Apply", args, &id))
|
||||
}
|
||||
|
||||
// Look up the service directly and via prepared query.
|
||||
questions := []string{
|
||||
"api-tier.service.consul.",
|
||||
"api-tier.query.consul.",
|
||||
id + ".query.consul.",
|
||||
}
|
||||
for _, question := range questions {
|
||||
question := question
|
||||
t.Run("question: "+question, func(t *testing.T) {
|
||||
|
||||
m := new(dns.Msg)
|
||||
|
||||
m.SetQuestion(question, qType)
|
||||
protocol := "tcp"
|
||||
if udpSize > 0 {
|
||||
protocol = "udp"
|
||||
}
|
||||
if udpSize > 512 {
|
||||
if setEDNS0 {
|
||||
m.SetEdns0(udpSize, true)
|
||||
}
|
||||
c := &dns.Client{Net: protocol, UDPSize: 8192}
|
||||
c := &dns.Client{Net: protocol, UDPSize: udpSize}
|
||||
in, _, err := c.Exchange(m, a.DNSAddr())
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -3094,82 +2986,154 @@ func checkDNSService(
|
|||
}
|
||||
}
|
||||
|
||||
func registerServicesAndPreparedQuery(t *testing.T, generateNumNodes int, a *TestAgent, serviceUniquenessKey string) []string {
|
||||
choices := perfectlyRandomChoices(generateNumNodes, pctNodesWithIPv6)
|
||||
serviceName := fmt.Sprintf("api-tier-%s", serviceUniquenessKey)
|
||||
for i := 0; i < generateNumNodes; i++ {
|
||||
nodeAddress := fmt.Sprintf("127.0.0.%d", i+1)
|
||||
if choices[i] {
|
||||
nodeAddress = fmt.Sprintf("fe80::%d", i+1)
|
||||
}
|
||||
args := &structs.RegisterRequest{
|
||||
Datacenter: "dc1",
|
||||
Node: fmt.Sprintf("foo%d", i),
|
||||
Address: nodeAddress,
|
||||
Service: &structs.NodeService{
|
||||
Service: serviceName,
|
||||
Port: 8080,
|
||||
},
|
||||
}
|
||||
|
||||
var out struct{}
|
||||
require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out))
|
||||
}
|
||||
var preparedQueryID string
|
||||
{
|
||||
args := &structs.PreparedQueryRequest{
|
||||
Datacenter: "dc1",
|
||||
Op: structs.PreparedQueryCreate,
|
||||
Query: &structs.PreparedQuery{
|
||||
Name: serviceName,
|
||||
Service: structs.ServiceQuery{
|
||||
Service: serviceName,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, a.RPC(context.Background(), "PreparedQuery.Apply", args, &preparedQueryID))
|
||||
}
|
||||
|
||||
// Look up the service directly and via prepared query.
|
||||
questions := []string{
|
||||
fmt.Sprintf("%s.service.consul.", serviceName),
|
||||
fmt.Sprintf("%s.query.consul.", serviceName),
|
||||
preparedQueryID + ".query.consul.",
|
||||
}
|
||||
return questions
|
||||
}
|
||||
|
||||
func TestDNS_ServiceLookup_ARecordLimits(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("too slow for testing.Short")
|
||||
}
|
||||
const (
|
||||
UDP = "udp"
|
||||
TCP = "tcp"
|
||||
)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
aRecordLimit int
|
||||
expectedAResults int
|
||||
expectedAAAAResults int
|
||||
expectedANYResults int
|
||||
expectedSRVResults int
|
||||
numNodesTotal int
|
||||
udpSize uint16
|
||||
_unused_udpAnswerLimit int // NOTE: this field is not used
|
||||
}{
|
||||
type testCase struct {
|
||||
protocol string
|
||||
aRecordLimit int
|
||||
expectedAResults int
|
||||
expectedAAAAResults int
|
||||
expectedANYResults int
|
||||
expectedSRVResults int
|
||||
numNodesTotal int
|
||||
udpSize uint16
|
||||
setEDNS0 bool
|
||||
}
|
||||
|
||||
type aRecordLimit struct {
|
||||
name string
|
||||
limit int
|
||||
}
|
||||
|
||||
tests := map[string]testCase{
|
||||
// UDP + EDNS
|
||||
{"udp-edns-1", 1, 1, 1, 1, 30, 30, 8192, 3},
|
||||
{"udp-edns-2", 2, 2, 2, 2, 30, 30, 8192, 3},
|
||||
{"udp-edns-3", 3, 3, 3, 3, 30, 30, 8192, 3},
|
||||
{"udp-edns-4", 4, 4, 4, 4, 30, 30, 8192, 3},
|
||||
{"udp-edns-5", 5, 5, 5, 5, 30, 30, 8192, 3},
|
||||
{"udp-edns-6", 6, 6, 6, 6, 30, 30, 8192, 3},
|
||||
{"udp-edns-max", 6, 2, 1, 3, 3, 3, 8192, 3},
|
||||
// All UDP without EDNS have a limit of 2 answers due to udpAnswerLimit
|
||||
// Even SRV records are limit to 2 records
|
||||
{"udp-limit-1", 1, 1, 0, 1, 1, 1, 512, 2},
|
||||
{"udp-limit-2", 2, 1, 1, 2, 2, 2, 512, 2},
|
||||
// AAAA results limited by size of payload
|
||||
{"udp-limit-3", 3, 1, 1, 2, 2, 2, 512, 2},
|
||||
{"udp-limit-4", 4, 1, 1, 2, 2, 2, 512, 2},
|
||||
{"udp-limit-5", 5, 1, 1, 2, 2, 2, 512, 2},
|
||||
{"udp-limit-6", 6, 1, 1, 2, 2, 2, 512, 2},
|
||||
{"udp-limit-max", 6, 1, 1, 2, 2, 2, 512, 2},
|
||||
"udp-edns-1": {UDP, 1, 1, 1, 1, 30, 30, 8192, true},
|
||||
"udp-edns-2": {UDP, 2, 2, 2, 2, 30, 30, 8192, true},
|
||||
"udp-edns-3": {UDP, 3, 3, 3, 3, 30, 30, 8192, true},
|
||||
"udp-edns-4": {UDP, 4, 4, 4, 4, 30, 30, 8192, true},
|
||||
"udp-edns-5": {UDP, 5, 5, 5, 5, 30, 30, 8192, true},
|
||||
"udp-edns-6": {UDP, 6, 6, 6, 6, 30, 30, 8192, true},
|
||||
"udp-edns-max": {UDP, 6, 2, 1, 3, 3, 3, 8192, true},
|
||||
// All UDP without EDNS and no udpAnswerLimit
|
||||
// Size of records is limited by UDP payload
|
||||
{"udp-1", 1, 1, 0, 1, 1, 1, 512, 0},
|
||||
{"udp-2", 2, 1, 1, 2, 2, 2, 512, 0},
|
||||
{"udp-3", 3, 1, 1, 2, 2, 2, 512, 0},
|
||||
{"udp-4", 4, 1, 1, 2, 2, 2, 512, 0},
|
||||
{"udp-5", 5, 1, 1, 2, 2, 2, 512, 0},
|
||||
{"udp-6", 6, 1, 1, 2, 2, 2, 512, 0},
|
||||
"udp-1": {UDP, 1, 1, 0, 1, 1, 1, 512, false},
|
||||
"udp-2": {UDP, 2, 1, 1, 2, 2, 2, 512, false},
|
||||
"udp-3": {UDP, 3, 1, 1, 2, 2, 2, 512, false},
|
||||
"udp-4": {UDP, 4, 1, 1, 2, 2, 2, 512, false},
|
||||
"udp-5": {UDP, 5, 1, 1, 2, 2, 2, 512, false},
|
||||
"udp-6": {UDP, 6, 1, 1, 2, 2, 2, 512, false},
|
||||
// Only 3 A and 3 SRV records on 512 bytes
|
||||
{"udp-max", 6, 1, 1, 2, 2, 2, 512, 0},
|
||||
"udp-max": {UDP, 6, 1, 1, 2, 2, 2, 512, false},
|
||||
|
||||
{"tcp-1", 1, 1, 1, 1, 30, 30, 0, 0},
|
||||
{"tcp-2", 2, 2, 2, 2, 30, 30, 0, 0},
|
||||
{"tcp-3", 3, 3, 3, 3, 30, 30, 0, 0},
|
||||
{"tcp-4", 4, 4, 4, 4, 30, 30, 0, 0},
|
||||
{"tcp-5", 5, 5, 5, 5, 30, 30, 0, 0},
|
||||
{"tcp-6", 6, 6, 6, 6, 30, 30, 0, 0},
|
||||
{"tcp-max", 6, 1, 1, 2, 2, 2, 0, 0},
|
||||
"tcp-1": {TCP, 1, 1, 1, 1, 30, 30, 0, false},
|
||||
"tcp-2": {TCP, 2, 2, 2, 2, 30, 30, 0, false},
|
||||
"tcp-3": {TCP, 3, 3, 3, 3, 30, 30, 0, false},
|
||||
"tcp-4": {TCP, 4, 4, 4, 4, 30, 30, 0, false},
|
||||
"tcp-5": {TCP, 5, 5, 5, 5, 30, 30, 0, false},
|
||||
"tcp-6": {TCP, 6, 6, 6, 6, 30, 30, 0, false},
|
||||
"tcp-max": {TCP, 6, 1, 1, 2, 2, 2, 0, false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test := test // capture loop var
|
||||
for _, recordLimit := range []aRecordLimit{
|
||||
{"1", 1},
|
||||
{"2", 2},
|
||||
{"3", 3},
|
||||
{"4", 4},
|
||||
{"5", 5},
|
||||
{"6", 6},
|
||||
{"max", 6},
|
||||
} {
|
||||
t.Run("record-limit-"+recordLimit.name, func(t *testing.T) {
|
||||
a := NewTestAgent(t, `
|
||||
node_name = "test-node"
|
||||
dns_config {
|
||||
a_record_limit = `+fmt.Sprintf("%d", recordLimit.limit)+`
|
||||
udp_answer_limit = `+fmt.Sprintf("%d", recordLimit.limit)+`
|
||||
}
|
||||
`)
|
||||
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
defer a.Shutdown()
|
||||
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
|
||||
|
||||
// All those queries should have at max queriesLimited elements
|
||||
for _, testName := range []string{
|
||||
fmt.Sprintf("udp-edns-%s", recordLimit.name),
|
||||
fmt.Sprintf("udp-%s", recordLimit.name),
|
||||
fmt.Sprintf("tcp-%s", recordLimit.name),
|
||||
} {
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
test := tests[testName]
|
||||
questions := registerServicesAndPreparedQuery(t, test.numNodesTotal, a, testName)
|
||||
|
||||
t.Run("A", func(t *testing.T) {
|
||||
checkDNSService(t, test.numNodesTotal, test.aRecordLimit, dns.TypeA, test.expectedAResults, test.udpSize)
|
||||
})
|
||||
t.Run("A", func(t *testing.T) {
|
||||
checkDNSService(t, test.protocol, questions, a, dns.TypeA, test.expectedAResults, test.udpSize, test.setEDNS0)
|
||||
})
|
||||
|
||||
t.Run("AAAA", func(t *testing.T) {
|
||||
checkDNSService(t, test.numNodesTotal, test.aRecordLimit, dns.TypeAAAA, test.expectedAAAAResults, test.udpSize)
|
||||
})
|
||||
t.Run("AAAA", func(t *testing.T) {
|
||||
checkDNSService(t, test.protocol, questions, a, dns.TypeAAAA, test.expectedAAAAResults, test.udpSize, test.setEDNS0)
|
||||
})
|
||||
|
||||
t.Run("ANY", func(t *testing.T) {
|
||||
checkDNSService(t, test.numNodesTotal, test.aRecordLimit, dns.TypeANY, test.expectedANYResults, test.udpSize)
|
||||
})
|
||||
t.Run("ANY", func(t *testing.T) {
|
||||
checkDNSService(t, test.protocol, questions, a, dns.TypeANY, test.expectedANYResults, test.udpSize, test.setEDNS0)
|
||||
})
|
||||
|
||||
// No limits but the size of records for SRV records, since not subject to randomization issues
|
||||
t.Run("SRV", func(t *testing.T) {
|
||||
checkDNSService(t, test.expectedSRVResults, test.aRecordLimit, dns.TypeSRV, test.numNodesTotal, test.udpSize)
|
||||
})
|
||||
// No limits but the size of records for SRV records, since not subject to randomization issues
|
||||
t.Run("SRV", func(t *testing.T) {
|
||||
checkDNSService(t, test.protocol, questions, a, dns.TypeSRV, test.numNodesTotal, test.udpSize, test.setEDNS0)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -3217,25 +3181,36 @@ func TestDNS_ServiceLookup_AnswerLimits(t *testing.T) {
|
|||
}
|
||||
for _, test := range tests {
|
||||
test := test // capture loop var
|
||||
t.Run(fmt.Sprintf("A lookup %v", test), func(t *testing.T) {
|
||||
ok, err := testDNSServiceLookupResponseLimits(t, test.udpAnswerLimit, dns.TypeA, test.expectedAService, test.expectedAQuery, test.expectedAQueryID, "")
|
||||
if !ok {
|
||||
t.Fatalf("Expected service A lookup %s to pass: %v", test.name, err)
|
||||
}
|
||||
})
|
||||
t.Run(fmt.Sprintf("answer-limit-%s", test.name), func(t *testing.T) {
|
||||
a := NewTestAgent(t, fmt.Sprintf(`
|
||||
node_name = "test-node"
|
||||
dns_config {
|
||||
udp_answer_limit = %d
|
||||
}`, test.udpAnswerLimit))
|
||||
defer a.Shutdown()
|
||||
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
|
||||
questions := registerServicesAndPreparedQuery(t, generateNumNodes, a, test.name)
|
||||
|
||||
t.Run(fmt.Sprintf("AAAA lookup %v", test), func(t *testing.T) {
|
||||
ok, err := testDNSServiceLookupResponseLimits(t, test.udpAnswerLimit, dns.TypeAAAA, test.expectedAAAAService, test.expectedAAAAQuery, test.expectedAAAAQueryID, "")
|
||||
if !ok {
|
||||
t.Fatalf("Expected service AAAA lookup %s to pass: %v", test.name, err)
|
||||
}
|
||||
})
|
||||
t.Run(fmt.Sprintf("A lookup %v", test), func(t *testing.T) {
|
||||
ok, err := testDNSServiceLookupResponseLimits(questions, test.udpAnswerLimit, dns.TypeA, test.expectedAService, test.expectedAQuery, test.expectedAQueryID, a)
|
||||
if !ok {
|
||||
t.Fatalf("Expected service A lookup %s to pass: %v", test.name, err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("ANY lookup %v", test), func(t *testing.T) {
|
||||
ok, err := testDNSServiceLookupResponseLimits(t, test.udpAnswerLimit, dns.TypeANY, test.expectedANYService, test.expectedANYQuery, test.expectedANYQueryID, "")
|
||||
if !ok {
|
||||
t.Fatalf("Expected service ANY lookup %s to pass: %v", test.name, err)
|
||||
}
|
||||
t.Run(fmt.Sprintf("AAAA lookup %v", test), func(t *testing.T) {
|
||||
ok, err := testDNSServiceLookupResponseLimits(questions, test.udpAnswerLimit, dns.TypeAAAA, test.expectedAAAAService, test.expectedAAAAQuery, test.expectedAAAAQueryID, a)
|
||||
if !ok {
|
||||
t.Fatalf("Expected service AAAA lookup %s to pass: %v", test.name, err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("ANY lookup %v", test), func(t *testing.T) {
|
||||
ok, err := testDNSServiceLookupResponseLimits(questions, test.udpAnswerLimit, dns.TypeANY, test.expectedANYService, test.expectedANYQuery, test.expectedANYQueryID, a)
|
||||
if !ok {
|
||||
t.Fatalf("Expected service ANY lookup %s to pass: %v", test.name, err)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue