Initial commit

This commit is contained in:
Ria Bhatia
2017-12-04 13:32:57 -06:00
committed by Erik St. Martin
commit 0075e5b0f3
9056 changed files with 2523100 additions and 0 deletions

View File

@@ -0,0 +1,257 @@
package main
import (
"archive/tar"
"bytes"
"net/http"
"github.com/docker/docker/pkg/integration/checker"
"github.com/go-check/check"
)
func (s *DockerSuite) TestBuildApiDockerfilePath(c *check.C) {
// Test to make sure we stop people from trying to leave the
// build context when specifying the path to the dockerfile
buffer := new(bytes.Buffer)
tw := tar.NewWriter(buffer)
defer tw.Close()
dockerfile := []byte("FROM busybox")
err := tw.WriteHeader(&tar.Header{
Name: "Dockerfile",
Size: int64(len(dockerfile)),
})
//failed to write tar file header
c.Assert(err, checker.IsNil)
_, err = tw.Write(dockerfile)
// failed to write tar file content
c.Assert(err, checker.IsNil)
// failed to close tar archive
c.Assert(tw.Close(), checker.IsNil)
res, body, err := sockRequestRaw("POST", "/build?dockerfile=../Dockerfile", buffer, "application/x-tar")
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
out, err := readBody(body)
c.Assert(err, checker.IsNil)
// Didn't complain about leaving build context
c.Assert(string(out), checker.Contains, "Forbidden path outside the build context")
}
func (s *DockerSuite) TestBuildApiDockerFileRemote(c *check.C) {
testRequires(c, NotUserNamespace)
testRequires(c, DaemonIsLinux)
server, err := fakeStorage(map[string]string{
"testD": `FROM busybox
COPY * /tmp/
RUN find / -name ba*
RUN find /tmp/`,
})
c.Assert(err, checker.IsNil)
defer server.Close()
res, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+server.URL()+"/testD", nil, "application/json")
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
buf, err := readBody(body)
c.Assert(err, checker.IsNil)
// Make sure Dockerfile exists.
// Make sure 'baz' doesn't exist ANYWHERE despite being mentioned in the URL
out := string(buf)
c.Assert(out, checker.Contains, "/tmp/Dockerfile")
c.Assert(out, checker.Not(checker.Contains), "baz")
}
func (s *DockerSuite) TestBuildApiRemoteTarballContext(c *check.C) {
testRequires(c, DaemonIsLinux)
buffer := new(bytes.Buffer)
tw := tar.NewWriter(buffer)
defer tw.Close()
dockerfile := []byte("FROM busybox")
err := tw.WriteHeader(&tar.Header{
Name: "Dockerfile",
Size: int64(len(dockerfile)),
})
// failed to write tar file header
c.Assert(err, checker.IsNil)
_, err = tw.Write(dockerfile)
// failed to write tar file content
c.Assert(err, checker.IsNil)
// failed to close tar archive
c.Assert(tw.Close(), checker.IsNil)
server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
"testT.tar": buffer,
})
c.Assert(err, checker.IsNil)
defer server.Close()
res, b, err := sockRequestRaw("POST", "/build?remote="+server.URL()+"/testT.tar", nil, "application/tar")
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
b.Close()
}
func (s *DockerSuite) TestBuildApiRemoteTarballContextWithCustomDockerfile(c *check.C) {
testRequires(c, DaemonIsLinux)
buffer := new(bytes.Buffer)
tw := tar.NewWriter(buffer)
defer tw.Close()
dockerfile := []byte(`FROM busybox
RUN echo 'wrong'`)
err := tw.WriteHeader(&tar.Header{
Name: "Dockerfile",
Size: int64(len(dockerfile)),
})
// failed to write tar file header
c.Assert(err, checker.IsNil)
_, err = tw.Write(dockerfile)
// failed to write tar file content
c.Assert(err, checker.IsNil)
custom := []byte(`FROM busybox
RUN echo 'right'
`)
err = tw.WriteHeader(&tar.Header{
Name: "custom",
Size: int64(len(custom)),
})
// failed to write tar file header
c.Assert(err, checker.IsNil)
_, err = tw.Write(custom)
// failed to write tar file content
c.Assert(err, checker.IsNil)
// failed to close tar archive
c.Assert(tw.Close(), checker.IsNil)
server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
"testT.tar": buffer,
})
c.Assert(err, checker.IsNil)
defer server.Close()
url := "/build?dockerfile=custom&remote=" + server.URL() + "/testT.tar"
res, body, err := sockRequestRaw("POST", url, nil, "application/tar")
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
defer body.Close()
content, err := readBody(body)
c.Assert(err, checker.IsNil)
// Build used the wrong dockerfile.
c.Assert(string(content), checker.Not(checker.Contains), "wrong")
}
func (s *DockerSuite) TestBuildApiLowerDockerfile(c *check.C) {
testRequires(c, DaemonIsLinux)
git, err := newFakeGit("repo", map[string]string{
"dockerfile": `FROM busybox
RUN echo from dockerfile`,
}, false)
c.Assert(err, checker.IsNil)
defer git.Close()
res, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
buf, err := readBody(body)
c.Assert(err, checker.IsNil)
out := string(buf)
c.Assert(out, checker.Contains, "from dockerfile")
}
func (s *DockerSuite) TestBuildApiBuildGitWithF(c *check.C) {
testRequires(c, DaemonIsLinux)
git, err := newFakeGit("repo", map[string]string{
"baz": `FROM busybox
RUN echo from baz`,
"Dockerfile": `FROM busybox
RUN echo from Dockerfile`,
}, false)
c.Assert(err, checker.IsNil)
defer git.Close()
// Make sure it tries to 'dockerfile' query param value
res, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+git.RepoURL, nil, "application/json")
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
buf, err := readBody(body)
c.Assert(err, checker.IsNil)
out := string(buf)
c.Assert(out, checker.Contains, "from baz")
}
func (s *DockerSuite) TestBuildApiDoubleDockerfile(c *check.C) {
testRequires(c, UnixCli) // dockerfile overwrites Dockerfile on Windows
git, err := newFakeGit("repo", map[string]string{
"Dockerfile": `FROM busybox
RUN echo from Dockerfile`,
"dockerfile": `FROM busybox
RUN echo from dockerfile`,
}, false)
c.Assert(err, checker.IsNil)
defer git.Close()
// Make sure it tries to 'dockerfile' query param value
res, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
buf, err := readBody(body)
c.Assert(err, checker.IsNil)
out := string(buf)
c.Assert(out, checker.Contains, "from Dockerfile")
}
func (s *DockerSuite) TestBuildApiDockerfileSymlink(c *check.C) {
// Test to make sure we stop people from trying to leave the
// build context when specifying a symlink as the path to the dockerfile
buffer := new(bytes.Buffer)
tw := tar.NewWriter(buffer)
defer tw.Close()
err := tw.WriteHeader(&tar.Header{
Name: "Dockerfile",
Typeflag: tar.TypeSymlink,
Linkname: "/etc/passwd",
})
// failed to write tar file header
c.Assert(err, checker.IsNil)
// failed to close tar archive
c.Assert(tw.Close(), checker.IsNil)
res, body, err := sockRequestRaw("POST", "/build", buffer, "application/x-tar")
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
out, err := readBody(body)
c.Assert(err, checker.IsNil)
// The reason the error is "Cannot locate specified Dockerfile" is because
// in the builder, the symlink is resolved within the context, therefore
// Dockerfile -> /etc/passwd becomes etc/passwd from the context which is
// a nonexistent file.
c.Assert(string(out), checker.Contains, "Cannot locate specified Dockerfile: Dockerfile", check.Commentf("Didn't complain about leaving build context"))
}

