mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Port update.sh to ginkgo test
This commit is contained in:
		@@ -16,6 +16,9 @@
 | 
			
		||||
 | 
			
		||||
# Launches an nginx container and verifies it can be reached. Assumes that
 | 
			
		||||
# we're being called by hack/e2e-test.sh (we use some env vars it sets up).
 | 
			
		||||
 | 
			
		||||
# TODO: remove this once test/e2e/kubectl.go is green in jenkins
 | 
			
		||||
 | 
			
		||||
set -o errexit
 | 
			
		||||
set -o nounset
 | 
			
		||||
set -o pipefail
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										192
									
								
								test/e2e/kubectl.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								test/e2e/kubectl.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,192 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2015 Google Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package e2e
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	. "github.com/onsi/ginkgo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	nautilusImage       = "kubernetes/update-demo:nautilus"
 | 
			
		||||
	kittenImage         = "kubernetes/update-demo:kitten"
 | 
			
		||||
	updateDemoSelector  = "name=update-demo"
 | 
			
		||||
	updateDemoContainer = "update-demo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ = Describe("kubectl", func() {
 | 
			
		||||
 | 
			
		||||
	updateDemoRoot := filepath.Join(root, "examples/update-demo")
 | 
			
		||||
	nautilusPath := filepath.Join(updateDemoRoot, "nautilus-rc.yaml")
 | 
			
		||||
	kittenPath := filepath.Join(updateDemoRoot, "kitten-rc.yaml")
 | 
			
		||||
 | 
			
		||||
	It("should create and stop a replication controller", func() {
 | 
			
		||||
		defer cleanup(nautilusPath)
 | 
			
		||||
 | 
			
		||||
		By("creating a replication controller")
 | 
			
		||||
		runKubectl("create", "-f", nautilusPath)
 | 
			
		||||
		validateController(nautilusImage, 2, 30*time.Second)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	It("should scale a replication controller", func() {
 | 
			
		||||
		defer cleanup(nautilusPath)
 | 
			
		||||
 | 
			
		||||
		By("creating a replication controller")
 | 
			
		||||
		runKubectl("create", "-f", nautilusPath)
 | 
			
		||||
		validateController(nautilusImage, 2, 30*time.Second)
 | 
			
		||||
		By("scaling down the replication controller")
 | 
			
		||||
		runKubectl("resize", "rc", "update-demo-nautilus", "--replicas=1")
 | 
			
		||||
		validateController(nautilusImage, 1, 30*time.Second)
 | 
			
		||||
		By("scaling up the replication controller")
 | 
			
		||||
		runKubectl("resize", "rc", "update-demo-nautilus", "--replicas=2")
 | 
			
		||||
		validateController(nautilusImage, 2, 30*time.Second)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	It("should do a rolling update of a replication controller", func() {
 | 
			
		||||
		// Cleanup all resources in case we fail somewhere in the middle
 | 
			
		||||
		defer cleanup(updateDemoRoot)
 | 
			
		||||
 | 
			
		||||
		By("creating the initial replication controller")
 | 
			
		||||
		runKubectl("create", "-f", nautilusPath)
 | 
			
		||||
		validateController(nautilusImage, 2, 30*time.Second)
 | 
			
		||||
		By("rollingupdate to new replication controller")
 | 
			
		||||
		runKubectl("rollingupdate", "update-demo-nautilus", "--update-period=1s", "-f", kittenPath)
 | 
			
		||||
		validateController(kittenImage, 2, 30*time.Second)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
func cleanup(filePath string) {
 | 
			
		||||
	By("using stop to clean up resources")
 | 
			
		||||
	runKubectl("stop", "-f", filePath)
 | 
			
		||||
 | 
			
		||||
	resources := runKubectl("get", "pods,rc", "-l", updateDemoSelector, "--no-headers")
 | 
			
		||||
	if resources != "" {
 | 
			
		||||
		Failf("Resources left running after stop:\n%s", resources)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func validateController(image string, replicas int, timeout time.Duration) {
 | 
			
		||||
 | 
			
		||||
	getPodsTemplate := "--template={{range.items}}{{.id}} {{end}}"
 | 
			
		||||
 | 
			
		||||
	// NB: kubectl adds the "exists" function to the standard template functions.
 | 
			
		||||
	// This lets us check to see if the "running" entry exists for each of the containers
 | 
			
		||||
	// we care about. Exists will never return an error and it's safe to check a chain of
 | 
			
		||||
	// things, any one of which may not exist. In the below template, all of info,
 | 
			
		||||
	// containername, and running might be nil, so the normal index function isn't very
 | 
			
		||||
	// helpful.
 | 
			
		||||
	// This template is unit-tested in kubectl, so if you change it, update the unit test.
 | 
			
		||||
	//
 | 
			
		||||
	// You can read about the syntax here: http://golang.org/pkg/text/template/
 | 
			
		||||
	getContainerStateTemplate := fmt.Sprintf(`--template={{and (exists . "currentState" "info" "%s" "state" "running")}}`, updateDemoContainer)
 | 
			
		||||
 | 
			
		||||
	getImageTemplate := fmt.Sprintf(`--template={{(index .currentState.info "%s").image}}`, updateDemoContainer)
 | 
			
		||||
 | 
			
		||||
	getHostIPTemplate := "--template={{.currentState.hostIP}}"
 | 
			
		||||
 | 
			
		||||
	By(fmt.Sprintf("waiting for all containers in %s pods to come up.", updateDemoSelector))
 | 
			
		||||
	for start := time.Now(); time.Since(start) < timeout; time.Sleep(5 * time.Second) {
 | 
			
		||||
		getPodsOutput := runKubectl("get", "pods", "-o", "template", getPodsTemplate, "-l", updateDemoSelector)
 | 
			
		||||
		pods := strings.Fields(getPodsOutput)
 | 
			
		||||
		if numPods := len(pods); numPods != replicas {
 | 
			
		||||
			By(fmt.Sprintf("Replicas for %s: expected=%d actual=%d", updateDemoSelector, replicas, numPods))
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		var runningPods []string
 | 
			
		||||
		for _, podId := range pods {
 | 
			
		||||
			running := runKubectl("get", "pods", podId, "-o", "template", getContainerStateTemplate)
 | 
			
		||||
			if running == "false" {
 | 
			
		||||
				By(fmt.Sprintf("%s is created but not running", podId))
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			currentImage := runKubectl("get", "pods", podId, "-o", "template", getImageTemplate)
 | 
			
		||||
			if currentImage != image {
 | 
			
		||||
				By(fmt.Sprintf("%s is created but running wrong image; expected: %s, actual: %s", podId, image, currentImage))
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			hostIP := runKubectl("get", "pods", podId, "-o", "template", getHostIPTemplate)
 | 
			
		||||
			data, err := getData(hostIP)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				By(fmt.Sprintf("%s is running right image but fetching data failed: %v", podId, err))
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if strings.Contains(data.image, image) {
 | 
			
		||||
				By(fmt.Sprintf("%s is running right image but fetched data has the wrong info: %s", podId, data))
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Logf("%s is verified up and running", podId)
 | 
			
		||||
			runningPods = append(runningPods, podId)
 | 
			
		||||
		}
 | 
			
		||||
		if len(runningPods) == replicas {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	Failf("Timed out waiting for %s pods to reach valid state", updateDemoSelector)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type updateDemoData struct {
 | 
			
		||||
	image string `json:"image"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getData(hostIP string) (*updateDemoData, error) {
 | 
			
		||||
	addr := fmt.Sprintf("http://%s:8080/data.json", hostIP)
 | 
			
		||||
	resp, err := http.Get(fmt.Sprintf(addr))
 | 
			
		||||
	if err != nil || resp.StatusCode != 200 {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer resp.Body.Close()
 | 
			
		||||
	body, err := ioutil.ReadAll(resp.Body)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	Logf("got data: %s", body)
 | 
			
		||||
	var data updateDemoData
 | 
			
		||||
	err = json.Unmarshal(body, &data)
 | 
			
		||||
	return &data, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func runKubectl(args ...string) string {
 | 
			
		||||
	// TODO: use kubectl binary directly instead of shell wrapper
 | 
			
		||||
	path := filepath.Join(root, "cluster/kubectl.sh")
 | 
			
		||||
	cmdStr := path + " " + strings.Join(args, " ")
 | 
			
		||||
	Logf("Running '%v'", cmdStr)
 | 
			
		||||
 | 
			
		||||
	cmd := exec.Command(path, args...)
 | 
			
		||||
	var stdout, stderr bytes.Buffer
 | 
			
		||||
	cmd.Stdout = &stdout
 | 
			
		||||
	cmd.Stderr = &stderr
 | 
			
		||||
 | 
			
		||||
	if err := cmd.Run(); err != nil {
 | 
			
		||||
		Failf("Error running %v:\nCommand stdout:\n%v\nstderr:\n%v\n", cmd, cmd.Stdout, cmd.Stderr)
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	Logf(stdout.String())
 | 
			
		||||
	return stdout.String()
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user