mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-29 06:06:03 +00:00
Moves e2e service util functions into service_util.go and cleans up test codes
This commit is contained in:
@@ -17,8 +17,13 @@ limitations under the License.
|
||||
package framework
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -30,6 +35,7 @@ import (
|
||||
coreclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||
"k8s.io/kubernetes/pkg/util/rand"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/util/uuid"
|
||||
@@ -586,3 +592,237 @@ func (config *NetworkingTestConfig) getServiceClient() coreclientset.ServiceInte
|
||||
func (config *NetworkingTestConfig) getNamespacesClient() coreclientset.NamespaceInterface {
|
||||
return config.f.ClientSet.Core().Namespaces()
|
||||
}
|
||||
|
||||
func CheckReachabilityFromPod(expectToBeReachable bool, namespace, pod, target string) {
|
||||
cmd := fmt.Sprintf("wget -T 5 -qO- %q", target)
|
||||
err := wait.PollImmediate(Poll, 2*time.Minute, func() (bool, error) {
|
||||
_, err := RunHostCmd(namespace, pod, cmd)
|
||||
if expectToBeReachable && err != nil {
|
||||
Logf("Expect target to be reachable. But got err: %v. Retry until timeout", err)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if !expectToBeReachable && err == nil {
|
||||
Logf("Expect target NOT to be reachable. But it is reachable. Retry until timeout")
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
// Does an HTTP GET, but does not reuse TCP connections
|
||||
// This masks problems where the iptables rule has changed, but we don't see it
|
||||
// This is intended for relatively quick requests (status checks), so we set a short (5 seconds) timeout
|
||||
func httpGetNoConnectionPool(url string) (*http.Response, error) {
|
||||
return httpGetNoConnectionPoolTimeout(url, 5*time.Second)
|
||||
}
|
||||
|
||||
func httpGetNoConnectionPoolTimeout(url string, timeout time.Duration) (*http.Response, error) {
|
||||
tr := utilnet.SetTransportDefaults(&http.Transport{
|
||||
DisableKeepAlives: true,
|
||||
})
|
||||
client := &http.Client{
|
||||
Transport: tr,
|
||||
Timeout: timeout,
|
||||
}
|
||||
|
||||
return client.Get(url)
|
||||
}
|
||||
|
||||
func TestReachableHTTP(ip string, port int, request string, expect string) (bool, error) {
|
||||
return TestReachableHTTPWithContent(ip, port, request, expect, nil)
|
||||
}
|
||||
|
||||
func TestReachableHTTPWithContent(ip string, port int, request string, expect string, content *bytes.Buffer) (bool, error) {
|
||||
return TestReachableHTTPWithContentTimeout(ip, port, request, expect, content, 5*time.Second)
|
||||
}
|
||||
|
||||
func TestReachableHTTPWithContentTimeout(ip string, port int, request string, expect string, content *bytes.Buffer, timeout time.Duration) (bool, error) {
|
||||
url := fmt.Sprintf("http://%s:%d%s", ip, port, request)
|
||||
if ip == "" {
|
||||
Failf("Got empty IP for reachability check (%s)", url)
|
||||
return false, nil
|
||||
}
|
||||
if port == 0 {
|
||||
Failf("Got port==0 for reachability check (%s)", url)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
Logf("Testing HTTP reachability of %v", url)
|
||||
|
||||
resp, err := httpGetNoConnectionPoolTimeout(url, timeout)
|
||||
if err != nil {
|
||||
Logf("Got error testing for reachability of %s: %v", url, err)
|
||||
return false, nil
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
Logf("Got error reading response from %s: %v", url, err)
|
||||
return false, nil
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return false, fmt.Errorf("received non-success return status %q trying to access %s; got body: %s",
|
||||
resp.Status, url, string(body))
|
||||
}
|
||||
if !strings.Contains(string(body), expect) {
|
||||
return false, fmt.Errorf("received response body without expected substring %q: %s", expect, string(body))
|
||||
}
|
||||
if content != nil {
|
||||
content.Write(body)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func TestNotReachableHTTP(ip string, port int) (bool, error) {
|
||||
return TestNotReachableHTTPTimeout(ip, port, 5*time.Second)
|
||||
}
|
||||
|
||||
func TestNotReachableHTTPTimeout(ip string, port int, timeout time.Duration) (bool, error) {
|
||||
url := fmt.Sprintf("http://%s:%d", ip, port)
|
||||
if ip == "" {
|
||||
Failf("Got empty IP for non-reachability check (%s)", url)
|
||||
return false, nil
|
||||
}
|
||||
if port == 0 {
|
||||
Failf("Got port==0 for non-reachability check (%s)", url)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
Logf("Testing HTTP non-reachability of %v", url)
|
||||
|
||||
resp, err := httpGetNoConnectionPoolTimeout(url, timeout)
|
||||
if err != nil {
|
||||
Logf("Confirmed that %s is not reachable", url)
|
||||
return true, nil
|
||||
}
|
||||
resp.Body.Close()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func TestReachableUDP(ip string, port int, request string, expect string) (bool, error) {
|
||||
uri := fmt.Sprintf("udp://%s:%d", ip, port)
|
||||
if ip == "" {
|
||||
Failf("Got empty IP for reachability check (%s)", uri)
|
||||
return false, nil
|
||||
}
|
||||
if port == 0 {
|
||||
Failf("Got port==0 for reachability check (%s)", uri)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
Logf("Testing UDP reachability of %v", uri)
|
||||
|
||||
con, err := net.Dial("udp", ip+":"+strconv.Itoa(port))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("Failed to dial %s:%d: %v", ip, port, err)
|
||||
}
|
||||
|
||||
_, err = con.Write([]byte(fmt.Sprintf("%s\n", request)))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("Failed to send request: %v", err)
|
||||
}
|
||||
|
||||
var buf []byte = make([]byte, len(expect)+1)
|
||||
|
||||
err = con.SetDeadline(time.Now().Add(3 * time.Second))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("Failed to set deadline: %v", err)
|
||||
}
|
||||
|
||||
_, err = con.Read(buf)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if !strings.Contains(string(buf), expect) {
|
||||
return false, fmt.Errorf("Failed to retrieve %q, got %q", expect, string(buf))
|
||||
}
|
||||
|
||||
Logf("Successfully reached %v", uri)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func TestNotReachableUDP(ip string, port int, request string) (bool, error) {
|
||||
uri := fmt.Sprintf("udp://%s:%d", ip, port)
|
||||
if ip == "" {
|
||||
Failf("Got empty IP for reachability check (%s)", uri)
|
||||
return false, nil
|
||||
}
|
||||
if port == 0 {
|
||||
Failf("Got port==0 for reachability check (%s)", uri)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
Logf("Testing UDP non-reachability of %v", uri)
|
||||
|
||||
con, err := net.Dial("udp", ip+":"+strconv.Itoa(port))
|
||||
if err != nil {
|
||||
Logf("Confirmed that %s is not reachable", uri)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
_, err = con.Write([]byte(fmt.Sprintf("%s\n", request)))
|
||||
if err != nil {
|
||||
Logf("Confirmed that %s is not reachable", uri)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var buf []byte = make([]byte, 1)
|
||||
|
||||
err = con.SetDeadline(time.Now().Add(3 * time.Second))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("Failed to set deadline: %v", err)
|
||||
}
|
||||
|
||||
_, err = con.Read(buf)
|
||||
if err != nil {
|
||||
Logf("Confirmed that %s is not reachable", uri)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func TestHitNodesFromOutside(externalIP string, httpPort int32, timeout time.Duration, expectedHosts sets.String) error {
|
||||
return TestHitNodesFromOutsideWithCount(externalIP, httpPort, timeout, expectedHosts, 1)
|
||||
}
|
||||
|
||||
func TestHitNodesFromOutsideWithCount(externalIP string, httpPort int32, timeout time.Duration, expectedHosts sets.String,
|
||||
countToSucceed int) error {
|
||||
Logf("Waiting up to %v for satisfying expectedHosts for %v times", timeout, countToSucceed)
|
||||
hittedHosts := sets.NewString()
|
||||
count := 0
|
||||
condition := func() (bool, error) {
|
||||
var respBody bytes.Buffer
|
||||
reached, err := TestReachableHTTPWithContentTimeout(externalIP, int(httpPort), "/hostname", "", &respBody,
|
||||
1*time.Second)
|
||||
if err != nil || !reached {
|
||||
return false, nil
|
||||
}
|
||||
hittedHost := strings.TrimSpace(respBody.String())
|
||||
if !expectedHosts.Has(hittedHost) {
|
||||
Logf("Error hitting unexpected host: %v, reset counter: %v", hittedHost, count)
|
||||
count = 0
|
||||
return false, nil
|
||||
}
|
||||
if !hittedHosts.Has(hittedHost) {
|
||||
hittedHosts.Insert(hittedHost)
|
||||
Logf("Missing %+v, got %+v", expectedHosts.Difference(hittedHosts), hittedHosts)
|
||||
}
|
||||
if hittedHosts.Equal(expectedHosts) {
|
||||
count++
|
||||
if count >= countToSucceed {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if err := wait.Poll(time.Second, timeout, condition); err != nil {
|
||||
return fmt.Errorf("error waiting for expectedHosts: %v, hittedHosts: %v, count: %v, expected count: %v",
|
||||
expectedHosts, hittedHosts, count, countToSucceed)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user