View File

@@ -0,0 +1,73 @@
package main
import (
"encoding/json"
"io"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/docker/docker/pkg/integration/checker"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/go-check/check"
)
func (s *DockerSuite) TestEventsApiEmptyOutput(c *check.C) {
type apiResp struct {
resp *http.Response
err error
}
chResp := make(chan *apiResp)
go func() {
resp, body, err := sockRequestRaw("GET", "/events", nil, "")
body.Close()
chResp <- &apiResp{resp, err}
}()
select {
case r := <-chResp:
c.Assert(r.err, checker.IsNil)
c.Assert(r.resp.StatusCode, checker.Equals, http.StatusOK)
case <-time.After(3 * time.Second):
c.Fatal("timeout waiting for events api to respond, should have responded immediately")
}
}
func (s *DockerSuite) TestEventsApiBackwardsCompatible(c *check.C) {
since := daemonTime(c).Unix()
ts := strconv.FormatInt(since, 10)
out, _ := dockerCmd(c, "run", "--name=foo", "-d", "busybox", "top")
containerID := strings.TrimSpace(out)
c.Assert(waitRun(containerID), checker.IsNil)
q := url.Values{}
q.Set("since", ts)
_, body, err := sockRequestRaw("GET", "/events?"+q.Encode(), nil, "")
c.Assert(err, checker.IsNil)
defer body.Close()
dec := json.NewDecoder(body)
var containerCreateEvent *jsonmessage.JSONMessage
for {
var event jsonmessage.JSONMessage
if err := dec.Decode(&event); err != nil {
if err == io.EOF {
break
}
c.Fatal(err)
}
if event.Status == "create" && event.ID == containerID {
containerCreateEvent = &event
break
}
}
c.Assert(containerCreateEvent, checker.Not(checker.IsNil))
c.Assert(containerCreateEvent.Status, checker.Equals, "create")
c.Assert(containerCreateEvent.ID, checker.Equals, containerID)
c.Assert(containerCreateEvent.From, checker.Equals, "busybox")
}

