mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-10-26 11:07:45 +00:00
First commit
This commit is contained in:
15
third_party/github.com/fsouza/go-dockerclient/testing/data/Dockerfile
vendored
Normal file
15
third_party/github.com/fsouza/go-dockerclient/testing/data/Dockerfile
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# this file describes how to build tsuru python image
|
||||
# to run it:
|
||||
# 1- install docker
|
||||
# 2- run: $ docker build -t tsuru/python https://raw.github.com/tsuru/basebuilder/master/python/Dockerfile
|
||||
|
||||
from base:ubuntu-quantal
|
||||
run apt-get install wget -y --force-yes
|
||||
run wget http://github.com/tsuru/basebuilder/tarball/master -O basebuilder.tar.gz --no-check-certificate
|
||||
run mkdir /var/lib/tsuru
|
||||
run tar -xvf basebuilder.tar.gz -C /var/lib/tsuru --strip 1
|
||||
run cp /var/lib/tsuru/python/deploy /var/lib/tsuru
|
||||
run cp /var/lib/tsuru/base/restart /var/lib/tsuru
|
||||
run cp /var/lib/tsuru/base/start /var/lib/tsuru
|
||||
run /var/lib/tsuru/base/install
|
||||
run /var/lib/tsuru/base/setup
|
||||
BIN
third_party/github.com/fsouza/go-dockerclient/testing/data/container.tar
vendored
Normal file
BIN
third_party/github.com/fsouza/go-dockerclient/testing/data/container.tar
vendored
Normal file
Binary file not shown.
BIN
third_party/github.com/fsouza/go-dockerclient/testing/data/dockerfile.tar
vendored
Normal file
BIN
third_party/github.com/fsouza/go-dockerclient/testing/data/dockerfile.tar
vendored
Normal file
Binary file not shown.
568
third_party/github.com/fsouza/go-dockerclient/testing/server.go
vendored
Normal file
568
third_party/github.com/fsouza/go-dockerclient/testing/server.go
vendored
Normal file
@@ -0,0 +1,568 @@
|
||||
// Copyright 2014 go-dockerclient authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package testing provides a fake implementation of the Docker API, useful for
|
||||
// testing purpose.
|
||||
package testing
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
"github.com/fsouza/go-dockerclient/utils"
|
||||
"github.com/gorilla/mux"
|
||||
mathrand "math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DockerServer represents a programmable, concurrent (not much), HTTP server
|
||||
// implementing a fake version of the Docker remote API.
|
||||
//
|
||||
// It can used in standalone mode, listening for connections or as an arbitrary
|
||||
// HTTP handler.
|
||||
//
|
||||
// For more details on the remote API, check http://goo.gl/yMI1S.
|
||||
type DockerServer struct {
|
||||
containers []*docker.Container
|
||||
cMut sync.RWMutex
|
||||
images []docker.Image
|
||||
iMut sync.RWMutex
|
||||
imgIDs map[string]string
|
||||
listener net.Listener
|
||||
mux *mux.Router
|
||||
hook func(*http.Request)
|
||||
failures map[string]FailureSpec
|
||||
}
|
||||
|
||||
// FailureSpec is used with PrepareFailure and describes in which situations
|
||||
// the request should fail. UrlRegex is mandatory, if a container id is sent
|
||||
// on the request you can also specify the other properties.
|
||||
type FailureSpec struct {
|
||||
UrlRegex string
|
||||
ContainerPath string
|
||||
ContainerArgs []string
|
||||
}
|
||||
|
||||
// NewServer returns a new instance of the fake server, in standalone mode. Use
|
||||
// the method URL to get the URL of the server.
|
||||
//
|
||||
// It receives the bind address (use 127.0.0.1:0 for getting an available port
|
||||
// on the host) and a hook function, that will be called on every request.
|
||||
func NewServer(bind string, hook func(*http.Request)) (*DockerServer, error) {
|
||||
listener, err := net.Listen("tcp", bind)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
server := DockerServer{listener: listener, imgIDs: make(map[string]string), hook: hook,
|
||||
failures: make(map[string]FailureSpec)}
|
||||
server.buildMuxer()
|
||||
go http.Serve(listener, &server)
|
||||
return &server, nil
|
||||
}
|
||||
|
||||
func (s *DockerServer) buildMuxer() {
|
||||
s.mux = mux.NewRouter()
|
||||
s.mux.Path("/commit").Methods("POST").HandlerFunc(s.handlerWrapper(s.commitContainer))
|
||||
s.mux.Path("/containers/json").Methods("GET").HandlerFunc(s.handlerWrapper(s.listContainers))
|
||||
s.mux.Path("/containers/create").Methods("POST").HandlerFunc(s.handlerWrapper(s.createContainer))
|
||||
s.mux.Path("/containers/{id:.*}/json").Methods("GET").HandlerFunc(s.handlerWrapper(s.inspectContainer))
|
||||
s.mux.Path("/containers/{id:.*}/start").Methods("POST").HandlerFunc(s.handlerWrapper(s.startContainer))
|
||||
s.mux.Path("/containers/{id:.*}/stop").Methods("POST").HandlerFunc(s.handlerWrapper(s.stopContainer))
|
||||
s.mux.Path("/containers/{id:.*}/wait").Methods("POST").HandlerFunc(s.handlerWrapper(s.waitContainer))
|
||||
s.mux.Path("/containers/{id:.*}/attach").Methods("POST").HandlerFunc(s.handlerWrapper(s.attachContainer))
|
||||
s.mux.Path("/containers/{id:.*}").Methods("DELETE").HandlerFunc(s.handlerWrapper(s.removeContainer))
|
||||
s.mux.Path("/images/create").Methods("POST").HandlerFunc(s.handlerWrapper(s.pullImage))
|
||||
s.mux.Path("/build").Methods("POST").HandlerFunc(s.handlerWrapper(s.buildImage))
|
||||
s.mux.Path("/images/json").Methods("GET").HandlerFunc(s.handlerWrapper(s.listImages))
|
||||
s.mux.Path("/images/{id:.*}").Methods("DELETE").HandlerFunc(s.handlerWrapper(s.removeImage))
|
||||
s.mux.Path("/images/{name:.*}/json").Methods("GET").HandlerFunc(s.handlerWrapper(s.inspectImage))
|
||||
s.mux.Path("/images/{name:.*}/push").Methods("POST").HandlerFunc(s.handlerWrapper(s.pushImage))
|
||||
s.mux.Path("/events").Methods("GET").HandlerFunc(s.listEvents)
|
||||
}
|
||||
|
||||
// PrepareFailure adds a new expected failure based on a FailureSpec
|
||||
// it receives an id for the failure and the spec.
|
||||
func (s *DockerServer) PrepareFailure(id string, spec FailureSpec) {
|
||||
s.failures[id] = spec
|
||||
}
|
||||
|
||||
// ResetFailure removes an expected failure identified by the id
|
||||
func (s *DockerServer) ResetFailure(id string) {
|
||||
delete(s.failures, id)
|
||||
}
|
||||
|
||||
// Stop stops the server.
|
||||
func (s *DockerServer) Stop() {
|
||||
if s.listener != nil {
|
||||
s.listener.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// URL returns the HTTP URL of the server.
|
||||
func (s *DockerServer) URL() string {
|
||||
if s.listener == nil {
|
||||
return ""
|
||||
}
|
||||
return "http://" + s.listener.Addr().String() + "/"
|
||||
}
|
||||
|
||||
// ServeHTTP handles HTTP requests sent to the server.
|
||||
func (s *DockerServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
s.mux.ServeHTTP(w, r)
|
||||
if s.hook != nil {
|
||||
s.hook(r)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerServer) handlerWrapper(f func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
for errorId, spec := range s.failures {
|
||||
matched, err := regexp.MatchString(spec.UrlRegex, r.URL.Path)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if !matched {
|
||||
continue
|
||||
}
|
||||
id := mux.Vars(r)["id"]
|
||||
if id != "" {
|
||||
container, _, err := s.findContainer(id)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if spec.ContainerPath != "" && container.Path != spec.ContainerPath {
|
||||
continue
|
||||
}
|
||||
if spec.ContainerArgs != nil && reflect.DeepEqual(container.Args, spec.ContainerArgs) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
http.Error(w, errorId, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
f(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerServer) listContainers(w http.ResponseWriter, r *http.Request) {
|
||||
all := r.URL.Query().Get("all")
|
||||
s.cMut.RLock()
|
||||
result := make([]docker.APIContainers, len(s.containers))
|
||||
for i, container := range s.containers {
|
||||
if all == "1" || container.State.Running {
|
||||
result[i] = docker.APIContainers{
|
||||
ID: container.ID,
|
||||
Image: container.Image,
|
||||
Command: fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " ")),
|
||||
Created: container.Created.Unix(),
|
||||
Status: container.State.String(),
|
||||
Ports: container.NetworkSettings.PortMappingAPI(),
|
||||
}
|
||||
}
|
||||
}
|
||||
s.cMut.RUnlock()
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(result)
|
||||
}
|
||||
|
||||
func (s *DockerServer) listImages(w http.ResponseWriter, r *http.Request) {
|
||||
s.cMut.RLock()
|
||||
result := make([]docker.APIImages, len(s.images))
|
||||
for i, image := range s.images {
|
||||
result[i] = docker.APIImages{
|
||||
ID: image.ID,
|
||||
Created: image.Created.Unix(),
|
||||
}
|
||||
}
|
||||
s.cMut.RUnlock()
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(result)
|
||||
}
|
||||
|
||||
func (s *DockerServer) findImage(id string) (string, error) {
|
||||
s.iMut.RLock()
|
||||
defer s.iMut.RUnlock()
|
||||
image, ok := s.imgIDs[id]
|
||||
if ok {
|
||||
return image, nil
|
||||
}
|
||||
image, _, err := s.findImageByID(id)
|
||||
return image, err
|
||||
}
|
||||
|
||||
func (s *DockerServer) findImageByID(id string) (string, int, error) {
|
||||
s.iMut.RLock()
|
||||
defer s.iMut.RUnlock()
|
||||
for i, image := range s.images {
|
||||
if image.ID == id {
|
||||
return image.ID, i, nil
|
||||
}
|
||||
}
|
||||
return "", -1, errors.New("No such image")
|
||||
}
|
||||
|
||||
func (s *DockerServer) createContainer(w http.ResponseWriter, r *http.Request) {
|
||||
var config docker.Config
|
||||
defer r.Body.Close()
|
||||
err := json.NewDecoder(r.Body).Decode(&config)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
image, err := s.findImage(config.Image)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
ports := map[docker.Port][]docker.PortBinding{}
|
||||
for port := range config.ExposedPorts {
|
||||
ports[port] = []docker.PortBinding{{
|
||||
HostIp: "0.0.0.0",
|
||||
HostPort: strconv.Itoa(mathrand.Int() % 65536),
|
||||
}}
|
||||
}
|
||||
|
||||
//the container may not have cmd when using a Dockerfile
|
||||
var path string
|
||||
var args []string
|
||||
if len(config.Cmd) == 1 {
|
||||
path = config.Cmd[0]
|
||||
} else if len(config.Cmd) > 1 {
|
||||
path = config.Cmd[0]
|
||||
args = config.Cmd[1:]
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
ID: s.generateID(),
|
||||
Created: time.Now(),
|
||||
Path: path,
|
||||
Args: args,
|
||||
Config: &config,
|
||||
State: docker.State{
|
||||
Running: false,
|
||||
Pid: mathrand.Int() % 50000,
|
||||
ExitCode: 0,
|
||||
StartedAt: time.Now(),
|
||||
},
|
||||
Image: image,
|
||||
NetworkSettings: &docker.NetworkSettings{
|
||||
IPAddress: fmt.Sprintf("172.16.42.%d", mathrand.Int()%250+2),
|
||||
IPPrefixLen: 24,
|
||||
Gateway: "172.16.42.1",
|
||||
Bridge: "docker0",
|
||||
Ports: ports,
|
||||
},
|
||||
}
|
||||
s.cMut.Lock()
|
||||
s.containers = append(s.containers, &container)
|
||||
s.cMut.Unlock()
|
||||
var c = struct{ ID string }{ID: container.ID}
|
||||
json.NewEncoder(w).Encode(c)
|
||||
}
|
||||
|
||||
func (s *DockerServer) generateID() string {
|
||||
var buf [16]byte
|
||||
rand.Read(buf[:])
|
||||
return fmt.Sprintf("%x", buf)
|
||||
}
|
||||
|
||||
func (s *DockerServer) inspectContainer(w http.ResponseWriter, r *http.Request) {
|
||||
id := mux.Vars(r)["id"]
|
||||
container, _, err := s.findContainer(id)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(container)
|
||||
}
|
||||
|
||||
func (s *DockerServer) startContainer(w http.ResponseWriter, r *http.Request) {
|
||||
id := mux.Vars(r)["id"]
|
||||
container, _, err := s.findContainer(id)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
s.cMut.Lock()
|
||||
defer s.cMut.Unlock()
|
||||
if container.State.Running {
|
||||
http.Error(w, "Container already running", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
container.State.Running = true
|
||||
}
|
||||
|
||||
func (s *DockerServer) stopContainer(w http.ResponseWriter, r *http.Request) {
|
||||
id := mux.Vars(r)["id"]
|
||||
container, _, err := s.findContainer(id)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
s.cMut.Lock()
|
||||
defer s.cMut.Unlock()
|
||||
if !container.State.Running {
|
||||
http.Error(w, "Container not running", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
container.State.Running = false
|
||||
}
|
||||
|
||||
func (s *DockerServer) attachContainer(w http.ResponseWriter, r *http.Request) {
|
||||
id := mux.Vars(r)["id"]
|
||||
container, _, err := s.findContainer(id)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
outStream := utils.NewStdWriter(w, utils.Stdout)
|
||||
fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
|
||||
if container.State.Running {
|
||||
fmt.Fprintf(outStream, "Container %q is running\n", container.ID)
|
||||
} else {
|
||||
fmt.Fprintf(outStream, "Container %q is not running\n", container.ID)
|
||||
}
|
||||
fmt.Fprintln(outStream, "What happened?")
|
||||
fmt.Fprintln(outStream, "Something happened")
|
||||
}
|
||||
|
||||
func (s *DockerServer) waitContainer(w http.ResponseWriter, r *http.Request) {
|
||||
id := mux.Vars(r)["id"]
|
||||
container, _, err := s.findContainer(id)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
for {
|
||||
time.Sleep(1e6)
|
||||
s.cMut.RLock()
|
||||
if !container.State.Running {
|
||||
s.cMut.RUnlock()
|
||||
break
|
||||
}
|
||||
s.cMut.RUnlock()
|
||||
}
|
||||
w.Write([]byte(`{"StatusCode":0}`))
|
||||
}
|
||||
|
||||
func (s *DockerServer) removeContainer(w http.ResponseWriter, r *http.Request) {
|
||||
id := mux.Vars(r)["id"]
|
||||
_, index, err := s.findContainer(id)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if s.containers[index].State.Running {
|
||||
msg := "Error: API error (406): Impossible to remove a running container, please stop it first"
|
||||
http.Error(w, msg, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
s.cMut.Lock()
|
||||
defer s.cMut.Unlock()
|
||||
s.containers[index] = s.containers[len(s.containers)-1]
|
||||
s.containers = s.containers[:len(s.containers)-1]
|
||||
}
|
||||
|
||||
func (s *DockerServer) commitContainer(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.URL.Query().Get("container")
|
||||
container, _, err := s.findContainer(id)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
var config *docker.Config
|
||||
runConfig := r.URL.Query().Get("run")
|
||||
if runConfig != "" {
|
||||
config = new(docker.Config)
|
||||
err = json.Unmarshal([]byte(runConfig), config)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
image := docker.Image{
|
||||
ID: "img-" + container.ID,
|
||||
Parent: container.Image,
|
||||
Container: container.ID,
|
||||
Comment: r.URL.Query().Get("m"),
|
||||
Author: r.URL.Query().Get("author"),
|
||||
Config: config,
|
||||
}
|
||||
repository := r.URL.Query().Get("repo")
|
||||
s.iMut.Lock()
|
||||
s.images = append(s.images, image)
|
||||
if repository != "" {
|
||||
s.imgIDs[repository] = image.ID
|
||||
}
|
||||
s.iMut.Unlock()
|
||||
fmt.Fprintf(w, `{"ID":%q}`, image.ID)
|
||||
}
|
||||
|
||||
func (s *DockerServer) findContainer(id string) (*docker.Container, int, error) {
|
||||
s.cMut.RLock()
|
||||
defer s.cMut.RUnlock()
|
||||
for i, container := range s.containers {
|
||||
if container.ID == id {
|
||||
return container, i, nil
|
||||
}
|
||||
}
|
||||
return nil, -1, errors.New("No such container")
|
||||
}
|
||||
|
||||
func (s *DockerServer) buildImage(w http.ResponseWriter, r *http.Request) {
|
||||
if ct := r.Header.Get("Content-Type"); ct == "application/tar" {
|
||||
gotDockerFile := false
|
||||
tr := tar.NewReader(r.Body)
|
||||
for {
|
||||
header, err := tr.Next()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if header.Name == "Dockerfile" {
|
||||
gotDockerFile = true
|
||||
}
|
||||
}
|
||||
if !gotDockerFile {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte("miss Dockerfile"))
|
||||
return
|
||||
}
|
||||
}
|
||||
//we did not use that Dockerfile to build image cause we are a fake Docker daemon
|
||||
image := docker.Image{
|
||||
ID: s.generateID(),
|
||||
}
|
||||
query := r.URL.Query()
|
||||
repository := image.ID
|
||||
if t := query.Get("t"); t != "" {
|
||||
repository = t
|
||||
}
|
||||
s.iMut.Lock()
|
||||
s.images = append(s.images, image)
|
||||
s.imgIDs[repository] = image.ID
|
||||
s.iMut.Unlock()
|
||||
w.Write([]byte(fmt.Sprintf("Successfully built %s", image.ID)))
|
||||
}
|
||||
|
||||
func (s *DockerServer) pullImage(w http.ResponseWriter, r *http.Request) {
|
||||
repository := r.URL.Query().Get("fromImage")
|
||||
image := docker.Image{
|
||||
ID: s.generateID(),
|
||||
}
|
||||
s.iMut.Lock()
|
||||
s.images = append(s.images, image)
|
||||
if repository != "" {
|
||||
s.imgIDs[repository] = image.ID
|
||||
}
|
||||
s.iMut.Unlock()
|
||||
}
|
||||
|
||||
func (s *DockerServer) pushImage(w http.ResponseWriter, r *http.Request) {
|
||||
name := mux.Vars(r)["name"]
|
||||
s.iMut.RLock()
|
||||
if _, ok := s.imgIDs[name]; !ok {
|
||||
s.iMut.RUnlock()
|
||||
http.Error(w, "No such image", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
s.iMut.RUnlock()
|
||||
fmt.Fprintln(w, "Pushing...")
|
||||
fmt.Fprintln(w, "Pushed")
|
||||
}
|
||||
|
||||
func (s *DockerServer) removeImage(w http.ResponseWriter, r *http.Request) {
|
||||
id := mux.Vars(r)["id"]
|
||||
s.iMut.RLock()
|
||||
if img, ok := s.imgIDs[id]; ok {
|
||||
id = img
|
||||
}
|
||||
s.iMut.RUnlock()
|
||||
_, index, err := s.findImageByID(id)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
s.iMut.Lock()
|
||||
defer s.iMut.Unlock()
|
||||
s.images[index] = s.images[len(s.images)-1]
|
||||
s.images = s.images[:len(s.images)-1]
|
||||
}
|
||||
|
||||
func (s *DockerServer) inspectImage(w http.ResponseWriter, r *http.Request) {
|
||||
name := mux.Vars(r)["name"]
|
||||
if id, ok := s.imgIDs[name]; ok {
|
||||
s.iMut.Lock()
|
||||
defer s.iMut.Unlock()
|
||||
|
||||
for _, img := range s.images {
|
||||
if img.ID == id {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(img)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
http.Error(w, "not found", http.StatusNotFound)
|
||||
}
|
||||
|
||||
func (s *DockerServer) listEvents(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var events [][]byte
|
||||
count := mathrand.Intn(20)
|
||||
for i := 0; i < count; i++ {
|
||||
data, err := json.Marshal(s.generateEvent())
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
events = append(events, data)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
for _, d := range events {
|
||||
fmt.Fprintln(w, d)
|
||||
time.Sleep(time.Duration(mathrand.Intn(200)) * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerServer) generateEvent() *docker.APIEvents {
|
||||
var eventType string
|
||||
switch mathrand.Intn(4) {
|
||||
case 0:
|
||||
eventType = "create"
|
||||
case 1:
|
||||
eventType = "start"
|
||||
case 2:
|
||||
eventType = "stop"
|
||||
case 3:
|
||||
eventType = "destroy"
|
||||
}
|
||||
return &docker.APIEvents{
|
||||
ID: s.generateID(),
|
||||
Status: eventType,
|
||||
From: "mybase:latest",
|
||||
Time: time.Now().Unix(),
|
||||
}
|
||||
}
|
||||
764
third_party/github.com/fsouza/go-dockerclient/testing/server_test.go
vendored
Normal file
764
third_party/github.com/fsouza/go-dockerclient/testing/server_test.go
vendored
Normal file
@@ -0,0 +1,764 @@
|
||||
// Copyright 2014 go-dockerclient authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package testing
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNewServer(t *testing.T) {
|
||||
server, err := NewServer("127.0.0.1:0", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer server.listener.Close()
|
||||
conn, err := net.Dial("tcp", server.listener.Addr().String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
conn.Close()
|
||||
}
|
||||
|
||||
func TestServerStop(t *testing.T) {
|
||||
server, err := NewServer("127.0.0.1:0", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
server.Stop()
|
||||
_, err = net.Dial("tcp", server.listener.Addr().String())
|
||||
if err == nil {
|
||||
t.Error("Unexpected <nil> error when dialing to stopped server")
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerStopNoListener(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.Stop()
|
||||
}
|
||||
|
||||
func TestServerURL(t *testing.T) {
|
||||
server, err := NewServer("127.0.0.1:0", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer server.Stop()
|
||||
url := server.URL()
|
||||
if expected := "http://" + server.listener.Addr().String() + "/"; url != expected {
|
||||
t.Errorf("DockerServer.URL(): Want %q. Got %q.", expected, url)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerURLNoListener(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
url := server.URL()
|
||||
if url != "" {
|
||||
t.Errorf("DockerServer.URL(): Expected empty URL on handler mode, got %q.", url)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleWithHook(t *testing.T) {
|
||||
var called bool
|
||||
server, _ := NewServer("127.0.0.1:0", func(*http.Request) { called = true })
|
||||
defer server.Stop()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("GET", "/containers/json?all=1", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if !called {
|
||||
t.Error("ServeHTTP did not call the hook function.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListContainers(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 2)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("GET", "/containers/json?all=1", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Errorf("ListContainers: wrong status. Want %d. Got %d.", http.StatusOK, recorder.Code)
|
||||
}
|
||||
expected := make([]docker.APIContainers, 2)
|
||||
for i, container := range server.containers {
|
||||
expected[i] = docker.APIContainers{
|
||||
ID: container.ID,
|
||||
Image: container.Image,
|
||||
Command: strings.Join(container.Config.Cmd, " "),
|
||||
Created: container.Created.Unix(),
|
||||
Status: container.State.String(),
|
||||
Ports: container.NetworkSettings.PortMappingAPI(),
|
||||
}
|
||||
}
|
||||
var got []docker.APIContainers
|
||||
err := json.NewDecoder(recorder.Body).Decode(&got)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, expected) {
|
||||
t.Errorf("ListContainers. Want %#v. Got %#v.", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListRunningContainers(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 2)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("GET", "/containers/json?all=0", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Errorf("ListRunningContainers: wrong status. Want %d. Got %d.", http.StatusOK, recorder.Code)
|
||||
}
|
||||
var got []docker.APIContainers
|
||||
err := json.NewDecoder(recorder.Body).Decode(&got)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(got) == 0 {
|
||||
t.Errorf("ListRunningContainers: Want 0. Got %d.", len(got))
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateContainer(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.imgIDs = map[string]string{"base": "a1234"}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
body := `{"Hostname":"", "User":"", "Memory":0, "MemorySwap":0, "AttachStdin":false, "AttachStdout":true, "AttachStderr":true,
|
||||
"PortSpecs":null, "Tty":false, "OpenStdin":false, "StdinOnce":false, "Env":null, "Cmd":["date"], "Image":"base", "Volumes":{}, "VolumesFrom":""}`
|
||||
request, _ := http.NewRequest("POST", "/containers/create", strings.NewReader(body))
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusCreated {
|
||||
t.Errorf("CreateContainer: wrong status. Want %d. Got %d.", http.StatusCreated, recorder.Code)
|
||||
}
|
||||
var returned docker.Container
|
||||
err := json.NewDecoder(recorder.Body).Decode(&returned)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stored := server.containers[0]
|
||||
if returned.ID != stored.ID {
|
||||
t.Errorf("CreateContainer: ID mismatch. Stored: %q. Returned: %q.", stored.ID, returned.ID)
|
||||
}
|
||||
if stored.State.Running {
|
||||
t.Errorf("CreateContainer should not set container to running state.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateContainerInvalidBody(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("POST", "/containers/create", strings.NewReader("whaaaaaat---"))
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusBadRequest {
|
||||
t.Errorf("CreateContainer: wrong status. Want %d. Got %d.", http.StatusBadRequest, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateContainerImageNotFound(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
body := `{"Hostname":"", "User":"", "Memory":0, "MemorySwap":0, "AttachStdin":false, "AttachStdout":true, "AttachStderr":true,
|
||||
"PortSpecs":null, "Tty":false, "OpenStdin":false, "StdinOnce":false, "Env":null, "Cmd":["date"],
|
||||
"Image":"base", "Volumes":{}, "VolumesFrom":""}`
|
||||
request, _ := http.NewRequest("POST", "/containers/create", strings.NewReader(body))
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNotFound {
|
||||
t.Errorf("CreateContainer: wrong status. Want %d. Got %d.", http.StatusNotFound, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitContainer(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 2)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("POST", "/commit?container="+server.containers[0].ID, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Errorf("CommitContainer: wrong status. Want %d. Got %d.", http.StatusOK, recorder.Code)
|
||||
}
|
||||
expected := fmt.Sprintf(`{"ID":"%s"}`, server.images[0].ID)
|
||||
if got := recorder.Body.String(); got != expected {
|
||||
t.Errorf("CommitContainer: wrong response body. Want %q. Got %q.", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitContainerComplete(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.imgIDs = make(map[string]string)
|
||||
addContainers(&server, 2)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
queryString := "container=" + server.containers[0].ID + "&repo=tsuru/python&m=saving&author=developers"
|
||||
queryString += `&run={"Cmd": ["cat", "/world"],"PortSpecs":["22"]}`
|
||||
request, _ := http.NewRequest("POST", "/commit?"+queryString, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
image := server.images[0]
|
||||
if image.Parent != server.containers[0].Image {
|
||||
t.Errorf("CommitContainer: wrong parent image. Want %q. Got %q.", server.containers[0].Image, image.Parent)
|
||||
}
|
||||
if image.Container != server.containers[0].ID {
|
||||
t.Errorf("CommitContainer: wrong container. Want %q. Got %q.", server.containers[0].ID, image.Container)
|
||||
}
|
||||
message := "saving"
|
||||
if image.Comment != message {
|
||||
t.Errorf("CommitContainer: wrong comment (commit message). Want %q. Got %q.", message, image.Comment)
|
||||
}
|
||||
author := "developers"
|
||||
if image.Author != author {
|
||||
t.Errorf("CommitContainer: wrong author. Want %q. Got %q.", author, image.Author)
|
||||
}
|
||||
if id := server.imgIDs["tsuru/python"]; id != image.ID {
|
||||
t.Errorf("CommitContainer: wrong ID saved for repository. Want %q. Got %q.", image.ID, id)
|
||||
}
|
||||
portSpecs := []string{"22"}
|
||||
if !reflect.DeepEqual(image.Config.PortSpecs, portSpecs) {
|
||||
t.Errorf("CommitContainer: wrong port spec in config. Want %#v. Got %#v.", portSpecs, image.Config.PortSpecs)
|
||||
}
|
||||
cmd := []string{"cat", "/world"}
|
||||
if !reflect.DeepEqual(image.Config.Cmd, cmd) {
|
||||
t.Errorf("CommitContainer: wrong cmd in config. Want %#v. Got %#v.", cmd, image.Config.Cmd)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitContainerInvalidRun(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 1)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("POST", "/commit?container="+server.containers[0].ID+"&run=abc---", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusBadRequest {
|
||||
t.Errorf("CommitContainer. Wrong status. Want %d. Got %d.", http.StatusBadRequest, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitContainerNotFound(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("POST", "/commit?container=abc123", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNotFound {
|
||||
t.Errorf("CommitContainer. Wrong status. Want %d. Got %d.", http.StatusNotFound, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInspectContainer(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 2)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/containers/%s/json", server.containers[0].ID)
|
||||
request, _ := http.NewRequest("GET", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Errorf("InspectContainer: wrong status. Want %d. Got %d.", http.StatusOK, recorder.Code)
|
||||
}
|
||||
expected := server.containers[0]
|
||||
var got docker.Container
|
||||
err := json.NewDecoder(recorder.Body).Decode(&got)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(got.Config, expected.Config) {
|
||||
t.Errorf("InspectContainer: wrong value. Want %#v. Got %#v.", *expected, got)
|
||||
}
|
||||
if !reflect.DeepEqual(got.NetworkSettings, expected.NetworkSettings) {
|
||||
t.Errorf("InspectContainer: wrong value. Want %#v. Got %#v.", *expected, got)
|
||||
}
|
||||
got.State.StartedAt = expected.State.StartedAt
|
||||
got.State.FinishedAt = expected.State.FinishedAt
|
||||
got.Config = expected.Config
|
||||
got.Created = expected.Created
|
||||
got.NetworkSettings = expected.NetworkSettings
|
||||
if !reflect.DeepEqual(got, *expected) {
|
||||
t.Errorf("InspectContainer: wrong value. Want %#v. Got %#v.", *expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInspectContainerNotFound(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("GET", "/containers/abc123/json", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNotFound {
|
||||
t.Errorf("InspectContainer: wrong status code. Want %d. Got %d.", http.StatusNotFound, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStartContainer(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 1)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/containers/%s/start", server.containers[0].ID)
|
||||
request, _ := http.NewRequest("POST", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Errorf("StartContainer: wrong status code. Want %d. Got %d.", http.StatusOK, recorder.Code)
|
||||
}
|
||||
if !server.containers[0].State.Running {
|
||||
t.Error("StartContainer: did not set the container to running state")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStartContainerNotFound(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := "/containers/abc123/start"
|
||||
request, _ := http.NewRequest("POST", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNotFound {
|
||||
t.Errorf("StartContainer: wrong status code. Want %d. Got %d.", http.StatusNotFound, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStartContainerAlreadyRunning(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 1)
|
||||
server.containers[0].State.Running = true
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/containers/%s/start", server.containers[0].ID)
|
||||
request, _ := http.NewRequest("POST", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusBadRequest {
|
||||
t.Errorf("StartContainer: wrong status code. Want %d. Got %d.", http.StatusBadRequest, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStopContainer(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 1)
|
||||
server.containers[0].State.Running = true
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/containers/%s/stop", server.containers[0].ID)
|
||||
request, _ := http.NewRequest("POST", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNoContent {
|
||||
t.Errorf("StopContainer: wrong status code. Want %d. Got %d.", http.StatusNoContent, recorder.Code)
|
||||
}
|
||||
if server.containers[0].State.Running {
|
||||
t.Error("StopContainer: did not stop the container")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStopContainerNotFound(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := "/containers/abc123/stop"
|
||||
request, _ := http.NewRequest("POST", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNotFound {
|
||||
t.Errorf("StopContainer: wrong status code. Want %d. Got %d.", http.StatusNotFound, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStopContainerNotRunning(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 1)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/containers/%s/stop", server.containers[0].ID)
|
||||
request, _ := http.NewRequest("POST", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusBadRequest {
|
||||
t.Errorf("StopContainer: wrong status code. Want %d. Got %d.", http.StatusBadRequest, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitContainer(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 1)
|
||||
server.containers[0].State.Running = true
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/containers/%s/wait", server.containers[0].ID)
|
||||
request, _ := http.NewRequest("POST", path, nil)
|
||||
go func() {
|
||||
server.cMut.Lock()
|
||||
server.containers[0].State.Running = false
|
||||
server.cMut.Unlock()
|
||||
}()
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Errorf("WaitContainer: wrong status. Want %d. Got %d.", http.StatusOK, recorder.Code)
|
||||
}
|
||||
expected := `{"StatusCode":0}`
|
||||
if body := recorder.Body.String(); body != expected {
|
||||
t.Errorf("WaitContainer: wrong body. Want %q. Got %q.", expected, body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitContainerNotFound(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := "/containers/abc123/wait"
|
||||
request, _ := http.NewRequest("POST", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNotFound {
|
||||
t.Errorf("WaitContainer: wrong status code. Want %d. Got %d.", http.StatusNotFound, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttachContainer(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 1)
|
||||
server.containers[0].State.Running = true
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/containers/%s/attach?logs=1", server.containers[0].ID)
|
||||
request, _ := http.NewRequest("POST", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
lines := []string{
|
||||
fmt.Sprintf("\x01\x00\x00\x00\x03\x00\x00\x00Container %q is running", server.containers[0].ID),
|
||||
"What happened?",
|
||||
"Something happened",
|
||||
}
|
||||
expected := strings.Join(lines, "\n") + "\n"
|
||||
if body := recorder.Body.String(); body == expected {
|
||||
t.Errorf("AttachContainer: wrong body. Want %q. Got %q.", expected, body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttachContainerNotFound(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := "/containers/abc123/attach?logs=1"
|
||||
request, _ := http.NewRequest("POST", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNotFound {
|
||||
t.Errorf("AttachContainer: wrong status. Want %d. Got %d.", http.StatusNotFound, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveContainer(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 1)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/containers/%s", server.containers[0].ID)
|
||||
request, _ := http.NewRequest("DELETE", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNoContent {
|
||||
t.Errorf("RemoveContainer: wrong status. Want %d. Got %d.", http.StatusNoContent, recorder.Code)
|
||||
}
|
||||
if len(server.containers) > 0 {
|
||||
t.Error("RemoveContainer: did not remove the container.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveContainerNotFound(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/containers/abc123")
|
||||
request, _ := http.NewRequest("DELETE", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNotFound {
|
||||
t.Errorf("RemoveContainer: wrong status. Want %d. Got %d.", http.StatusNotFound, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveContainerRunning(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addContainers(&server, 1)
|
||||
server.containers[0].State.Running = true
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/containers/%s", server.containers[0].ID)
|
||||
request, _ := http.NewRequest("DELETE", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusInternalServerError {
|
||||
t.Errorf("RemoveContainer: wrong status. Want %d. Got %d.", http.StatusInternalServerError, recorder.Code)
|
||||
}
|
||||
if len(server.containers) < 1 {
|
||||
t.Error("RemoveContainer: should not remove the container.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPullImage(t *testing.T) {
|
||||
server := DockerServer{imgIDs: make(map[string]string)}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("POST", "/images/create?fromImage=base", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Errorf("PullImage: wrong status. Want %d. Got %d.", http.StatusOK, recorder.Code)
|
||||
}
|
||||
if len(server.images) != 1 {
|
||||
t.Errorf("PullImage: Want 1 image. Got %d.", len(server.images))
|
||||
}
|
||||
if _, ok := server.imgIDs["base"]; !ok {
|
||||
t.Error("PullImage: Repository should not be empty.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPushImage(t *testing.T) {
|
||||
server := DockerServer{imgIDs: map[string]string{"tsuru/python": "a123"}}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("POST", "/images/tsuru/python/push", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Errorf("PushImage: wrong status. Want %d. Got %d.", http.StatusOK, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPushImageNotFound(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("POST", "/images/tsuru/python/push", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNotFound {
|
||||
t.Errorf("PushImage: wrong status. Want %d. Got %d.", http.StatusNotFound, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func addContainers(server *DockerServer, n int) {
|
||||
server.cMut.Lock()
|
||||
defer server.cMut.Unlock()
|
||||
for i := 0; i < n; i++ {
|
||||
date := time.Now().Add(time.Duration((rand.Int() % (i + 1))) * time.Hour)
|
||||
container := docker.Container{
|
||||
ID: fmt.Sprintf("%x", rand.Int()%10000),
|
||||
Created: date,
|
||||
Path: "ls",
|
||||
Args: []string{"-la", ".."},
|
||||
Config: &docker.Config{
|
||||
Hostname: fmt.Sprintf("docker-%d", i),
|
||||
AttachStdout: true,
|
||||
AttachStderr: true,
|
||||
Env: []string{"ME=you", fmt.Sprintf("NUMBER=%d", i)},
|
||||
Cmd: []string{"ls", "-la", ".."},
|
||||
Image: "base",
|
||||
},
|
||||
State: docker.State{
|
||||
Running: false,
|
||||
Pid: 400 + i,
|
||||
ExitCode: 0,
|
||||
StartedAt: date,
|
||||
},
|
||||
Image: "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
|
||||
NetworkSettings: &docker.NetworkSettings{
|
||||
IPAddress: fmt.Sprintf("10.10.10.%d", i+2),
|
||||
IPPrefixLen: 24,
|
||||
Gateway: "10.10.10.1",
|
||||
Bridge: "docker0",
|
||||
PortMapping: map[string]docker.PortMapping{
|
||||
"Tcp": {"8888": fmt.Sprintf("%d", 49600+i)},
|
||||
},
|
||||
},
|
||||
ResolvConfPath: "/etc/resolv.conf",
|
||||
}
|
||||
server.containers = append(server.containers, &container)
|
||||
}
|
||||
}
|
||||
|
||||
func addImages(server *DockerServer, n int, repo bool) {
|
||||
server.iMut.Lock()
|
||||
defer server.iMut.Unlock()
|
||||
if server.imgIDs == nil {
|
||||
server.imgIDs = make(map[string]string)
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
date := time.Now().Add(time.Duration((rand.Int() % (i + 1))) * time.Hour)
|
||||
image := docker.Image{
|
||||
ID: fmt.Sprintf("%x", rand.Int()%10000),
|
||||
Created: date,
|
||||
}
|
||||
server.images = append(server.images, image)
|
||||
if repo {
|
||||
repo := "docker/python-" + image.ID
|
||||
server.imgIDs[repo] = image.ID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestListImages(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addImages(&server, 2, false)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("GET", "/images/json?all=1", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Errorf("ListImages: wrong status. Want %d. Got %d.", http.StatusOK, recorder.Code)
|
||||
}
|
||||
expected := make([]docker.APIImages, 2)
|
||||
for i, image := range server.images {
|
||||
expected[i] = docker.APIImages{
|
||||
ID: image.ID,
|
||||
Created: image.Created.Unix(),
|
||||
}
|
||||
}
|
||||
var got []docker.APIImages
|
||||
err := json.NewDecoder(recorder.Body).Decode(&got)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, expected) {
|
||||
t.Errorf("ListImages. Want %#v. Got %#v.", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveImage(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addImages(&server, 1, false)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/images/%s", server.images[0].ID)
|
||||
request, _ := http.NewRequest("DELETE", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNoContent {
|
||||
t.Errorf("RemoveImage: wrong status. Want %d. Got %d.", http.StatusNoContent, recorder.Code)
|
||||
}
|
||||
if len(server.images) > 0 {
|
||||
t.Error("RemoveImage: did not remove the image.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveImageByName(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addImages(&server, 1, true)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := "/images/docker/python-" + server.images[0].ID
|
||||
request, _ := http.NewRequest("DELETE", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNoContent {
|
||||
t.Errorf("RemoveImage: wrong status. Want %d. Got %d.", http.StatusNoContent, recorder.Code)
|
||||
}
|
||||
if len(server.images) > 0 {
|
||||
t.Error("RemoveImage: did not remove the image.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrepareFailure(t *testing.T) {
|
||||
server := DockerServer{failures: make(map[string]FailureSpec)}
|
||||
server.buildMuxer()
|
||||
errorId := "my_error"
|
||||
failure := FailureSpec{UrlRegex: "containers/json"}
|
||||
server.PrepareFailure(errorId, failure)
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("GET", "/containers/json?all=1", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusBadRequest {
|
||||
t.Errorf("PrepareFailure: wrong status. Want %d. Got %d.", http.StatusBadRequest, recorder.Code)
|
||||
}
|
||||
if recorder.Body.String() != errorId+"\n" {
|
||||
t.Errorf("PrepareFailure: wrong message. Want %s. Got %s.", errorId, recorder.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrepareFailureUsingContainerPath(t *testing.T) {
|
||||
server := DockerServer{failures: make(map[string]FailureSpec)}
|
||||
addContainers(&server, 1)
|
||||
server.buildMuxer()
|
||||
errorId := "my_path_error"
|
||||
failure := FailureSpec{UrlRegex: "containers/.*?/start", ContainerPath: "ls"}
|
||||
server.PrepareFailure(errorId, failure)
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/containers/%s/start", server.containers[0].ID)
|
||||
request, _ := http.NewRequest("POST", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusBadRequest {
|
||||
t.Errorf("TestPrepareFailureUsingContainerPath: wrong status. Want %d. Got %d.", http.StatusBadRequest, recorder.Code)
|
||||
}
|
||||
if recorder.Body.String() != errorId+"\n" {
|
||||
t.Errorf("TestPrepareFailureUsingContainerPath: wrong message. Want %s. Got %s.", errorId, recorder.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrepareFailureUsingContainerPathWithWrongPath(t *testing.T) {
|
||||
server := DockerServer{failures: make(map[string]FailureSpec)}
|
||||
addContainers(&server, 1)
|
||||
server.buildMuxer()
|
||||
errorId := "my_path_error"
|
||||
failure := FailureSpec{UrlRegex: "containers/.*?/start", ContainerPath: "xxx"}
|
||||
server.PrepareFailure(errorId, failure)
|
||||
recorder := httptest.NewRecorder()
|
||||
path := fmt.Sprintf("/containers/%s/start", server.containers[0].ID)
|
||||
request, _ := http.NewRequest("POST", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Errorf("StartContainer: wrong status code. Want %d. Got %d.", http.StatusOK, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveFailure(t *testing.T) {
|
||||
server := DockerServer{failures: make(map[string]FailureSpec)}
|
||||
server.buildMuxer()
|
||||
errorId := "my_error"
|
||||
failure := FailureSpec{UrlRegex: "containers/json"}
|
||||
server.PrepareFailure(errorId, failure)
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("GET", "/containers/json?all=1", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusBadRequest {
|
||||
t.Errorf("PrepareFailure: wrong status. Want %d. Got %d.", http.StatusBadRequest, recorder.Code)
|
||||
}
|
||||
server.ResetFailure(errorId)
|
||||
recorder = httptest.NewRecorder()
|
||||
request, _ = http.NewRequest("GET", "/containers/json?all=1", nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Errorf("RemoveFailure: wrong status. Want %d. Got %d.", http.StatusOK, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildImageWithContentTypeTar(t *testing.T) {
|
||||
server := DockerServer{imgIDs: make(map[string]string)}
|
||||
imageName := "teste"
|
||||
recorder := httptest.NewRecorder()
|
||||
tarFile, err := os.Open("data/dockerfile.tar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer tarFile.Close()
|
||||
request, _ := http.NewRequest("POST", "/build?t=teste", tarFile)
|
||||
request.Header.Add("Content-Type", "application/tar")
|
||||
server.buildImage(recorder, request)
|
||||
if recorder.Body.String() == "miss Dockerfile" {
|
||||
t.Errorf("BuildImage: miss Dockerfile")
|
||||
return
|
||||
}
|
||||
if _, ok := server.imgIDs[imageName]; ok == false {
|
||||
t.Errorf("BuildImage: image %s not builded", imageName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildImageWithRemoteDockerfile(t *testing.T) {
|
||||
server := DockerServer{imgIDs: make(map[string]string)}
|
||||
imageName := "teste"
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("POST", "/build?t=teste&remote=http://localhost/Dockerfile", nil)
|
||||
server.buildImage(recorder, request)
|
||||
if _, ok := server.imgIDs[imageName]; ok == false {
|
||||
t.Errorf("BuildImage: image %s not builded", imageName)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user