Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorder/Modularize networking e2e + pod launch phase, clean up comments. #6341

Merged
merged 1 commit into from
Apr 2, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 95 additions & 74 deletions test/e2e/networking.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,62 @@ import (
. "github.com/onsi/gomega"
)

var _ = BeforeSuite(func() {
//Assert basic external connectivity.
//Since this is not really a test of kubernetes in any way, we
//leave it as a pre-test assertion, rather than a Ginko test.

By("Executing a successfull http request from the external internet")
resp, err := http.Get("http://google.com")
if err != nil {
Failf("Unable to connect/talk to the internet: %v", err)
}
if resp.StatusCode != http.StatusOK {
Failf("Unexpected error code, expected 200, got, %v (%v)", resp.StatusCode, resp)
}
})

func LaunchNetTestPodPerNode(nodes *api.NodeList, name string, c *client.Client, ns string) []string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe move this function to the test/e2e/util.go? It's useful function which starts pod on each node. As a parameter use docker image name.

podNames := []string{}

totalPods := len(nodes.Items)

Expect(totalPods).NotTo(Equal(0))

for i, node := range nodes.Items {
podName := fmt.Sprintf("%s-%d", name, i)
podNames = append(podNames, podName)
Logf("Creating pod %s on node %s", podName, node.Name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to have this log message?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find these log messages very useful for debugging.

_, err := c.Pods(ns).Create(&api.Pod{
ObjectMeta: api.ObjectMeta{
Name: podName,
Labels: map[string]string{
"name": name,
},
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "webserver",
Image: "gcr.io/google_containers/nettest:1.1",
Args: []string{
"-service=" + name,
//peers >= totalPods should be asserted by the container.
//the nettest container finds peers by looking up list of svc endpoints.
fmt.Sprintf("-peers=%d", totalPods),
"-namespace=" + ns},
Ports: []api.ContainerPort{{ContainerPort: 8080}},
},
},
Host: node.Name,
RestartPolicy: api.RestartPolicyNever,
},
})
Expect(err).NotTo(HaveOccurred())
}
return podNames
}

var _ = Describe("Networking", func() {
var c *client.Client

Expand All @@ -38,37 +94,38 @@ var _ = Describe("Networking", func() {
Expect(err).NotTo(HaveOccurred())
})

// First test because it has no dependencies on variables created later on.
It("should provide unchanging, static URL paths for kubernetes api services.", func() {
tests := []struct {
path string
}{
{path: "/validate"},
{path: "/healthz"},
// TODO: test proxy links here
}
for _, test := range tests {
By(fmt.Sprintf("testing: %s", test.path))
data, err := c.RESTClient.Get().
Namespace(api.NamespaceDefault).
AbsPath(test.path).
DoRaw()
if err != nil {
Failf("Failed: %v\nBody: %s", err, string(data))
}
}
})

// Create a unique namespace for this test.
ns := "nettest-" + randomSuffix()
name := "nettest"

It("should function for pods", func() {
It("should function for intra-pod communication", func() {
if testContext.Provider == "vagrant" {
By("Skipping test which is broken for vagrant (See https://github.com/GoogleCloudPlatform/kubernetes/issues/3580)")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"#3580" only

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup this should be skipped since its below the return if Provider==vagrant.

return
}

// Obtain a list of nodes so we can place one webserver container on each node.
nodes, err := c.Nodes().List()
if err != nil {
Failf("Failed to list nodes: %v", err)
}
peers := len(nodes.Items)
if peers == 0 {
Failf("Failed to find any nodes")
}

// Test basic external connectivity.
resp, err := http.Get("http://google.com/")
if err != nil {
Failf("unable to talk to the external internet: %v", err)
}
if resp.StatusCode != http.StatusOK {
Failf("unexpected error code. expected 200, got: %v (%v)", resp.StatusCode, resp)
}

name := "nettest"

By(fmt.Sprintf("Creating service with name %s in namespace %s", name, ns))
By(fmt.Sprintf("Creating a service named [%s] in namespace %s", name, ns))
svc, err := c.Services(ns).Create(&api.Service{
ObjectMeta: api.ObjectMeta{
Name: name,
Expand All @@ -88,8 +145,9 @@ var _ = Describe("Networking", func() {
},
})
if err != nil {
Failf("unable to create test service %s: %v", svc.Name, err)
Failf("unable to create test service named [%s] %v", svc.Name, err)
}

// Clean up service
defer func() {
defer GinkgoRecover()
Expand All @@ -99,37 +157,15 @@ var _ = Describe("Networking", func() {
}
}()

By("Creating a webserver pod on each node")
podNames := []string{}
for i, node := range nodes.Items {
podName := fmt.Sprintf("%s-%d", name, i)
podNames = append(podNames, podName)
Logf("Creating pod %s on node %s", podName, node.Name)
_, err := c.Pods(ns).Create(&api.Pod{
ObjectMeta: api.ObjectMeta{
Name: podName,
Labels: map[string]string{
"name": name,
},
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "webserver",
Image: "gcr.io/google_containers/nettest:1.1",
Args: []string{
"-service=" + name,
fmt.Sprintf("-peers=%d", peers),
"-namespace=" + ns},
Ports: []api.ContainerPort{{ContainerPort: 8080}},
},
},
Host: node.Name,
RestartPolicy: api.RestartPolicyNever,
},
})
Expect(err).NotTo(HaveOccurred())
By("Creating a webserver (pending) pod on each node")

nodes, err := c.Nodes().List()
if err != nil {
Failf("Failed to list nodes: %v", err)
}

podNames := LaunchNetTestPodPerNode(nodes, name, c, ns)

// Clean up the pods
defer func() {
defer GinkgoRecover()
Expand All @@ -141,7 +177,7 @@ var _ = Describe("Networking", func() {
}
}()

By("Wait for the webserver pods to be ready")
By("Waiting for the webserver pods to transition to Running state")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about moving this also to LaunchNetTestPodPerNode()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since its a test, i chose to keep it in this block - and use that function as a utility instead... is that ok?

for _, podName := range podNames {
err = waitForPodRunningInNamespace(c, podName, ns)
Expect(err).NotTo(HaveOccurred())
Expand All @@ -150,7 +186,10 @@ var _ = Describe("Networking", func() {
By("Waiting for connectivity to be verified")
const maxAttempts = 60
passed := false

//once response OK, evaluate response body for pass/fail.
var body []byte

for i := 0; i < maxAttempts && !passed; i++ {
time.Sleep(2 * time.Second)
Logf("About to make a proxy status call")
Expand All @@ -167,6 +206,7 @@ var _ = Describe("Networking", func() {
Logf("Attempt %v/%v: service/pod still starting. (error: '%v')", i, maxAttempts, err)
continue
}
//Finally, we pass/fail the test based on if the container's response body, as to wether or not it was able to find peers.
switch string(body) {
case "pass":
Logf("Passed on attempt %v. Cleaning up.", i)
Expand Down Expand Up @@ -205,23 +245,4 @@ var _ = Describe("Networking", func() {
Expect(string(body)).To(Equal("pass"))
})

It("should provide unchanging URLs", func() {
tests := []struct {
path string
}{
{path: "/validate"},
{path: "/healthz"},
// TODO: test proxy links here
}
for _, test := range tests {
By(fmt.Sprintf("testing: %s", test.path))
data, err := c.RESTClient.Get().
Namespace(ns).
AbsPath(test.path).
DoRaw()
if err != nil {
Failf("Failed: %v\nBody: %s", err, string(data))
}
}
})
})