View File

@@ -0,0 +1,335 @@
package main
import (
"encoding/json"
"fmt"
"net"
"net/http"
"net/url"
"strings"
"github.com/docker/docker/pkg/integration/checker"
"github.com/docker/engine-api/types"
"github.com/docker/engine-api/types/filters"
"github.com/docker/engine-api/types/network"
"github.com/go-check/check"
)
func (s *DockerSuite) TestApiNetworkGetDefaults(c *check.C) {
testRequires(c, DaemonIsLinux)
// By default docker daemon creates 3 networks. check if they are present
defaults := []string{"bridge", "host", "none"}
for _, nn := range defaults {
c.Assert(isNetworkAvailable(c, nn), checker.Equals, true)
}
}
func (s *DockerSuite) TestApiNetworkCreateDelete(c *check.C) {
testRequires(c, DaemonIsLinux)
// Create a network
name := "testnetwork"
config := types.NetworkCreate{
Name: name,
CheckDuplicate: true,
}
id := createNetwork(c, config, true)
c.Assert(isNetworkAvailable(c, name), checker.Equals, true)
// delete the network and make sure it is deleted
deleteNetwork(c, id, true)
c.Assert(isNetworkAvailable(c, name), checker.Equals, false)
}
func (s *DockerSuite) TestApiNetworkCreateCheckDuplicate(c *check.C) {
testRequires(c, DaemonIsLinux)
name := "testcheckduplicate"
configOnCheck := types.NetworkCreate{
Name: name,
CheckDuplicate: true,
}
configNotCheck := types.NetworkCreate{
Name: name,
CheckDuplicate: false,
}
// Creating a new network first
createNetwork(c, configOnCheck, true)
c.Assert(isNetworkAvailable(c, name), checker.Equals, true)
// Creating another network with same name and CheckDuplicate must fail
createNetwork(c, configOnCheck, false)
// Creating another network with same name and not CheckDuplicate must succeed
createNetwork(c, configNotCheck, true)
}
func (s *DockerSuite) TestApiNetworkFilter(c *check.C) {
testRequires(c, DaemonIsLinux)
nr := getNetworkResource(c, getNetworkIDByName(c, "bridge"))
c.Assert(nr.Name, checker.Equals, "bridge")
}
func (s *DockerSuite) TestApiNetworkInspect(c *check.C) {
testRequires(c, DaemonIsLinux)
// Inspect default bridge network
nr := getNetworkResource(c, "bridge")
c.Assert(nr.Name, checker.Equals, "bridge")
// run a container and attach it to the default bridge network
out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
containerID := strings.TrimSpace(out)
containerIP := findContainerIP(c, "test", "bridge")
// inspect default bridge network again and make sure the container is connected
nr = getNetworkResource(c, nr.ID)
c.Assert(nr.Driver, checker.Equals, "bridge")
c.Assert(nr.Scope, checker.Equals, "local")
c.Assert(nr.IPAM.Driver, checker.Equals, "default")
c.Assert(len(nr.Containers), checker.Equals, 1)
c.Assert(nr.Containers[containerID], checker.NotNil)
ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
c.Assert(err, checker.IsNil)
c.Assert(ip.String(), checker.Equals, containerIP)
// IPAM configuration inspect
ipam := network.IPAM{
Driver: "default",
Config: []network.IPAMConfig{{Subnet: "172.28.0.0/16", IPRange: "172.28.5.0/24", Gateway: "172.28.5.254"}},
}
config := types.NetworkCreate{
Name: "br0",
Driver: "bridge",
IPAM: ipam,
Options: map[string]string{"foo": "bar", "opts": "dopts"},
}
id0 := createNetwork(c, config, true)
c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, true)
nr = getNetworkResource(c, id0)
c.Assert(len(nr.IPAM.Config), checker.Equals, 1)
c.Assert(nr.IPAM.Config[0].Subnet, checker.Equals, "172.28.0.0/16")
c.Assert(nr.IPAM.Config[0].IPRange, checker.Equals, "172.28.5.0/24")
c.Assert(nr.IPAM.Config[0].Gateway, checker.Equals, "172.28.5.254")
c.Assert(nr.Options["foo"], checker.Equals, "bar")
c.Assert(nr.Options["opts"], checker.Equals, "dopts")
// delete the network and make sure it is deleted
deleteNetwork(c, id0, true)
c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, false)
}
func (s *DockerSuite) TestApiNetworkConnectDisconnect(c *check.C) {
testRequires(c, DaemonIsLinux)
// Create test network
name := "testnetwork"
config := types.NetworkCreate{
Name: name,
}
id := createNetwork(c, config, true)
nr := getNetworkResource(c, id)
c.Assert(nr.Name, checker.Equals, name)
c.Assert(nr.ID, checker.Equals, id)
c.Assert(len(nr.Containers), checker.Equals, 0)
// run a container
out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
containerID := strings.TrimSpace(out)
// connect the container to the test network
connectNetwork(c, nr.ID, containerID)
// inspect the network to make sure container is connected
nr = getNetworkResource(c, nr.ID)
c.Assert(len(nr.Containers), checker.Equals, 1)
c.Assert(nr.Containers[containerID], checker.NotNil)
// check if container IP matches network inspect
ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
c.Assert(err, checker.IsNil)
containerIP := findContainerIP(c, "test", "testnetwork")
c.Assert(ip.String(), checker.Equals, containerIP)
// disconnect container from the network
disconnectNetwork(c, nr.ID, containerID)
nr = getNetworkResource(c, nr.ID)
c.Assert(nr.Name, checker.Equals, name)
c.Assert(len(nr.Containers), checker.Equals, 0)
// delete the network
deleteNetwork(c, nr.ID, true)
}
func (s *DockerSuite) TestApiNetworkIpamMultipleBridgeNetworks(c *check.C) {
testRequires(c, DaemonIsLinux)
// test0 bridge network
ipam0 := network.IPAM{
Driver: "default",
Config: []network.IPAMConfig{{Subnet: "192.178.0.0/16", IPRange: "192.178.128.0/17", Gateway: "192.178.138.100"}},
}
config0 := types.NetworkCreate{
Name: "test0",
Driver: "bridge",
IPAM: ipam0,
}
id0 := createNetwork(c, config0, true)
c.Assert(isNetworkAvailable(c, "test0"), checker.Equals, true)
ipam1 := network.IPAM{
Driver: "default",
Config: []network.IPAMConfig{{Subnet: "192.178.128.0/17", Gateway: "192.178.128.1"}},
}
// test1 bridge network overlaps with test0
config1 := types.NetworkCreate{
Name: "test1",
Driver: "bridge",
IPAM: ipam1,
}
createNetwork(c, config1, false)
c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, false)
ipam2 := network.IPAM{
Driver: "default",
Config: []network.IPAMConfig{{Subnet: "192.169.0.0/16", Gateway: "192.169.100.100"}},
}
// test2 bridge network does not overlap
config2 := types.NetworkCreate{
Name: "test2",
Driver: "bridge",
IPAM: ipam2,
}
createNetwork(c, config2, true)
c.Assert(isNetworkAvailable(c, "test2"), checker.Equals, true)
// remove test0 and retry to create test1
deleteNetwork(c, id0, true)
createNetwork(c, config1, true)
c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, true)
// for networks w/o ipam specified, docker will choose proper non-overlapping subnets
createNetwork(c, types.NetworkCreate{Name: "test3"}, true)
c.Assert(isNetworkAvailable(c, "test3"), checker.Equals, true)
createNetwork(c, types.NetworkCreate{Name: "test4"}, true)
c.Assert(isNetworkAvailable(c, "test4"), checker.Equals, true)
createNetwork(c, types.NetworkCreate{Name: "test5"}, true)
c.Assert(isNetworkAvailable(c, "test5"), checker.Equals, true)
for i := 1; i < 6; i++ {
deleteNetwork(c, fmt.Sprintf("test%d", i), true)
}
}
func (s *DockerSuite) TestApiCreateDeletePredefinedNetworks(c *check.C) {
testRequires(c, DaemonIsLinux)
createDeletePredefinedNetwork(c, "bridge")
createDeletePredefinedNetwork(c, "none")
createDeletePredefinedNetwork(c, "host")
}
func createDeletePredefinedNetwork(c *check.C, name string) {
// Create pre-defined network
config := types.NetworkCreate{
Name: name,
CheckDuplicate: true,
}
shouldSucceed := false
createNetwork(c, config, shouldSucceed)
deleteNetwork(c, name, shouldSucceed)
}
func isNetworkAvailable(c *check.C, name string) bool {
status, body, err := sockRequest("GET", "/networks", nil)
c.Assert(status, checker.Equals, http.StatusOK)
c.Assert(err, checker.IsNil)
nJSON := []types.NetworkResource{}
err = json.Unmarshal(body, &nJSON)
c.Assert(err, checker.IsNil)
for _, n := range nJSON {
if n.Name == name {
return true
}
}
return false
}
func getNetworkIDByName(c *check.C, name string) string {
var (
v = url.Values{}
filterArgs = filters.NewArgs()
)
filterArgs.Add("name", name)
filterJSON, err := filters.ToParam(filterArgs)
c.Assert(err, checker.IsNil)
v.Set("filters", filterJSON)
status, body, err := sockRequest("GET", "/networks?"+v.Encode(), nil)
c.Assert(status, checker.Equals, http.StatusOK)
c.Assert(err, checker.IsNil)
nJSON := []types.NetworkResource{}
err = json.Unmarshal(body, &nJSON)
c.Assert(err, checker.IsNil)
c.Assert(len(nJSON), checker.Equals, 1)
return nJSON[0].ID
}
func getNetworkResource(c *check.C, id string) *types.NetworkResource {
_, obj, err := sockRequest("GET", "/networks/"+id, nil)
c.Assert(err, checker.IsNil)
nr := types.NetworkResource{}
err = json.Unmarshal(obj, &nr)
c.Assert(err, checker.IsNil)
return &nr
}
func createNetwork(c *check.C, config types.NetworkCreate, shouldSucceed bool) string {
status, resp, err := sockRequest("POST", "/networks/create", config)
if !shouldSucceed {
c.Assert(status, checker.Not(checker.Equals), http.StatusCreated)
return ""
}
c.Assert(status, checker.Equals, http.StatusCreated)
c.Assert(err, checker.IsNil)
var nr types.NetworkCreateResponse
err = json.Unmarshal(resp, &nr)
c.Assert(err, checker.IsNil)
return nr.ID
}
func connectNetwork(c *check.C, nid, cid string) {
config := types.NetworkConnect{
Container: cid,
}
status, _, err := sockRequest("POST", "/networks/"+nid+"/connect", config)
c.Assert(status, checker.Equals, http.StatusOK)
c.Assert(err, checker.IsNil)
}
func disconnectNetwork(c *check.C, nid, cid string) {
config := types.NetworkConnect{
Container: cid,
}
status, _, err := sockRequest("POST", "/networks/"+nid+"/disconnect", config)
c.Assert(status, checker.Equals, http.StatusOK)
c.Assert(err, checker.IsNil)
}
func deleteNetwork(c *check.C, id string, shouldSucceed bool) {
status, _, err := sockRequest("DELETE", "/networks/"+id, nil)
if !shouldSucceed {
c.Assert(status, checker.Not(checker.Equals), http.StatusOK)
return
}
c.Assert(status, checker.Equals, http.StatusOK)
c.Assert(err, checker.IsNil)
}

