mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
Merge pull request #83680 from bclau/tests/network-large-requests
tests: Adds large requests tests
This commit is contained in:
commit
b9fa6e01b9
@ -73,6 +73,9 @@ const (
|
|||||||
RegexIPv6 = "(?:(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-fA-F]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,1}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,2}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,3}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:[0-9a-fA-F]{1,4})):)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,4}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,5}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,6}(?:(?:[0-9a-fA-F]{1,4})))?::))))"
|
RegexIPv6 = "(?:(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-fA-F]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,1}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,2}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,3}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:[0-9a-fA-F]{1,4})):)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,4}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,5}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,6}(?:(?:[0-9a-fA-F]{1,4})))?::))))"
|
||||||
resizeNodeReadyTimeout = 2 * time.Minute
|
resizeNodeReadyTimeout = 2 * time.Minute
|
||||||
resizeNodeNotReadyTimeout = 2 * time.Minute
|
resizeNodeNotReadyTimeout = 2 * time.Minute
|
||||||
|
// netexec dial commands
|
||||||
|
// the destination will echo its hostname.
|
||||||
|
echoHostname = "hostname"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NetexecImageName is the image name for agnhost.
|
// NetexecImageName is the image name for agnhost.
|
||||||
@ -146,12 +149,30 @@ type NetworkingTestConfig struct {
|
|||||||
|
|
||||||
// DialFromEndpointContainer executes a curl via kubectl exec in an endpoint container.
|
// DialFromEndpointContainer executes a curl via kubectl exec in an endpoint container.
|
||||||
func (config *NetworkingTestConfig) DialFromEndpointContainer(protocol, targetIP string, targetPort, maxTries, minTries int, expectedEps sets.String) {
|
func (config *NetworkingTestConfig) DialFromEndpointContainer(protocol, targetIP string, targetPort, maxTries, minTries int, expectedEps sets.String) {
|
||||||
config.DialFromContainer(protocol, config.EndpointPods[0].Status.PodIP, targetIP, EndpointHTTPPort, targetPort, maxTries, minTries, expectedEps)
|
config.DialFromContainer(protocol, echoHostname, config.EndpointPods[0].Status.PodIP, targetIP, EndpointHTTPPort, targetPort, maxTries, minTries, expectedEps)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialFromTestContainer executes a curl via kubectl exec in a test container.
|
// DialFromTestContainer executes a curl via kubectl exec in a test container.
|
||||||
func (config *NetworkingTestConfig) DialFromTestContainer(protocol, targetIP string, targetPort, maxTries, minTries int, expectedEps sets.String) {
|
func (config *NetworkingTestConfig) DialFromTestContainer(protocol, targetIP string, targetPort, maxTries, minTries int, expectedEps sets.String) {
|
||||||
config.DialFromContainer(protocol, config.TestContainerPod.Status.PodIP, targetIP, testContainerHTTPPort, targetPort, maxTries, minTries, expectedEps)
|
config.DialFromContainer(protocol, echoHostname, config.TestContainerPod.Status.PodIP, targetIP, testContainerHTTPPort, targetPort, maxTries, minTries, expectedEps)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialEchoFromTestContainer executes a curl via kubectl exec in a test container. The response is expected to match the echoMessage.
|
||||||
|
func (config *NetworkingTestConfig) DialEchoFromTestContainer(protocol, targetIP string, targetPort, maxTries, minTries int, echoMessage string) {
|
||||||
|
expectedResponse := sets.NewString()
|
||||||
|
expectedResponse.Insert(echoMessage)
|
||||||
|
var dialCommand string
|
||||||
|
|
||||||
|
// NOTE(claudiub): netexec /dialCommand will send a request to the given targetIP and targetPort as follows:
|
||||||
|
// for HTTP: it will send a request to: http://targetIP:targetPort/dialCommand
|
||||||
|
// for UDP: it will send targetCommand as a message. The consumer receives the data message and looks for
|
||||||
|
// a few starting strings, including echo, and treats it accordingly.
|
||||||
|
if protocol == "http" {
|
||||||
|
dialCommand = fmt.Sprintf("echo?msg=%s", echoMessage)
|
||||||
|
} else {
|
||||||
|
dialCommand = fmt.Sprintf("echo%%20%s", echoMessage)
|
||||||
|
}
|
||||||
|
config.DialFromContainer(protocol, dialCommand, config.TestContainerPod.Status.PodIP, targetIP, testContainerHTTPPort, targetPort, maxTries, minTries, expectedResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// diagnoseMissingEndpoints prints debug information about the endpoints that
|
// diagnoseMissingEndpoints prints debug information about the endpoints that
|
||||||
@ -186,23 +207,29 @@ func (config *NetworkingTestConfig) EndpointHostnames() sets.String {
|
|||||||
// at least once.
|
// at least once.
|
||||||
// - maxTries is the maximum number of curl attempts. If this many attempts pass
|
// - maxTries is the maximum number of curl attempts. If this many attempts pass
|
||||||
// and we don't see all expected endpoints, the test fails.
|
// and we don't see all expected endpoints, the test fails.
|
||||||
// - expectedEps is the set of endpointnames to wait for. Typically this is also
|
// - targetIP is the source Pod IP that will dial the given dialCommand using the given protocol.
|
||||||
// the hostname reported by each pod in the service through /hostName.
|
// - dialCommand is the command that the targetIP will send to the targetIP using the given protocol.
|
||||||
|
// the dialCommand should be formatted properly for the protocol (http: URL path+parameters,
|
||||||
|
// udp: command%20parameters, where parameters are optional)
|
||||||
|
// - expectedResponses is the unordered set of responses to wait for. The responses are based on
|
||||||
|
// the dialCommand; for example, for the dialCommand "hostname", the expectedResponses
|
||||||
|
// should contain the hostnames reported by each pod in the service through /hostName.
|
||||||
// maxTries == minTries will confirm that we see the expected endpoints and no
|
// maxTries == minTries will confirm that we see the expected endpoints and no
|
||||||
// more for maxTries. Use this if you want to eg: fail a readiness check on a
|
// more for maxTries. Use this if you want to eg: fail a readiness check on a
|
||||||
// pod and confirm it doesn't show up as an endpoint.
|
// pod and confirm it doesn't show up as an endpoint.
|
||||||
func (config *NetworkingTestConfig) DialFromContainer(protocol, containerIP, targetIP string, containerHTTPPort, targetPort, maxTries, minTries int, expectedEps sets.String) {
|
func (config *NetworkingTestConfig) DialFromContainer(protocol, dialCommand, containerIP, targetIP string, containerHTTPPort, targetPort, maxTries, minTries int, expectedResponses sets.String) {
|
||||||
ipPort := net.JoinHostPort(containerIP, strconv.Itoa(containerHTTPPort))
|
ipPort := net.JoinHostPort(containerIP, strconv.Itoa(containerHTTPPort))
|
||||||
// The current versions of curl included in CentOS and RHEL distros
|
// The current versions of curl included in CentOS and RHEL distros
|
||||||
// misinterpret square brackets around IPv6 as globbing, so use the -g
|
// misinterpret square brackets around IPv6 as globbing, so use the -g
|
||||||
// argument to disable globbing to handle the IPv6 case.
|
// argument to disable globbing to handle the IPv6 case.
|
||||||
cmd := fmt.Sprintf("curl -g -q -s 'http://%s/dial?request=hostName&protocol=%s&host=%s&port=%d&tries=1'",
|
cmd := fmt.Sprintf("curl -g -q -s 'http://%s/dial?request=%s&protocol=%s&host=%s&port=%d&tries=1'",
|
||||||
ipPort,
|
ipPort,
|
||||||
|
dialCommand,
|
||||||
protocol,
|
protocol,
|
||||||
targetIP,
|
targetIP,
|
||||||
targetPort)
|
targetPort)
|
||||||
|
|
||||||
eps := sets.NewString()
|
responses := sets.NewString()
|
||||||
|
|
||||||
for i := 0; i < maxTries; i++ {
|
for i := 0; i < maxTries; i++ {
|
||||||
stdout, stderr, err := config.f.ExecShellInPodWithFullOutput(config.HostTestContainerPod.Name, cmd)
|
stdout, stderr, err := config.f.ExecShellInPodWithFullOutput(config.HostTestContainerPod.Name, cmd)
|
||||||
@ -219,25 +246,27 @@ func (config *NetworkingTestConfig) DialFromContainer(protocol, containerIP, tar
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, hostName := range output["responses"] {
|
for _, response := range output["responses"] {
|
||||||
trimmed := strings.TrimSpace(hostName)
|
trimmed := strings.TrimSpace(response)
|
||||||
if trimmed != "" {
|
if trimmed != "" {
|
||||||
eps.Insert(trimmed)
|
responses.Insert(trimmed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
framework.Logf("Waiting for endpoints: %v", expectedEps.Difference(eps))
|
framework.Logf("Waiting for responses: %v", expectedResponses.Difference(responses))
|
||||||
|
|
||||||
// Check against i+1 so we exit if minTries == maxTries.
|
// Check against i+1 so we exit if minTries == maxTries.
|
||||||
if (eps.Equal(expectedEps) || eps.Len() == 0 && expectedEps.Len() == 0) && i+1 >= minTries {
|
if (responses.Equal(expectedResponses) || responses.Len() == 0 && expectedResponses.Len() == 0) && i+1 >= minTries {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO: get rid of this delay #36281
|
// TODO: get rid of this delay #36281
|
||||||
time.Sleep(hitEndpointRetryDelay)
|
time.Sleep(hitEndpointRetryDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
config.diagnoseMissingEndpoints(eps)
|
if dialCommand == echoHostname {
|
||||||
framework.Failf("Failed to find expected endpoints:\nTries %d\nCommand %v\nretrieved %v\nexpected %v\n", maxTries, cmd, eps, expectedEps)
|
config.diagnoseMissingEndpoints(responses)
|
||||||
|
}
|
||||||
|
framework.Failf("Failed to find expected responses:\nTries %d\nCommand %v\nretrieved %v\nexpected %v\n", maxTries, cmd, responses, expectedResponses)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEndpointsFromTestContainer executes a curl via kubectl exec in a test container.
|
// GetEndpointsFromTestContainer executes a curl via kubectl exec in a test container.
|
||||||
|
@ -295,6 +295,20 @@ var _ = SIGDescribe("Networking", func() {
|
|||||||
framework.Failf("Unexpected endpoints return: %v, expect 1 endpoints", eps)
|
framework.Failf("Unexpected endpoints return: %v, expect 1 endpoints", eps)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ginkgo.It("should be able to handle large requests: http", func() {
|
||||||
|
config := e2enetwork.NewNetworkingTestConfig(f)
|
||||||
|
ginkgo.By(fmt.Sprintf("dialing(http) %v --> %v:%v (config.clusterIP)", config.TestContainerPod.Name, config.ClusterIP, e2enetwork.ClusterHTTPPort))
|
||||||
|
message := strings.Repeat("42", 1000)
|
||||||
|
config.DialEchoFromTestContainer("http", config.ClusterIP, e2enetwork.ClusterHTTPPort, config.MaxTries, 0, message)
|
||||||
|
})
|
||||||
|
|
||||||
|
ginkgo.It("should be able to handle large requests: udp", func() {
|
||||||
|
config := e2enetwork.NewNetworkingTestConfig(f)
|
||||||
|
ginkgo.By(fmt.Sprintf("dialing(udp) %v --> %v:%v (config.clusterIP)", config.TestContainerPod.Name, config.ClusterIP, e2enetwork.ClusterUDPPort))
|
||||||
|
message := "n" + strings.Repeat("o", 1999)
|
||||||
|
config.DialEchoFromTestContainer("udp", config.ClusterIP, e2enetwork.ClusterUDPPort, config.MaxTries, 0, message)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
ginkgo.It("should recreate its iptables rules if they are deleted [Disruptive]", func() {
|
ginkgo.It("should recreate its iptables rules if they are deleted [Disruptive]", func() {
|
||||||
|
Loading…
Reference in New Issue
Block a user