mirror of https://github.com/docker/docs.git
Merge pull request #12407 from cpuguy83/move_integration_api_tests
Move some integration api tests
This commit is contained in:
commit
27edbd2868
|
@ -369,10 +369,15 @@ func TestBuildApiDockerfilePath(t *testing.T) {
|
||||||
t.Fatalf("failed to close tar archive: %v", err)
|
t.Fatalf("failed to close tar archive: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, out, err := sockRequestRaw("POST", "/build?dockerfile=../Dockerfile", buffer, "application/x-tar")
|
_, body, err := sockRequestRaw("POST", "/build?dockerfile=../Dockerfile", buffer, "application/x-tar")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
out, _ := readBody(body)
|
||||||
t.Fatalf("Build was supposed to fail: %s", out)
|
t.Fatalf("Build was supposed to fail: %s", out)
|
||||||
}
|
}
|
||||||
|
out, err := readBody(body)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
if !strings.Contains(string(out), "must be within the build context") {
|
if !strings.Contains(string(out), "must be within the build context") {
|
||||||
t.Fatalf("Didn't complain about leaving build context: %s", out)
|
t.Fatalf("Didn't complain about leaving build context: %s", out)
|
||||||
|
@ -393,10 +398,14 @@ RUN find /tmp/`,
|
||||||
}
|
}
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
_, buf, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+server.URL()+"/testD", nil, "application/json")
|
_, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+server.URL()+"/testD", nil, "application/json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Build failed: %s", err)
|
t.Fatalf("Build failed: %s", err)
|
||||||
}
|
}
|
||||||
|
buf, err := readBody(body)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure Dockerfile exists.
|
// Make sure Dockerfile exists.
|
||||||
// Make sure 'baz' doesn't exist ANYWHERE despite being mentioned in the URL
|
// Make sure 'baz' doesn't exist ANYWHERE despite being mentioned in the URL
|
||||||
|
@ -419,10 +428,15 @@ RUN echo from dockerfile`,
|
||||||
}
|
}
|
||||||
defer git.Close()
|
defer git.Close()
|
||||||
|
|
||||||
_, buf, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
|
_, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
buf, _ := readBody(body)
|
||||||
t.Fatalf("Build failed: %s\n%q", err, buf)
|
t.Fatalf("Build failed: %s\n%q", err, buf)
|
||||||
}
|
}
|
||||||
|
buf, err := readBody(body)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
out := string(buf)
|
out := string(buf)
|
||||||
if !strings.Contains(out, "from dockerfile") {
|
if !strings.Contains(out, "from dockerfile") {
|
||||||
|
@ -445,10 +459,15 @@ RUN echo from Dockerfile`,
|
||||||
defer git.Close()
|
defer git.Close()
|
||||||
|
|
||||||
// Make sure it tries to 'dockerfile' query param value
|
// Make sure it tries to 'dockerfile' query param value
|
||||||
_, buf, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+git.RepoURL, nil, "application/json")
|
_, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+git.RepoURL, nil, "application/json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
buf, _ := readBody(body)
|
||||||
t.Fatalf("Build failed: %s\n%q", err, buf)
|
t.Fatalf("Build failed: %s\n%q", err, buf)
|
||||||
}
|
}
|
||||||
|
buf, err := readBody(body)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
out := string(buf)
|
out := string(buf)
|
||||||
if !strings.Contains(out, "from baz") {
|
if !strings.Contains(out, "from baz") {
|
||||||
|
@ -472,10 +491,14 @@ RUN echo from dockerfile`,
|
||||||
defer git.Close()
|
defer git.Close()
|
||||||
|
|
||||||
// Make sure it tries to 'dockerfile' query param value
|
// Make sure it tries to 'dockerfile' query param value
|
||||||
_, buf, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
|
_, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Build failed: %s", err)
|
t.Fatalf("Build failed: %s", err)
|
||||||
}
|
}
|
||||||
|
buf, err := readBody(body)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
out := string(buf)
|
out := string(buf)
|
||||||
if !strings.Contains(out, "from Dockerfile") {
|
if !strings.Contains(out, "from Dockerfile") {
|
||||||
|
@ -503,10 +526,15 @@ func TestBuildApiDockerfileSymlink(t *testing.T) {
|
||||||
t.Fatalf("failed to close tar archive: %v", err)
|
t.Fatalf("failed to close tar archive: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, out, err := sockRequestRaw("POST", "/build", buffer, "application/x-tar")
|
_, body, err := sockRequestRaw("POST", "/build", buffer, "application/x-tar")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
out, _ := readBody(body)
|
||||||
t.Fatalf("Build was supposed to fail: %s", out)
|
t.Fatalf("Build was supposed to fail: %s", out)
|
||||||
}
|
}
|
||||||
|
out, err := readBody(body)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
// The reason the error is "Cannot locate specified Dockerfile" is because
|
// The reason the error is "Cannot locate specified Dockerfile" is because
|
||||||
// in the builder, the symlink is resolved within the context, therefore
|
// in the builder, the symlink is resolved within the context, therefore
|
||||||
|
@ -596,3 +624,196 @@ func TestContainerApiPause(t *testing.T) {
|
||||||
|
|
||||||
logDone("container REST API - check POST containers/pause and unpause")
|
logDone("container REST API - check POST containers/pause and unpause")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContainerApiTop(t *testing.T) {
|
||||||
|
defer deleteAllContainers()
|
||||||
|
out, _, _ := dockerCmd(t, "run", "-d", "-i", "busybox", "/bin/sh", "-c", "cat")
|
||||||
|
id := strings.TrimSpace(out)
|
||||||
|
if err := waitRun(id); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type topResp struct {
|
||||||
|
Titles []string
|
||||||
|
Processes [][]string
|
||||||
|
}
|
||||||
|
var top topResp
|
||||||
|
_, b, err := sockRequest("GET", "/containers/"+id+"/top?ps_args=aux", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(b, &top); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(top.Titles) != 11 {
|
||||||
|
t.Fatalf("expected 11 titles, found %d: %v", len(top.Titles), top.Titles)
|
||||||
|
}
|
||||||
|
|
||||||
|
if top.Titles[0] != "USER" || top.Titles[10] != "COMMAND" {
|
||||||
|
t.Fatalf("expected `USER` at `Titles[0]` and `COMMAND` at Titles[10]: %v", top.Titles)
|
||||||
|
}
|
||||||
|
if len(top.Processes) != 2 {
|
||||||
|
t.Fatalf("expeted 2 processes, found %d: %v", len(top.Processes), top.Processes)
|
||||||
|
}
|
||||||
|
if top.Processes[0][10] != "/bin/sh -c cat" {
|
||||||
|
t.Fatalf("expected `/bin/sh -c cat`, found: %s", top.Processes[0][10])
|
||||||
|
}
|
||||||
|
if top.Processes[1][10] != "cat" {
|
||||||
|
t.Fatalf("expected `cat`, found: %s", top.Processes[1][10])
|
||||||
|
}
|
||||||
|
|
||||||
|
logDone("containers REST API - GET /containers/<id>/top")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContainerApiCommit(t *testing.T) {
|
||||||
|
out, _, _ := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "touch /test")
|
||||||
|
id := strings.TrimSpace(out)
|
||||||
|
|
||||||
|
name := "testcommit"
|
||||||
|
_, b, err := sockRequest("POST", "/commit?repo="+name+"&testtag=tag&container="+id, nil)
|
||||||
|
if err != nil && !strings.Contains(err.Error(), "200 OK: 201") {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type resp struct {
|
||||||
|
Id string
|
||||||
|
}
|
||||||
|
var img resp
|
||||||
|
if err := json.Unmarshal(b, &img); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer deleteImages(img.Id)
|
||||||
|
|
||||||
|
out, err = inspectField(img.Id, "Config.Cmd")
|
||||||
|
if out != "[/bin/sh -c touch /test]" {
|
||||||
|
t.Fatalf("got wrong Cmd from commit: %q", out)
|
||||||
|
}
|
||||||
|
// sanity check, make sure the image is what we think it is
|
||||||
|
dockerCmd(t, "run", img.Id, "ls", "/test")
|
||||||
|
|
||||||
|
logDone("containers REST API - POST /commit")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContainerApiCreate(t *testing.T) {
|
||||||
|
defer deleteAllContainers()
|
||||||
|
config := map[string]interface{}{
|
||||||
|
"Image": "busybox",
|
||||||
|
"Cmd": []string{"/bin/sh", "-c", "touch /test && ls /test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, b, err := sockRequest("POST", "/containers/create", config)
|
||||||
|
if err != nil && !strings.Contains(err.Error(), "200 OK: 201") {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
type createResp struct {
|
||||||
|
Id string
|
||||||
|
}
|
||||||
|
var container createResp
|
||||||
|
if err := json.Unmarshal(b, &container); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
out, _, _ := dockerCmd(t, "start", "-a", container.Id)
|
||||||
|
if strings.TrimSpace(out) != "/test" {
|
||||||
|
t.Fatalf("expected output `/test`, got %q", out)
|
||||||
|
}
|
||||||
|
|
||||||
|
logDone("containers REST API - POST /containers/create")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContainerApiVerifyHeader(t *testing.T) {
|
||||||
|
defer deleteAllContainers()
|
||||||
|
config := map[string]interface{}{
|
||||||
|
"Image": "busybox",
|
||||||
|
}
|
||||||
|
|
||||||
|
create := func(ct string) (int, io.ReadCloser, error) {
|
||||||
|
jsonData := bytes.NewBuffer(nil)
|
||||||
|
if err := json.NewEncoder(jsonData).Encode(config); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return sockRequestRaw("POST", "/containers/create", jsonData, ct)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try with no content-type
|
||||||
|
_, body, err := create("")
|
||||||
|
if err == nil {
|
||||||
|
b, _ := readBody(body)
|
||||||
|
t.Fatalf("expected error when content-type is not set: %q", string(b))
|
||||||
|
}
|
||||||
|
body.Close()
|
||||||
|
// Try with wrong content-type
|
||||||
|
_, body, err = create("application/xml")
|
||||||
|
if err == nil {
|
||||||
|
b, _ := readBody(body)
|
||||||
|
t.Fatalf("expected error when content-type is not set: %q", string(b))
|
||||||
|
}
|
||||||
|
body.Close()
|
||||||
|
|
||||||
|
// now application/json
|
||||||
|
_, body, err = create("application/json")
|
||||||
|
if err != nil && !strings.Contains(err.Error(), "200 OK: 201") {
|
||||||
|
b, _ := readBody(body)
|
||||||
|
t.Fatalf("%v - %q", err, string(b))
|
||||||
|
}
|
||||||
|
body.Close()
|
||||||
|
|
||||||
|
logDone("containers REST API - verify create header")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issue 7941 - test to make sure a "null" in JSON is just ignored.
|
||||||
|
// W/o this fix a null in JSON would be parsed into a string var as "null"
|
||||||
|
func TestContainerApiPostCreateNull(t *testing.T) {
|
||||||
|
config := `{
|
||||||
|
"Hostname":"",
|
||||||
|
"Domainname":"",
|
||||||
|
"Memory":0,
|
||||||
|
"MemorySwap":0,
|
||||||
|
"CpuShares":0,
|
||||||
|
"Cpuset":null,
|
||||||
|
"AttachStdin":true,
|
||||||
|
"AttachStdout":true,
|
||||||
|
"AttachStderr":true,
|
||||||
|
"PortSpecs":null,
|
||||||
|
"ExposedPorts":{},
|
||||||
|
"Tty":true,
|
||||||
|
"OpenStdin":true,
|
||||||
|
"StdinOnce":true,
|
||||||
|
"Env":[],
|
||||||
|
"Cmd":"ls",
|
||||||
|
"Image":"busybox",
|
||||||
|
"Volumes":{},
|
||||||
|
"WorkingDir":"",
|
||||||
|
"Entrypoint":null,
|
||||||
|
"NetworkDisabled":false,
|
||||||
|
"OnBuild":null}`
|
||||||
|
|
||||||
|
_, body, err := sockRequestRaw("POST", "/containers/create", strings.NewReader(config), "application/json")
|
||||||
|
if err != nil && !strings.Contains(err.Error(), "200 OK: 201") {
|
||||||
|
b, _ := readBody(body)
|
||||||
|
t.Fatal(err, string(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := readBody(body)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
type createResp struct {
|
||||||
|
Id string
|
||||||
|
}
|
||||||
|
var container createResp
|
||||||
|
if err := json.Unmarshal(b, &container); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := inspectField(container.Id, "HostConfig.CpusetCpus")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err, out)
|
||||||
|
}
|
||||||
|
if out != "" {
|
||||||
|
t.Fatalf("expected empty string, got %q", out)
|
||||||
|
}
|
||||||
|
|
||||||
|
logDone("containers REST API - Create Null")
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
@ -67,3 +68,33 @@ func TestApiImagesFilter(t *testing.T) {
|
||||||
|
|
||||||
logDone("images - filter param is applied")
|
logDone("images - filter param is applied")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestApiImagesSaveAndLoad(t *testing.T) {
|
||||||
|
out, err := buildImage("saveandload", "FROM hello-world\nENV FOO bar", false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
id := strings.TrimSpace(out)
|
||||||
|
defer deleteImages("saveandload")
|
||||||
|
|
||||||
|
_, body, err := sockRequestRaw("GET", "/images/"+id+"/get", nil, "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer body.Close()
|
||||||
|
|
||||||
|
dockerCmd(t, "rmi", id)
|
||||||
|
|
||||||
|
_, loadBody, err := sockRequestRaw("POST", "/images/load", body, "application/x-tar")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer loadBody.Close()
|
||||||
|
|
||||||
|
out, _, _ = dockerCmd(t, "inspect", "--format='{{ .Id }}'", id)
|
||||||
|
if strings.TrimSpace(out) != id {
|
||||||
|
t.Fatal("load did not work properly")
|
||||||
|
}
|
||||||
|
|
||||||
|
logDone("images API - save and load")
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/api"
|
"github.com/docker/docker/api"
|
||||||
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
"github.com/docker/docker/pkg/stringutils"
|
"github.com/docker/docker/pkg/stringutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -304,41 +305,53 @@ func sockRequest(method, endpoint string, data interface{}) (int, []byte, error)
|
||||||
return -1, nil, err
|
return -1, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return sockRequestRaw(method, endpoint, jsonData, "application/json")
|
status, body, err := sockRequestRaw(method, endpoint, jsonData, "application/json")
|
||||||
|
if err != nil {
|
||||||
|
b, _ := ioutil.ReadAll(body)
|
||||||
|
return status, b, err
|
||||||
|
}
|
||||||
|
var b []byte
|
||||||
|
b, err = readBody(body)
|
||||||
|
return status, b, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func sockRequestRaw(method, endpoint string, data io.Reader, ct string) (int, []byte, error) {
|
func sockRequestRaw(method, endpoint string, data io.Reader, ct string) (int, io.ReadCloser, error) {
|
||||||
c, err := sockConn(time.Duration(10 * time.Second))
|
c, err := sockConn(time.Duration(10 * time.Second))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, nil, fmt.Errorf("could not dial docker daemon: %v", err)
|
return -1, nil, fmt.Errorf("could not dial docker daemon: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
client := httputil.NewClientConn(c, nil)
|
client := httputil.NewClientConn(c, nil)
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
req, err := http.NewRequest(method, endpoint, data)
|
req, err := http.NewRequest(method, endpoint, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
client.Close()
|
||||||
return -1, nil, fmt.Errorf("could not create new request: %v", err)
|
return -1, nil, fmt.Errorf("could not create new request: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ct == "" {
|
if ct != "" {
|
||||||
ct = "application/json"
|
req.Header.Set("Content-Type", ct)
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", ct)
|
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
client.Close()
|
||||||
return -1, nil, fmt.Errorf("could not perform request: %v", err)
|
return -1, nil, fmt.Errorf("could not perform request: %v", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
body := ioutils.NewReadCloserWrapper(resp.Body, func() error {
|
||||||
|
defer client.Close()
|
||||||
|
return resp.Body.Close()
|
||||||
|
})
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
body, _ := ioutil.ReadAll(resp.Body)
|
|
||||||
return resp.StatusCode, body, fmt.Errorf("received status != 200 OK: %s", resp.Status)
|
return resp.StatusCode, body, fmt.Errorf("received status != 200 OK: %s", resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := ioutil.ReadAll(resp.Body)
|
return resp.StatusCode, body, err
|
||||||
|
}
|
||||||
|
|
||||||
return resp.StatusCode, b, err
|
func readBody(b io.ReadCloser) ([]byte, error) {
|
||||||
|
defer b.Close()
|
||||||
|
return ioutil.ReadAll(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteContainer(container string) error {
|
func deleteContainer(container string) error {
|
||||||
|
|
|
@ -4,335 +4,22 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/api"
|
"github.com/docker/docker/api"
|
||||||
"github.com/docker/docker/api/server"
|
"github.com/docker/docker/api/server"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/builder"
|
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/engine"
|
||||||
"github.com/docker/docker/runconfig"
|
"github.com/docker/docker/runconfig"
|
||||||
"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
|
"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSaveImageAndThenLoad(t *testing.T) {
|
|
||||||
eng := NewTestEngine(t)
|
|
||||||
defer mkDaemonFromEngine(eng, t).Nuke()
|
|
||||||
|
|
||||||
// save image
|
|
||||||
r := httptest.NewRecorder()
|
|
||||||
req, err := http.NewRequest("GET", "/images/"+unitTestImageID+"/get", nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
server.ServeRequest(eng, api.APIVERSION, r, req)
|
|
||||||
if r.Code != http.StatusOK {
|
|
||||||
t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
|
|
||||||
}
|
|
||||||
tarball := r.Body
|
|
||||||
|
|
||||||
// delete the image
|
|
||||||
r = httptest.NewRecorder()
|
|
||||||
req, err = http.NewRequest("DELETE", "/images/"+unitTestImageID, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
server.ServeRequest(eng, api.APIVERSION, r, req)
|
|
||||||
if r.Code != http.StatusOK {
|
|
||||||
t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure there is no image
|
|
||||||
r = httptest.NewRecorder()
|
|
||||||
req, err = http.NewRequest("GET", "/images/"+unitTestImageID+"/get", nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
server.ServeRequest(eng, api.APIVERSION, r, req)
|
|
||||||
if r.Code != http.StatusNotFound {
|
|
||||||
t.Fatalf("%d NotFound expected, received %d\n", http.StatusNotFound, r.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
// load the image
|
|
||||||
r = httptest.NewRecorder()
|
|
||||||
req, err = http.NewRequest("POST", "/images/load", tarball)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
server.ServeRequest(eng, api.APIVERSION, r, req)
|
|
||||||
if r.Code != http.StatusOK {
|
|
||||||
t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally make sure the image is there
|
|
||||||
r = httptest.NewRecorder()
|
|
||||||
req, err = http.NewRequest("GET", "/images/"+unitTestImageID+"/get", nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
server.ServeRequest(eng, api.APIVERSION, r, req)
|
|
||||||
if r.Code != http.StatusOK {
|
|
||||||
t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetContainersTop(t *testing.T) {
|
|
||||||
eng := NewTestEngine(t)
|
|
||||||
defer mkDaemonFromEngine(eng, t).Nuke()
|
|
||||||
|
|
||||||
containerID := createTestContainer(eng,
|
|
||||||
&runconfig.Config{
|
|
||||||
Image: unitTestImageID,
|
|
||||||
Cmd: runconfig.NewCommand("/bin/sh", "-c", "cat"),
|
|
||||||
OpenStdin: true,
|
|
||||||
},
|
|
||||||
t,
|
|
||||||
)
|
|
||||||
defer func() {
|
|
||||||
// Make sure the process dies before destroying daemon
|
|
||||||
containerKill(eng, containerID, t)
|
|
||||||
containerWait(eng, containerID, t)
|
|
||||||
}()
|
|
||||||
|
|
||||||
startContainer(eng, containerID, t)
|
|
||||||
|
|
||||||
setTimeout(t, "Waiting for the container to be started timed out", 10*time.Second, func() {
|
|
||||||
for {
|
|
||||||
if containerRunning(eng, containerID, t) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if !containerRunning(eng, containerID, t) {
|
|
||||||
t.Fatalf("Container should be running")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure sh spawn up cat
|
|
||||||
setTimeout(t, "read/write assertion timed out", 2*time.Second, func() {
|
|
||||||
in, out := containerAttach(eng, containerID, t)
|
|
||||||
if err := assertPipe("hello\n", "hello", out, in, 150); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
r := httptest.NewRecorder()
|
|
||||||
req, err := http.NewRequest("GET", "/containers/"+containerID+"/top?ps_args=aux", nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
server.ServeRequest(eng, api.APIVERSION, r, req)
|
|
||||||
assertHttpNotError(r, t)
|
|
||||||
var procs engine.Env
|
|
||||||
if err := procs.Decode(r.Body); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(procs.GetList("Titles")) != 11 {
|
|
||||||
t.Fatalf("Expected 11 titles, found %d.", len(procs.GetList("Titles")))
|
|
||||||
}
|
|
||||||
if procs.GetList("Titles")[0] != "USER" || procs.GetList("Titles")[10] != "COMMAND" {
|
|
||||||
t.Fatalf("Expected Titles[0] to be USER and Titles[10] to be COMMAND, found %s and %s.", procs.GetList("Titles")[0], procs.GetList("Titles")[10])
|
|
||||||
}
|
|
||||||
processes := [][]string{}
|
|
||||||
if err := procs.GetJson("Processes", &processes); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(processes) != 2 {
|
|
||||||
t.Fatalf("Expected 2 processes, found %d.", len(processes))
|
|
||||||
}
|
|
||||||
if processes[0][10] != "/bin/sh -c cat" {
|
|
||||||
t.Fatalf("Expected `/bin/sh -c cat`, found %s.", processes[0][10])
|
|
||||||
}
|
|
||||||
if processes[1][10] != "/bin/sh -c cat" {
|
|
||||||
t.Fatalf("Expected `/bin/sh -c cat`, found %s.", processes[1][10])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostCommit(t *testing.T) {
|
|
||||||
eng := NewTestEngine(t)
|
|
||||||
b := &builder.BuilderJob{Engine: eng}
|
|
||||||
b.Install()
|
|
||||||
defer mkDaemonFromEngine(eng, t).Nuke()
|
|
||||||
|
|
||||||
// Create a container and remove a file
|
|
||||||
containerID := createTestContainer(eng,
|
|
||||||
&runconfig.Config{
|
|
||||||
Image: unitTestImageID,
|
|
||||||
Cmd: runconfig.NewCommand("touch", "/test"),
|
|
||||||
},
|
|
||||||
t,
|
|
||||||
)
|
|
||||||
|
|
||||||
containerRun(eng, containerID, t)
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "/commit?repo=testrepo&testtag=tag&container="+containerID, bytes.NewReader([]byte{}))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
r := httptest.NewRecorder()
|
|
||||||
server.ServeRequest(eng, api.APIVERSION, r, req)
|
|
||||||
assertHttpNotError(r, t)
|
|
||||||
if r.Code != http.StatusCreated {
|
|
||||||
t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
var env engine.Env
|
|
||||||
if err := env.Decode(r.Body); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := eng.Job("image_inspect", env.Get("Id")).Run(); err != nil {
|
|
||||||
t.Fatalf("The image has not been committed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostContainersCreate(t *testing.T) {
|
|
||||||
eng := NewTestEngine(t)
|
|
||||||
defer mkDaemonFromEngine(eng, t).Nuke()
|
|
||||||
|
|
||||||
configJSON, err := json.Marshal(&runconfig.Config{
|
|
||||||
Image: unitTestImageID,
|
|
||||||
Cmd: runconfig.NewCommand("touch", "/test"),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "/containers/create", bytes.NewReader(configJSON))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
r := httptest.NewRecorder()
|
|
||||||
server.ServeRequest(eng, api.APIVERSION, r, req)
|
|
||||||
assertHttpNotError(r, t)
|
|
||||||
if r.Code != http.StatusCreated {
|
|
||||||
t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
var apiRun engine.Env
|
|
||||||
if err := apiRun.Decode(r.Body); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
containerID := apiRun.Get("Id")
|
|
||||||
|
|
||||||
containerAssertExists(eng, containerID, t)
|
|
||||||
containerRun(eng, containerID, t)
|
|
||||||
|
|
||||||
if !containerFileExists(eng, containerID, "test", t) {
|
|
||||||
t.Fatal("Test file was not created")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostJsonVerify(t *testing.T) {
|
|
||||||
eng := NewTestEngine(t)
|
|
||||||
defer mkDaemonFromEngine(eng, t).Nuke()
|
|
||||||
|
|
||||||
configJSON, err := json.Marshal(&runconfig.Config{
|
|
||||||
Image: unitTestImageID,
|
|
||||||
Cmd: runconfig.NewCommand("touch", "/test"),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "/containers/create", bytes.NewReader(configJSON))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
r := httptest.NewRecorder()
|
|
||||||
|
|
||||||
server.ServeRequest(eng, api.APIVERSION, r, req)
|
|
||||||
|
|
||||||
// Don't add Content-Type header
|
|
||||||
// req.Header.Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
server.ServeRequest(eng, api.APIVERSION, r, req)
|
|
||||||
if r.Code != http.StatusInternalServerError || !strings.Contains(((*r.Body).String()), "application/json") {
|
|
||||||
t.Fatal("Create should have failed due to no Content-Type header - got:", r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now add header but with wrong type and retest
|
|
||||||
req.Header.Set("Content-Type", "application/xml")
|
|
||||||
|
|
||||||
server.ServeRequest(eng, api.APIVERSION, r, req)
|
|
||||||
if r.Code != http.StatusInternalServerError || !strings.Contains(((*r.Body).String()), "application/json") {
|
|
||||||
t.Fatal("Create should have failed due to wrong Content-Type header - got:", r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Issue 7941 - test to make sure a "null" in JSON is just ignored.
|
|
||||||
// W/o this fix a null in JSON would be parsed into a string var as "null"
|
|
||||||
func TestPostCreateNull(t *testing.T) {
|
|
||||||
eng := NewTestEngine(t)
|
|
||||||
daemon := mkDaemonFromEngine(eng, t)
|
|
||||||
defer daemon.Nuke()
|
|
||||||
|
|
||||||
configStr := fmt.Sprintf(`{
|
|
||||||
"Hostname":"",
|
|
||||||
"Domainname":"",
|
|
||||||
"Memory":0,
|
|
||||||
"MemorySwap":0,
|
|
||||||
"CpuShares":0,
|
|
||||||
"Cpuset":null,
|
|
||||||
"AttachStdin":true,
|
|
||||||
"AttachStdout":true,
|
|
||||||
"AttachStderr":true,
|
|
||||||
"PortSpecs":null,
|
|
||||||
"ExposedPorts":{},
|
|
||||||
"Tty":true,
|
|
||||||
"OpenStdin":true,
|
|
||||||
"StdinOnce":true,
|
|
||||||
"Env":[],
|
|
||||||
"Cmd":"ls",
|
|
||||||
"Image":"%s",
|
|
||||||
"Volumes":{},
|
|
||||||
"WorkingDir":"",
|
|
||||||
"Entrypoint":null,
|
|
||||||
"NetworkDisabled":false,
|
|
||||||
"OnBuild":null}`, unitTestImageID)
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "/containers/create", strings.NewReader(configStr))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
r := httptest.NewRecorder()
|
|
||||||
server.ServeRequest(eng, api.APIVERSION, r, req)
|
|
||||||
assertHttpNotError(r, t)
|
|
||||||
if r.Code != http.StatusCreated {
|
|
||||||
t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
var apiRun engine.Env
|
|
||||||
if err := apiRun.Decode(r.Body); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
containerID := apiRun.Get("Id")
|
|
||||||
|
|
||||||
containerAssertExists(eng, containerID, t)
|
|
||||||
|
|
||||||
c, _ := daemon.Get(containerID)
|
|
||||||
if c.HostConfig().CpusetCpus != "" {
|
|
||||||
t.Fatalf("Cpuset should have been empty - instead its:" + c.HostConfig().CpusetCpus)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostContainersKill(t *testing.T) {
|
func TestPostContainersKill(t *testing.T) {
|
||||||
eng := NewTestEngine(t)
|
eng := NewTestEngine(t)
|
||||||
defer mkDaemonFromEngine(eng, t).Nuke()
|
defer mkDaemonFromEngine(eng, t).Nuke()
|
||||||
|
|
Loading…
Reference in New Issue