View File

@@ -0,0 +1,44 @@
package main
import (
"net/http"
"strings"
"github.com/docker/docker/pkg/integration/checker"
"github.com/go-check/check"
)
func (s *DockerSuite) TestResizeApiResponse(c *check.C) {
out, _ := runSleepingContainer(c, "-d")
cleanedContainerID := strings.TrimSpace(out)
endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
status, _, err := sockRequest("POST", endpoint, nil)
c.Assert(status, check.Equals, http.StatusOK)
c.Assert(err, check.IsNil)
}
func (s *DockerSuite) TestResizeApiHeightWidthNoInt(c *check.C) {
out, _ := runSleepingContainer(c, "-d")
cleanedContainerID := strings.TrimSpace(out)
endpoint := "/containers/" + cleanedContainerID + "/resize?h=foo&w=bar"
status, _, err := sockRequest("POST", endpoint, nil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(err, check.IsNil)
}
func (s *DockerSuite) TestResizeApiResponseWhenContainerNotStarted(c *check.C) {
out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
cleanedContainerID := strings.TrimSpace(out)
// make sure the exited container is not running
dockerCmd(c, "wait", cleanedContainerID)
endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
status, body, err := sockRequest("POST", endpoint, nil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(err, check.IsNil)
c.Assert(string(body), checker.Contains, "is not running", check.Commentf("resize should fail with message 'Container is not running'"))
}

View File

@@ -0,0 +1,102 @@
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"net/http/httputil"
"os"
"os/exec"
"strconv"
"strings"
"time"
"github.com/docker/docker/api"
"github.com/docker/docker/pkg/integration/checker"
"github.com/go-check/check"
)
func (s *DockerSuite) TestApiOptionsRoute(c *check.C) {
status, _, err := sockRequest("OPTIONS", "/", nil)
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusOK)
}
func (s *DockerSuite) TestApiGetEnabledCors(c *check.C) {
res, body, err := sockRequestRaw("GET", "/version", nil, "")
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
body.Close()
// TODO: @runcom incomplete tests, why old integration tests had this headers
// and here none of the headers below are in the response?
//c.Log(res.Header)
//c.Assert(res.Header.Get("Access-Control-Allow-Origin"), check.Equals, "*")
//c.Assert(res.Header.Get("Access-Control-Allow-Headers"), check.Equals, "Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth")
}
func (s *DockerSuite) TestApiVersionStatusCode(c *check.C) {
conn, err := sockConn(time.Duration(10 * time.Second))
c.Assert(err, checker.IsNil)
client := httputil.NewClientConn(conn, nil)
defer client.Close()
req, err := http.NewRequest("GET", "/v999.0/version", nil)
c.Assert(err, checker.IsNil)
req.Header.Set("User-Agent", "Docker-Client/999.0 (os)")
res, err := client.Do(req)
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
}
func (s *DockerSuite) TestApiClientVersionNewerThanServer(c *check.C) {
v := strings.Split(api.DefaultVersion.String(), ".")
vMinInt, err := strconv.Atoi(v[1])
c.Assert(err, checker.IsNil)
vMinInt++
v[1] = strconv.Itoa(vMinInt)
version := strings.Join(v, ".")
status, body, err := sockRequest("GET", "/v"+version+"/version", nil)
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusBadRequest)
expected := fmt.Sprintf("client is newer than server (client API version: %s, server API version: %s)", version, api.DefaultVersion)
c.Assert(strings.TrimSpace(string(body)), checker.Equals, expected)
}
func (s *DockerSuite) TestApiClientVersionOldNotSupported(c *check.C) {
v := strings.Split(api.MinVersion.String(), ".")
vMinInt, err := strconv.Atoi(v[1])
c.Assert(err, checker.IsNil)
vMinInt--
v[1] = strconv.Itoa(vMinInt)
version := strings.Join(v, ".")
status, body, err := sockRequest("GET", "/v"+version+"/version", nil)
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusBadRequest)
expected := fmt.Sprintf("client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", version, api.MinVersion)
c.Assert(strings.TrimSpace(string(body)), checker.Equals, expected)
}
func (s *DockerSuite) TestApiDockerApiVersion(c *check.C) {
var svrVersion string
server := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
url := r.URL.Path
svrVersion = url
}))
defer server.Close()
// Test using the env var first
cmd := exec.Command(dockerBinary, "--region="+server.URL[7:], "version")
cmd.Env = append([]string{"DOCKER_API_VERSION=xxx"}, os.Environ()...)
out, _, _ := runCommandWithOutput(cmd)
c.Assert(svrVersion, check.Equals, "/vxxx/version")
if !strings.Contains(out, "API version: xxx") {
c.Fatalf("Out didn't have 'xxx' for the API version, had:\n%s", out)
}
}

View File

@@ -0,0 +1,35 @@
// +build !windows
package main
import (
"strings"
"github.com/docker/docker/pkg/integration/checker"
"github.com/go-check/check"
)
func (s *DockerSuite) TestApiUpdateContainer(c *check.C) {
testRequires(c, DaemonIsLinux)
testRequires(c, memoryLimitSupport)
testRequires(c, swapMemorySupport)
name := "apiUpdateContainer"
hostConfig := map[string]interface{}{
"Memory": 314572800,
"MemorySwap": 524288000,
}
dockerCmd(c, "run", "-d", "--name", name, "-m", "200M", "busybox", "top")
_, _, err := sockRequest("POST", "/containers/"+name+"/update", hostConfig)
c.Assert(err, check.IsNil)
c.Assert(inspectField(c, name, "HostConfig.Memory"), checker.Equals, "314572800")
file := "/sys/fs/cgroup/memory/memory.limit_in_bytes"
out, _ := dockerCmd(c, "exec", name, "cat", file)
c.Assert(strings.TrimSpace(out), checker.Equals, "314572800")
c.Assert(inspectField(c, name, "HostConfig.MemorySwap"), checker.Equals, "524288000")
file = "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes"
out, _ = dockerCmd(c, "exec", name, "cat", file)
c.Assert(strings.TrimSpace(out), checker.Equals, "524288000")
}