commit
61854b171d
81 changed files with 8461 additions and 4807 deletions
|
@ -57,6 +57,8 @@ clone git github.com/Sirupsen/logrus v0.7.2
|
|||
|
||||
clone git github.com/go-fsnotify/fsnotify v1.0.4
|
||||
|
||||
clone git github.com/go-check/check 64131543e7896d5bcc6bd5a76287eb75ea96c673
|
||||
|
||||
# get Go tip's archive/tar, for xattr support and improved performance
|
||||
# TODO after Go 1.4 drops, bump our minimum supported version and drop this vendored dep
|
||||
if [ "$1" = '--go' ]; then
|
||||
|
|
34
integration-cli/check_test.go
Normal file
34
integration-cli/check_test.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) { check.TestingT(t) }
|
||||
|
||||
type TimerSuite struct {
|
||||
start time.Time
|
||||
}
|
||||
|
||||
func (s *TimerSuite) SetUpTest(c *check.C) {
|
||||
s.start = time.Now()
|
||||
}
|
||||
|
||||
func (s *TimerSuite) TearDownTest(c *check.C) {
|
||||
fmt.Printf("%-60s%.2f\n", c.TestName(), time.Since(s.start).Seconds())
|
||||
}
|
||||
|
||||
type DockerSuite struct {
|
||||
TimerSuite
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TearDownTest(c *check.C) {
|
||||
deleteAllContainers()
|
||||
s.TimerSuite.TearDownTest(c)
|
||||
}
|
||||
|
||||
var _ = check.Suite(&DockerSuite{})
|
|
@ -4,23 +4,23 @@ import (
|
|||
"bytes"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-check/check"
|
||||
|
||||
"code.google.com/p/go.net/websocket"
|
||||
)
|
||||
|
||||
func TestGetContainersAttachWebsocket(t *testing.T) {
|
||||
func (s *DockerSuite) TestGetContainersAttachWebsocket(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-dit", "busybox", "cat")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
defer deleteAllContainers()
|
||||
|
||||
rwc, err := sockConn(time.Duration(10 * time.Second))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -29,12 +29,12 @@ func TestGetContainersAttachWebsocket(t *testing.T) {
|
|||
"http://localhost",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
ws, err := websocket.NewClient(config, rwc)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer ws.Close()
|
||||
|
||||
|
@ -43,7 +43,7 @@ func TestGetContainersAttachWebsocket(t *testing.T) {
|
|||
outChan := make(chan string)
|
||||
go func() {
|
||||
if _, err := ws.Read(actual); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
outChan <- "done"
|
||||
}()
|
||||
|
@ -51,7 +51,7 @@ func TestGetContainersAttachWebsocket(t *testing.T) {
|
|||
inChan := make(chan string)
|
||||
go func() {
|
||||
if _, err := ws.Write(expected); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
inChan <- "done"
|
||||
}()
|
||||
|
@ -60,8 +60,6 @@ func TestGetContainersAttachWebsocket(t *testing.T) {
|
|||
<-outChan
|
||||
|
||||
if !bytes.Equal(expected, actual) {
|
||||
t.Fatal("Expected output on websocket to match input")
|
||||
c.Fatal("Expected output on websocket to match input")
|
||||
}
|
||||
|
||||
logDone("container attach websocket - can echo input via cat")
|
||||
}
|
||||
|
|
|
@ -7,65 +7,59 @@ import (
|
|||
"net/http"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestContainerApiGetAll(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
|
||||
func (s *DockerSuite) TestContainerApiGetAll(c *check.C) {
|
||||
startCount, err := getContainerCount()
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot query container count: %v", err)
|
||||
c.Fatalf("Cannot query container count: %v", err)
|
||||
}
|
||||
|
||||
name := "getall"
|
||||
runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("Error on container creation: %v, output: %q", err, out)
|
||||
c.Fatalf("Error on container creation: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
_, body, err := sockRequest("GET", "/containers/json?all=1", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("GET all containers sockRequest failed: %v", err)
|
||||
c.Fatalf("GET all containers sockRequest failed: %v", err)
|
||||
}
|
||||
|
||||
var inspectJSON []struct {
|
||||
Names []string
|
||||
}
|
||||
if err = json.Unmarshal(body, &inspectJSON); err != nil {
|
||||
t.Fatalf("unable to unmarshal response body: %v", err)
|
||||
c.Fatalf("unable to unmarshal response body: %v", err)
|
||||
}
|
||||
|
||||
if len(inspectJSON) != startCount+1 {
|
||||
t.Fatalf("Expected %d container(s), %d found (started with: %d)", startCount+1, len(inspectJSON), startCount)
|
||||
c.Fatalf("Expected %d container(s), %d found (started with: %d)", startCount+1, len(inspectJSON), startCount)
|
||||
}
|
||||
|
||||
if actual := inspectJSON[0].Names[0]; actual != "/"+name {
|
||||
t.Fatalf("Container Name mismatch. Expected: %q, received: %q\n", "/"+name, actual)
|
||||
c.Fatalf("Container Name mismatch. Expected: %q, received: %q\n", "/"+name, actual)
|
||||
}
|
||||
|
||||
logDone("container REST API - check GET json/all=1")
|
||||
}
|
||||
|
||||
func TestContainerApiGetExport(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
|
||||
func (s *DockerSuite) TestContainerApiGetExport(c *check.C) {
|
||||
name := "exportcontainer"
|
||||
runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "touch", "/test")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("Error on container creation: %v, output: %q", err, out)
|
||||
c.Fatalf("Error on container creation: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
_, body, err := sockRequest("GET", "/containers/"+name+"/export", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("GET containers/export sockRequest failed: %v", err)
|
||||
c.Fatalf("GET containers/export sockRequest failed: %v", err)
|
||||
}
|
||||
|
||||
found := false
|
||||
|
@ -75,7 +69,7 @@ func TestContainerApiGetExport(t *testing.T) {
|
|||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if h.Name == "test" {
|
||||
found = true
|
||||
|
@ -84,25 +78,21 @@ func TestContainerApiGetExport(t *testing.T) {
|
|||
}
|
||||
|
||||
if !found {
|
||||
t.Fatalf("The created test file has not been found in the exported image")
|
||||
c.Fatalf("The created test file has not been found in the exported image")
|
||||
}
|
||||
|
||||
logDone("container REST API - check GET containers/export")
|
||||
}
|
||||
|
||||
func TestContainerApiGetChanges(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
|
||||
func (s *DockerSuite) TestContainerApiGetChanges(c *check.C) {
|
||||
name := "changescontainer"
|
||||
runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "rm", "/etc/passwd")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("Error on container creation: %v, output: %q", err, out)
|
||||
c.Fatalf("Error on container creation: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
_, body, err := sockRequest("GET", "/containers/"+name+"/changes", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("GET containers/changes sockRequest failed: %v", err)
|
||||
c.Fatalf("GET containers/changes sockRequest failed: %v", err)
|
||||
}
|
||||
|
||||
changes := []struct {
|
||||
|
@ -110,7 +100,7 @@ func TestContainerApiGetChanges(t *testing.T) {
|
|||
Path string
|
||||
}{}
|
||||
if err = json.Unmarshal(body, &changes); err != nil {
|
||||
t.Fatalf("unable to unmarshal response body: %v", err)
|
||||
c.Fatalf("unable to unmarshal response body: %v", err)
|
||||
}
|
||||
|
||||
// Check the changelog for removal of /etc/passwd
|
||||
|
@ -121,14 +111,11 @@ func TestContainerApiGetChanges(t *testing.T) {
|
|||
}
|
||||
}
|
||||
if !success {
|
||||
t.Fatalf("/etc/passwd has been removed but is not present in the diff")
|
||||
c.Fatalf("/etc/passwd has been removed but is not present in the diff")
|
||||
}
|
||||
|
||||
logDone("container REST API - check GET containers/changes")
|
||||
}
|
||||
|
||||
func TestContainerApiStartVolumeBinds(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestContainerApiStartVolumeBinds(c *check.C) {
|
||||
name := "testing"
|
||||
config := map[string]interface{}{
|
||||
"Image": "busybox",
|
||||
|
@ -136,7 +123,7 @@ func TestContainerApiStartVolumeBinds(t *testing.T) {
|
|||
}
|
||||
|
||||
if status, _, err := sockRequest("POST", "/containers/create?name="+name, config); err != nil && status != http.StatusCreated {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
bindPath := randomUnixTmpDirPath("test")
|
||||
|
@ -144,24 +131,21 @@ func TestContainerApiStartVolumeBinds(t *testing.T) {
|
|||
"Binds": []string{bindPath + ":/tmp"},
|
||||
}
|
||||
if status, _, err := sockRequest("POST", "/containers/"+name+"/start", config); err != nil && status != http.StatusNoContent {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
pth, err := inspectFieldMap(name, "Volumes", "/tmp")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if pth != bindPath {
|
||||
t.Fatalf("expected volume host path to be %s, got %s", bindPath, pth)
|
||||
c.Fatalf("expected volume host path to be %s, got %s", bindPath, pth)
|
||||
}
|
||||
|
||||
logDone("container REST API - check volume binds on start")
|
||||
}
|
||||
|
||||
// Test for GH#10618
|
||||
func TestContainerApiStartDupVolumeBinds(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestContainerApiStartDupVolumeBinds(c *check.C) {
|
||||
name := "testdups"
|
||||
config := map[string]interface{}{
|
||||
"Image": "busybox",
|
||||
|
@ -169,7 +153,7 @@ func TestContainerApiStartDupVolumeBinds(t *testing.T) {
|
|||
}
|
||||
|
||||
if status, _, err := sockRequest("POST", "/containers/create?name="+name, config); err != nil && status != http.StatusCreated {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
bindPath1 := randomUnixTmpDirPath("test1")
|
||||
|
@ -179,22 +163,19 @@ func TestContainerApiStartDupVolumeBinds(t *testing.T) {
|
|||
"Binds": []string{bindPath1 + ":/tmp", bindPath2 + ":/tmp"},
|
||||
}
|
||||
if _, body, err := sockRequest("POST", "/containers/"+name+"/start", config); err == nil {
|
||||
t.Fatal("expected container start to fail when duplicate volume binds to same container path")
|
||||
c.Fatal("expected container start to fail when duplicate volume binds to same container path")
|
||||
} else {
|
||||
if !strings.Contains(string(body), "Duplicate volume") {
|
||||
t.Fatalf("Expected failure due to duplicate bind mounts to same path, instead got: %q with error: %v", string(body), err)
|
||||
c.Fatalf("Expected failure due to duplicate bind mounts to same path, instead got: %q with error: %v", string(body), err)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("container REST API - check for duplicate volume binds error on start")
|
||||
}
|
||||
func TestContainerApiStartVolumesFrom(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestContainerApiStartVolumesFrom(c *check.C) {
|
||||
volName := "voltst"
|
||||
volPath := "/tmp"
|
||||
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", volName, "-v", volPath, "busybox")); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
name := "testing"
|
||||
|
@ -204,41 +185,38 @@ func TestContainerApiStartVolumesFrom(t *testing.T) {
|
|||
}
|
||||
|
||||
if status, _, err := sockRequest("POST", "/containers/create?name="+name, config); err != nil && status != http.StatusCreated {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
config = map[string]interface{}{
|
||||
"VolumesFrom": []string{volName},
|
||||
}
|
||||
if status, _, err := sockRequest("POST", "/containers/"+name+"/start", config); err != nil && status != http.StatusNoContent {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
pth, err := inspectFieldMap(name, "Volumes", volPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
pth2, err := inspectFieldMap(volName, "Volumes", volPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if pth != pth2 {
|
||||
t.Fatalf("expected volume host path to be %s, got %s", pth, pth2)
|
||||
c.Fatalf("expected volume host path to be %s, got %s", pth, pth2)
|
||||
}
|
||||
|
||||
logDone("container REST API - check VolumesFrom on start")
|
||||
}
|
||||
|
||||
// Ensure that volumes-from has priority over binds/anything else
|
||||
// This is pretty much the same as TestRunApplyVolumesFromBeforeVolumes, except with passing the VolumesFrom and the bind on start
|
||||
func TestVolumesFromHasPriority(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestVolumesFromHasPriority(c *check.C) {
|
||||
volName := "voltst2"
|
||||
volPath := "/tmp"
|
||||
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", volName, "-v", volPath, "busybox")); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
name := "testing"
|
||||
|
@ -248,7 +226,7 @@ func TestVolumesFromHasPriority(t *testing.T) {
|
|||
}
|
||||
|
||||
if status, _, err := sockRequest("POST", "/containers/create?name="+name, config); err != nil && status != http.StatusCreated {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
bindPath := randomUnixTmpDirPath("test")
|
||||
|
@ -257,34 +235,31 @@ func TestVolumesFromHasPriority(t *testing.T) {
|
|||
"Binds": []string{bindPath + ":/tmp"},
|
||||
}
|
||||
if status, _, err := sockRequest("POST", "/containers/"+name+"/start", config); err != nil && status != http.StatusNoContent {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
pth, err := inspectFieldMap(name, "Volumes", volPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
pth2, err := inspectFieldMap(volName, "Volumes", volPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if pth != pth2 {
|
||||
t.Fatalf("expected volume host path to be %s, got %s", pth, pth2)
|
||||
c.Fatalf("expected volume host path to be %s, got %s", pth, pth2)
|
||||
}
|
||||
|
||||
logDone("container REST API - check VolumesFrom has priority")
|
||||
}
|
||||
|
||||
func TestGetContainerStats(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestGetContainerStats(c *check.C) {
|
||||
var (
|
||||
name = "statscontainer"
|
||||
runCmd = exec.Command(dockerBinary, "run", "-d", "--name", name, "busybox", "top")
|
||||
)
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("Error on container creation: %v, output: %q", err, out)
|
||||
c.Fatalf("Error on container creation: %v, output: %q", err, out)
|
||||
}
|
||||
type b struct {
|
||||
body []byte
|
||||
|
@ -299,38 +274,36 @@ func TestGetContainerStats(t *testing.T) {
|
|||
// allow some time to stream the stats from the container
|
||||
time.Sleep(4 * time.Second)
|
||||
if _, err := runCommand(exec.Command(dockerBinary, "rm", "-f", name)); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// collect the results from the stats stream or timeout and fail
|
||||
// if the stream was not disconnected.
|
||||
select {
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("stream was not closed after container was removed")
|
||||
c.Fatal("stream was not closed after container was removed")
|
||||
case sr := <-bc:
|
||||
if sr.err != nil {
|
||||
t.Fatal(sr.err)
|
||||
c.Fatal(sr.err)
|
||||
}
|
||||
|
||||
dec := json.NewDecoder(bytes.NewBuffer(sr.body))
|
||||
var s *types.Stats
|
||||
// decode only one object from the stream
|
||||
if err := dec.Decode(&s); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
}
|
||||
logDone("container REST API - check GET containers/stats")
|
||||
}
|
||||
|
||||
func TestGetStoppedContainerStats(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestGetStoppedContainerStats(c *check.C) {
|
||||
var (
|
||||
name = "statscontainer"
|
||||
runCmd = exec.Command(dockerBinary, "create", "--name", name, "busybox", "top")
|
||||
)
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("Error on container creation: %v, output: %q", err, out)
|
||||
c.Fatalf("Error on container creation: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
@ -338,17 +311,15 @@ func TestGetStoppedContainerStats(t *testing.T) {
|
|||
// just send request and see if panic or error would happen on daemon side.
|
||||
_, _, err := sockRequest("GET", "/containers/"+name+"/stats", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
// allow some time to send request and let daemon deal with it
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
logDone("container REST API - check GET stopped containers/stats")
|
||||
}
|
||||
|
||||
func TestBuildApiDockerfilePath(t *testing.T) {
|
||||
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)
|
||||
|
@ -360,33 +331,31 @@ func TestBuildApiDockerfilePath(t *testing.T) {
|
|||
Name: "Dockerfile",
|
||||
Size: int64(len(dockerfile)),
|
||||
}); err != nil {
|
||||
t.Fatalf("failed to write tar file header: %v", err)
|
||||
c.Fatalf("failed to write tar file header: %v", err)
|
||||
}
|
||||
if _, err := tw.Write(dockerfile); err != nil {
|
||||
t.Fatalf("failed to write tar file content: %v", err)
|
||||
c.Fatalf("failed to write tar file content: %v", err)
|
||||
}
|
||||
if err := tw.Close(); err != nil {
|
||||
t.Fatalf("failed to close tar archive: %v", err)
|
||||
c.Fatalf("failed to close tar archive: %v", err)
|
||||
}
|
||||
|
||||
_, body, err := sockRequestRaw("POST", "/build?dockerfile=../Dockerfile", buffer, "application/x-tar")
|
||||
if err == nil {
|
||||
out, _ := readBody(body)
|
||||
t.Fatalf("Build was supposed to fail: %s", out)
|
||||
c.Fatalf("Build was supposed to fail: %s", out)
|
||||
}
|
||||
out, err := readBody(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if !strings.Contains(string(out), "must be within the build context") {
|
||||
t.Fatalf("Didn't complain about leaving build context: %s", out)
|
||||
c.Fatalf("Didn't complain about leaving build context: %s", out)
|
||||
}
|
||||
|
||||
logDone("container REST API - check build w/bad Dockerfile path")
|
||||
}
|
||||
|
||||
func TestBuildApiDockerFileRemote(t *testing.T) {
|
||||
func (s *DockerSuite) TestBuildApiDockerFileRemote(c *check.C) {
|
||||
server, err := fakeStorage(map[string]string{
|
||||
"testD": `FROM busybox
|
||||
COPY * /tmp/
|
||||
|
@ -394,17 +363,17 @@ RUN find / -name ba*
|
|||
RUN find /tmp/`,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer server.Close()
|
||||
|
||||
_, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+server.URL()+"/testD", nil, "application/json")
|
||||
if err != nil {
|
||||
t.Fatalf("Build failed: %s", err)
|
||||
c.Fatalf("Build failed: %s", err)
|
||||
}
|
||||
buf, err := readBody(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// Make sure Dockerfile exists.
|
||||
|
@ -412,41 +381,37 @@ RUN find /tmp/`,
|
|||
out := string(buf)
|
||||
if !strings.Contains(out, "/tmp/Dockerfile") ||
|
||||
strings.Contains(out, "baz") {
|
||||
t.Fatalf("Incorrect output: %s", out)
|
||||
c.Fatalf("Incorrect output: %s", out)
|
||||
}
|
||||
|
||||
logDone("container REST API - check build with -f from remote")
|
||||
}
|
||||
|
||||
func TestBuildApiLowerDockerfile(t *testing.T) {
|
||||
func (s *DockerSuite) TestBuildApiLowerDockerfile(c *check.C) {
|
||||
git, err := fakeGIT("repo", map[string]string{
|
||||
"dockerfile": `FROM busybox
|
||||
RUN echo from dockerfile`,
|
||||
}, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer git.Close()
|
||||
|
||||
_, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
|
||||
if err != nil {
|
||||
buf, _ := readBody(body)
|
||||
t.Fatalf("Build failed: %s\n%q", err, buf)
|
||||
c.Fatalf("Build failed: %s\n%q", err, buf)
|
||||
}
|
||||
buf, err := readBody(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
out := string(buf)
|
||||
if !strings.Contains(out, "from dockerfile") {
|
||||
t.Fatalf("Incorrect output: %s", out)
|
||||
c.Fatalf("Incorrect output: %s", out)
|
||||
}
|
||||
|
||||
logDone("container REST API - check build with lower dockerfile")
|
||||
}
|
||||
|
||||
func TestBuildApiBuildGitWithF(t *testing.T) {
|
||||
func (s *DockerSuite) TestBuildApiBuildGitWithF(c *check.C) {
|
||||
git, err := fakeGIT("repo", map[string]string{
|
||||
"baz": `FROM busybox
|
||||
RUN echo from baz`,
|
||||
|
@ -454,7 +419,7 @@ RUN echo from baz`,
|
|||
RUN echo from Dockerfile`,
|
||||
}, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer git.Close()
|
||||
|
||||
|
@ -462,23 +427,21 @@ RUN echo from Dockerfile`,
|
|||
_, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+git.RepoURL, nil, "application/json")
|
||||
if err != nil {
|
||||
buf, _ := readBody(body)
|
||||
t.Fatalf("Build failed: %s\n%q", err, buf)
|
||||
c.Fatalf("Build failed: %s\n%q", err, buf)
|
||||
}
|
||||
buf, err := readBody(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
out := string(buf)
|
||||
if !strings.Contains(out, "from baz") {
|
||||
t.Fatalf("Incorrect output: %s", out)
|
||||
c.Fatalf("Incorrect output: %s", out)
|
||||
}
|
||||
|
||||
logDone("container REST API - check build from git w/F")
|
||||
}
|
||||
|
||||
func TestBuildApiDoubleDockerfile(t *testing.T) {
|
||||
testRequires(t, UnixCli) // dockerfile overwrites Dockerfile on Windows
|
||||
func (s *DockerSuite) TestBuildApiDoubleDockerfile(c *check.C) {
|
||||
testRequires(c, UnixCli) // dockerfile overwrites Dockerfile on Windows
|
||||
git, err := fakeGIT("repo", map[string]string{
|
||||
"Dockerfile": `FROM busybox
|
||||
RUN echo from Dockerfile`,
|
||||
|
@ -486,29 +449,27 @@ RUN echo from Dockerfile`,
|
|||
RUN echo from dockerfile`,
|
||||
}, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer git.Close()
|
||||
|
||||
// Make sure it tries to 'dockerfile' query param value
|
||||
_, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
|
||||
if err != nil {
|
||||
t.Fatalf("Build failed: %s", err)
|
||||
c.Fatalf("Build failed: %s", err)
|
||||
}
|
||||
buf, err := readBody(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
out := string(buf)
|
||||
if !strings.Contains(out, "from Dockerfile") {
|
||||
t.Fatalf("Incorrect output: %s", out)
|
||||
c.Fatalf("Incorrect output: %s", out)
|
||||
}
|
||||
|
||||
logDone("container REST API - check build with two dockerfiles")
|
||||
}
|
||||
|
||||
func TestBuildApiDockerfileSymlink(t *testing.T) {
|
||||
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)
|
||||
|
@ -520,20 +481,20 @@ func TestBuildApiDockerfileSymlink(t *testing.T) {
|
|||
Typeflag: tar.TypeSymlink,
|
||||
Linkname: "/etc/passwd",
|
||||
}); err != nil {
|
||||
t.Fatalf("failed to write tar file header: %v", err)
|
||||
c.Fatalf("failed to write tar file header: %v", err)
|
||||
}
|
||||
if err := tw.Close(); err != nil {
|
||||
t.Fatalf("failed to close tar archive: %v", err)
|
||||
c.Fatalf("failed to close tar archive: %v", err)
|
||||
}
|
||||
|
||||
_, body, err := sockRequestRaw("POST", "/build", buffer, "application/x-tar")
|
||||
if err == nil {
|
||||
out, _ := readBody(body)
|
||||
t.Fatalf("Build was supposed to fail: %s", out)
|
||||
c.Fatalf("Build was supposed to fail: %s", out)
|
||||
}
|
||||
out, err := readBody(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// The reason the error is "Cannot locate specified Dockerfile" is because
|
||||
|
@ -541,96 +502,89 @@ func TestBuildApiDockerfileSymlink(t *testing.T) {
|
|||
// Dockerfile -> /etc/passwd becomes etc/passwd from the context which is
|
||||
// a nonexistent file.
|
||||
if !strings.Contains(string(out), "Cannot locate specified Dockerfile: Dockerfile") {
|
||||
t.Fatalf("Didn't complain about leaving build context: %s", out)
|
||||
c.Fatalf("Didn't complain about leaving build context: %s", out)
|
||||
}
|
||||
|
||||
logDone("container REST API - check build w/bad Dockerfile symlink path")
|
||||
}
|
||||
|
||||
// #9981 - Allow a docker created volume (ie, one in /var/lib/docker/volumes) to be used to overwrite (via passing in Binds on api start) an existing volume
|
||||
func TestPostContainerBindNormalVolume(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
|
||||
func (s *DockerSuite) TestPostContainerBindNormalVolume(c *check.C) {
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "create", "-v", "/foo", "--name=one", "busybox"))
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
fooDir, err := inspectFieldMap("one", "Volumes", "/foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "create", "-v", "/foo", "--name=two", "busybox"))
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
bindSpec := map[string][]string{"Binds": {fooDir + ":/foo"}}
|
||||
if status, _, err := sockRequest("POST", "/containers/two/start", bindSpec); err != nil && status != http.StatusNoContent {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
fooDir2, err := inspectFieldMap("two", "Volumes", "/foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if fooDir2 != fooDir {
|
||||
t.Fatalf("expected volume path to be %s, got: %s", fooDir, fooDir2)
|
||||
c.Fatalf("expected volume path to be %s, got: %s", fooDir, fooDir2)
|
||||
}
|
||||
|
||||
logDone("container REST API - can use path from normal volume as bind-mount to overwrite another volume")
|
||||
}
|
||||
|
||||
func TestContainerApiPause(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestContainerApiPause(c *check.C) {
|
||||
defer unpauseAllContainers()
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sleep", "30")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create a container: %s, %v", out, err)
|
||||
c.Fatalf("failed to create a container: %s, %v", out, err)
|
||||
}
|
||||
ContainerID := strings.TrimSpace(out)
|
||||
|
||||
if status, _, err := sockRequest("POST", "/containers/"+ContainerID+"/pause", nil); err != nil && status != http.StatusNoContent {
|
||||
t.Fatalf("POST a container pause: sockRequest failed: %v", err)
|
||||
c.Fatalf("POST a container pause: sockRequest failed: %v", err)
|
||||
}
|
||||
|
||||
pausedContainers, err := getSliceOfPausedContainers()
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("error thrown while checking if containers were paused: %v", err)
|
||||
c.Fatalf("error thrown while checking if containers were paused: %v", err)
|
||||
}
|
||||
|
||||
if len(pausedContainers) != 1 || stringid.TruncateID(ContainerID) != pausedContainers[0] {
|
||||
t.Fatalf("there should be one paused container and not %d", len(pausedContainers))
|
||||
c.Fatalf("there should be one paused container and not %d", len(pausedContainers))
|
||||
}
|
||||
|
||||
if status, _, err := sockRequest("POST", "/containers/"+ContainerID+"/unpause", nil); err != nil && status != http.StatusNoContent {
|
||||
t.Fatalf("POST a container pause: sockRequest failed: %v", err)
|
||||
c.Fatalf("POST a container pause: sockRequest failed: %v", err)
|
||||
}
|
||||
|
||||
pausedContainers, err = getSliceOfPausedContainers()
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("error thrown while checking if containers were paused: %v", err)
|
||||
c.Fatalf("error thrown while checking if containers were paused: %v", err)
|
||||
}
|
||||
|
||||
if pausedContainers != nil {
|
||||
t.Fatalf("There should be no paused container.")
|
||||
c.Fatalf("There should be no paused container.")
|
||||
}
|
||||
|
||||
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)
|
||||
func (s *DockerSuite) TestContainerApiTop(c *check.C) {
|
||||
out, err := exec.Command(dockerBinary, "run", "-d", "busybox", "/bin/sh", "-c", "top").CombinedOutput()
|
||||
if err != nil {
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
id := strings.TrimSpace(string(out))
|
||||
if err := waitRun(id); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
type topResp struct {
|
||||
|
@ -640,40 +594,41 @@ func TestContainerApiTop(t *testing.T) {
|
|||
var top topResp
|
||||
_, b, err := sockRequest("GET", "/containers/"+id+"/top?ps_args=aux", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if err := json.Unmarshal(b, &top); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if len(top.Titles) != 11 {
|
||||
t.Fatalf("expected 11 titles, found %d: %v", len(top.Titles), top.Titles)
|
||||
c.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)
|
||||
c.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)
|
||||
c.Fatalf("expected 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[0][10] != "/bin/sh -c top" {
|
||||
c.Fatalf("expected `/bin/sh -c top`, found: %s", top.Processes[0][10])
|
||||
}
|
||||
if top.Processes[1][10] != "cat" {
|
||||
t.Fatalf("expected `cat`, found: %s", top.Processes[1][10])
|
||||
if top.Processes[1][10] != "top" {
|
||||
c.Fatalf("expected `top`, 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)
|
||||
func (s *DockerSuite) TestContainerApiCommit(c *check.C) {
|
||||
out, err := exec.Command(dockerBinary, "run", "-d", "busybox", "/bin/sh", "-c", "touch /test").CombinedOutput()
|
||||
if err != nil {
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
id := strings.TrimSpace(string(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)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
type resp struct {
|
||||
|
@ -681,22 +636,25 @@ func TestContainerApiCommit(t *testing.T) {
|
|||
}
|
||||
var img resp
|
||||
if err := json.Unmarshal(b, &img); err != nil {
|
||||
t.Fatal(err)
|
||||
c.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)
|
||||
cmd, err := inspectField(img.Id, "Config.Cmd")
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
if cmd != "[/bin/sh -c touch /test]" {
|
||||
c.Fatalf("got wrong Cmd from commit: %q", cmd)
|
||||
}
|
||||
// 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")
|
||||
out, err = exec.Command(dockerBinary, "run", img.Id, "ls", "/test").CombinedOutput()
|
||||
if err != nil {
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainerApiCreate(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestContainerApiCreate(c *check.C) {
|
||||
config := map[string]interface{}{
|
||||
"Image": "busybox",
|
||||
"Cmd": []string{"/bin/sh", "-c", "touch /test && ls /test"},
|
||||
|
@ -704,26 +662,26 @@ func TestContainerApiCreate(t *testing.T) {
|
|||
|
||||
_, b, err := sockRequest("POST", "/containers/create", config)
|
||||
if err != nil && !strings.Contains(err.Error(), "200 OK: 201") {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
type createResp struct {
|
||||
Id string
|
||||
}
|
||||
var container createResp
|
||||
if err := json.Unmarshal(b, &container); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
out, _ := dockerCmd(t, "start", "-a", container.Id)
|
||||
if strings.TrimSpace(out) != "/test" {
|
||||
t.Fatalf("expected output `/test`, got %q", out)
|
||||
out, err := exec.Command(dockerBinary, "start", "-a", container.Id).CombinedOutput()
|
||||
if err != nil {
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
if strings.TrimSpace(string(out)) != "/test" {
|
||||
c.Fatalf("expected output `/test`, got %q", out)
|
||||
}
|
||||
|
||||
logDone("containers REST API - POST /containers/create")
|
||||
}
|
||||
|
||||
func TestContainerApiVerifyHeader(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestContainerApiVerifyHeader(c *check.C) {
|
||||
config := map[string]interface{}{
|
||||
"Image": "busybox",
|
||||
}
|
||||
|
@ -731,7 +689,7 @@ func TestContainerApiVerifyHeader(t *testing.T) {
|
|||
create := func(ct string) (int, io.ReadCloser, error) {
|
||||
jsonData := bytes.NewBuffer(nil)
|
||||
if err := json.NewEncoder(jsonData).Encode(config); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
return sockRequestRaw("POST", "/containers/create", jsonData, ct)
|
||||
}
|
||||
|
@ -740,14 +698,14 @@ func TestContainerApiVerifyHeader(t *testing.T) {
|
|||
_, body, err := create("")
|
||||
if err == nil {
|
||||
b, _ := readBody(body)
|
||||
t.Fatalf("expected error when content-type is not set: %q", string(b))
|
||||
c.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))
|
||||
c.Fatalf("expected error when content-type is not set: %q", string(b))
|
||||
}
|
||||
body.Close()
|
||||
|
||||
|
@ -755,16 +713,14 @@ func TestContainerApiVerifyHeader(t *testing.T) {
|
|||
_, 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))
|
||||
c.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) {
|
||||
func (s *DockerSuite) TestContainerApiPostCreateNull(c *check.C) {
|
||||
config := `{
|
||||
"Hostname":"",
|
||||
"Domainname":"",
|
||||
|
@ -792,33 +748,31 @@ func TestContainerApiPostCreateNull(t *testing.T) {
|
|||
_, 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))
|
||||
c.Fatal(err, string(b))
|
||||
}
|
||||
|
||||
b, err := readBody(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
type createResp struct {
|
||||
Id string
|
||||
}
|
||||
var container createResp
|
||||
if err := json.Unmarshal(b, &container); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
out, err := inspectField(container.Id, "HostConfig.CpusetCpus")
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
if out != "" {
|
||||
t.Fatalf("expected empty string, got %q", out)
|
||||
c.Fatalf("expected empty string, got %q", out)
|
||||
}
|
||||
|
||||
logDone("containers REST API - Create Null")
|
||||
}
|
||||
|
||||
func TestCreateWithTooLowMemoryLimit(t *testing.T) {
|
||||
func (s *DockerSuite) TestCreateWithTooLowMemoryLimit(c *check.C) {
|
||||
defer deleteAllContainers()
|
||||
config := `{
|
||||
"Image": "busybox",
|
||||
|
@ -831,22 +785,21 @@ func TestCreateWithTooLowMemoryLimit(t *testing.T) {
|
|||
_, body, err := sockRequestRaw("POST", "/containers/create", strings.NewReader(config), "application/json")
|
||||
b, err2 := readBody(body)
|
||||
if err2 != nil {
|
||||
t.Fatal(err2)
|
||||
c.Fatal(err2)
|
||||
}
|
||||
|
||||
if err == nil || !strings.Contains(string(b), "Minimum memory limit allowed is 4MB") {
|
||||
t.Errorf("Memory limit is smaller than the allowed limit. Container creation should've failed!")
|
||||
c.Errorf("Memory limit is smaller than the allowed limit. Container creation should've failed!")
|
||||
}
|
||||
|
||||
logDone("container REST API - create can't set too low memory limit")
|
||||
}
|
||||
|
||||
func TestStartWithTooLowMemoryLimit(t *testing.T) {
|
||||
func (s *DockerSuite) TestStartWithTooLowMemoryLimit(c *check.C) {
|
||||
defer deleteAllContainers()
|
||||
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "create", "busybox"))
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
@ -859,12 +812,10 @@ func TestStartWithTooLowMemoryLimit(t *testing.T) {
|
|||
_, body, err := sockRequestRaw("POST", "/containers/"+containerID+"/start", strings.NewReader(config), "application/json")
|
||||
b, err2 := readBody(body)
|
||||
if err2 != nil {
|
||||
t.Fatal(err2)
|
||||
c.Fatal(err2)
|
||||
}
|
||||
|
||||
if err == nil || !strings.Contains(string(b), "Minimum memory limit allowed is 4MB") {
|
||||
t.Errorf("Memory limit is smaller than the allowed limit. Container creation should've failed!")
|
||||
c.Errorf("Memory limit is smaller than the allowed limit. Container creation should've failed!")
|
||||
}
|
||||
|
||||
logDone("container REST API - start can't set too low memory limit")
|
||||
}
|
||||
|
|
|
@ -4,26 +4,24 @@ import (
|
|||
"net/http"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestExecResizeApiHeightWidthNoInt(t *testing.T) {
|
||||
func (s *DockerSuite) TestExecResizeApiHeightWidthNoInt(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
defer deleteAllContainers()
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
endpoint := "/exec/" + cleanedContainerID + "/resize?h=foo&w=bar"
|
||||
status, _, err := sockRequest("POST", endpoint, nil)
|
||||
if err == nil {
|
||||
t.Fatal("Expected exec resize Request to fail")
|
||||
c.Fatal("Expected exec resize Request to fail")
|
||||
}
|
||||
if status != http.StatusInternalServerError {
|
||||
t.Fatalf("Status expected %d, got %d", http.StatusInternalServerError, status)
|
||||
c.Fatalf("Status expected %d, got %d", http.StatusInternalServerError, status)
|
||||
}
|
||||
|
||||
logDone("container exec resize - height, width no int fail")
|
||||
}
|
||||
|
|
|
@ -6,22 +6,20 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// Regression test for #9414
|
||||
func TestExecApiCreateNoCmd(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecApiCreateNoCmd(c *check.C) {
|
||||
name := "exec_test"
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
_, body, err := sockRequest("POST", fmt.Sprintf("/containers/%s/exec", name), map[string]interface{}{"Cmd": nil})
|
||||
if err == nil || !bytes.Contains(body, []byte("No exec command specified")) {
|
||||
t.Fatalf("Expected error when creating exec command with no Cmd specified: %q", err)
|
||||
c.Fatalf("Expected error when creating exec command with no Cmd specified: %q", err)
|
||||
}
|
||||
|
||||
logDone("exec create API - returns error when missing Cmd")
|
||||
}
|
||||
|
|
|
@ -3,50 +3,50 @@ package main
|
|||
import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestLegacyImages(t *testing.T) {
|
||||
func (s *DockerSuite) TestLegacyImages(c *check.C) {
|
||||
_, body, err := sockRequest("GET", "/v1.6/images/json", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Error on GET: %s", err)
|
||||
c.Fatalf("Error on GET: %s", err)
|
||||
}
|
||||
|
||||
images := []types.LegacyImage{}
|
||||
if err = json.Unmarshal(body, &images); err != nil {
|
||||
t.Fatalf("Error on unmarshal: %s", err)
|
||||
c.Fatalf("Error on unmarshal: %s", err)
|
||||
}
|
||||
|
||||
if len(images) == 0 || images[0].Tag == "" || images[0].Repository == "" {
|
||||
t.Fatalf("Bad data: %q", images)
|
||||
c.Fatalf("Bad data: %q", images)
|
||||
}
|
||||
|
||||
logDone("images - checking legacy json")
|
||||
}
|
||||
|
||||
func TestApiImagesFilter(t *testing.T) {
|
||||
func (s *DockerSuite) TestApiImagesFilter(c *check.C) {
|
||||
name := "utest:tag1"
|
||||
name2 := "utest/docker:tag2"
|
||||
name3 := "utest:5000/docker:tag3"
|
||||
defer deleteImages(name, name2, name3)
|
||||
dockerCmd(t, "tag", "busybox", name)
|
||||
dockerCmd(t, "tag", "busybox", name2)
|
||||
dockerCmd(t, "tag", "busybox", name3)
|
||||
|
||||
for _, n := range []string{name, name2, name3} {
|
||||
if out, err := exec.Command(dockerBinary, "tag", "busybox", n).CombinedOutput(); err != nil {
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
}
|
||||
type image struct{ RepoTags []string }
|
||||
getImages := func(filter string) []image {
|
||||
v := url.Values{}
|
||||
v.Set("filter", filter)
|
||||
_, b, err := sockRequest("GET", "/images/json?"+v.Encode(), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
var images []image
|
||||
if err := json.Unmarshal(b, &images); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
return images
|
||||
|
@ -54,48 +54,49 @@ func TestApiImagesFilter(t *testing.T) {
|
|||
|
||||
errMsg := "incorrect number of matches returned"
|
||||
if images := getImages("utest*/*"); len(images[0].RepoTags) != 2 {
|
||||
t.Fatal(errMsg)
|
||||
c.Fatal(errMsg)
|
||||
}
|
||||
if images := getImages("utest"); len(images[0].RepoTags) != 1 {
|
||||
t.Fatal(errMsg)
|
||||
c.Fatal(errMsg)
|
||||
}
|
||||
if images := getImages("utest*"); len(images[0].RepoTags) != 1 {
|
||||
t.Fatal(errMsg)
|
||||
c.Fatal(errMsg)
|
||||
}
|
||||
if images := getImages("*5000*/*"); len(images[0].RepoTags) != 1 {
|
||||
t.Fatal(errMsg)
|
||||
c.Fatal(errMsg)
|
||||
}
|
||||
|
||||
logDone("images - filter param is applied")
|
||||
}
|
||||
|
||||
func TestApiImagesSaveAndLoad(t *testing.T) {
|
||||
testRequires(t, Network)
|
||||
func (s *DockerSuite) TestApiImagesSaveAndLoad(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
out, err := buildImage("saveandload", "FROM hello-world\nENV FOO bar", false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
id := strings.TrimSpace(out)
|
||||
defer deleteImages("saveandload")
|
||||
|
||||
_, body, err := sockRequestRaw("GET", "/images/"+id+"/get", nil, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
dockerCmd(t, "rmi", id)
|
||||
if out, err := exec.Command(dockerBinary, "rmi", id).CombinedOutput(); err != nil {
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
_, loadBody, err := sockRequestRaw("POST", "/images/load", body, "application/x-tar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer loadBody.Close()
|
||||
|
||||
out, _ = dockerCmd(t, "inspect", "--format='{{ .Id }}'", id)
|
||||
if strings.TrimSpace(out) != id {
|
||||
t.Fatal("load did not work properly")
|
||||
inspectOut, err := exec.Command(dockerBinary, "inspect", "--format='{{ .Id }}'", id).CombinedOutput()
|
||||
if err != nil {
|
||||
c.Fatal(err, inspectOut)
|
||||
}
|
||||
if strings.TrimSpace(string(inspectOut)) != id {
|
||||
c.Fatal("load did not work properly")
|
||||
}
|
||||
|
||||
logDone("images API - save and load")
|
||||
}
|
||||
|
|
|
@ -33,6 +33,4 @@ func TestInfoApi(t *testing.T) {
|
|||
t.Errorf("couldn't find string %v in output", linePrefix)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("container REST API - check GET /info")
|
||||
}
|
||||
|
|
|
@ -4,16 +4,15 @@ import (
|
|||
"encoding/json"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestInspectApiContainerResponse(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
|
||||
func (s *DockerSuite) TestInspectApiContainerResponse(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create a container: %s, %v", out, err)
|
||||
c.Fatalf("failed to create a container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -29,12 +28,12 @@ func TestInspectApiContainerResponse(t *testing.T) {
|
|||
}
|
||||
_, body, err := sockRequest("GET", endpoint, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("sockRequest failed for %s version: %v", testVersion, err)
|
||||
c.Fatalf("sockRequest failed for %s version: %v", testVersion, err)
|
||||
}
|
||||
|
||||
var inspectJSON map[string]interface{}
|
||||
if err = json.Unmarshal(body, &inspectJSON); err != nil {
|
||||
t.Fatalf("unable to unmarshal body for %s version: %v", testVersion, err)
|
||||
c.Fatalf("unable to unmarshal body for %s version: %v", testVersion, err)
|
||||
}
|
||||
|
||||
keys := []string{"State", "Created", "Path", "Args", "Config", "Image", "NetworkSettings", "ResolvConfPath", "HostnamePath", "HostsPath", "LogPath", "Name", "Driver", "ExecDriver", "MountLabel", "ProcessLabel", "Volumes", "VolumesRW"}
|
||||
|
@ -47,14 +46,12 @@ func TestInspectApiContainerResponse(t *testing.T) {
|
|||
|
||||
for _, key := range keys {
|
||||
if _, ok := inspectJSON[key]; !ok {
|
||||
t.Fatalf("%s does not exist in response for %s version", key, testVersion)
|
||||
c.Fatalf("%s does not exist in response for %s version", key, testVersion)
|
||||
}
|
||||
}
|
||||
//Issue #6830: type not properly converted to JSON/back
|
||||
if _, ok := inspectJSON["Path"].(bool); ok {
|
||||
t.Fatalf("Path of `true` should not be converted to boolean `true` via JSON marshalling")
|
||||
c.Fatalf("Path of `true` should not be converted to boolean `true` via JSON marshalling")
|
||||
}
|
||||
}
|
||||
|
||||
logDone("container json - check keys in container json response")
|
||||
}
|
||||
|
|
|
@ -5,49 +5,44 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestLogsApiWithStdout(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLogsApiWithStdout(c *check.C) {
|
||||
name := "logs_test"
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "-t", "--name", name, "busybox", "bin/sh", "-c", "sleep 10 && echo "+name)
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
statusCode, body, err := sockRequest("GET", fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1×tamps=1", name), nil)
|
||||
|
||||
if err != nil || statusCode != http.StatusOK {
|
||||
t.Fatalf("Expected %d from logs request, got %d", http.StatusOK, statusCode)
|
||||
c.Fatalf("Expected %d from logs request, got %d", http.StatusOK, statusCode)
|
||||
}
|
||||
|
||||
if !bytes.Contains(body, []byte(name)) {
|
||||
t.Fatalf("Expected %s, got %s", name, string(body[:]))
|
||||
c.Fatalf("Expected %s, got %s", name, string(body[:]))
|
||||
}
|
||||
|
||||
logDone("logs API - with stdout ok")
|
||||
}
|
||||
|
||||
func TestLogsApiNoStdoutNorStderr(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLogsApiNoStdoutNorStderr(c *check.C) {
|
||||
name := "logs_test"
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
statusCode, body, err := sockRequest("GET", fmt.Sprintf("/containers/%s/logs", name), nil)
|
||||
|
||||
if err == nil || statusCode != http.StatusBadRequest {
|
||||
t.Fatalf("Expected %d from logs request, got %d", http.StatusBadRequest, statusCode)
|
||||
c.Fatalf("Expected %d from logs request, got %d", http.StatusBadRequest, statusCode)
|
||||
}
|
||||
|
||||
expected := "Bad parameters: you must choose at least one stream"
|
||||
if !bytes.Contains(body, []byte(expected)) {
|
||||
t.Fatalf("Expected %s, got %s", expected, string(body[:]))
|
||||
c.Fatalf("Expected %s, got %s", expected, string(body[:]))
|
||||
}
|
||||
|
||||
logDone("logs API - returns error when no stdout nor stderr specified")
|
||||
}
|
||||
|
|
|
@ -4,72 +4,64 @@ import (
|
|||
"net/http"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestResizeApiResponse(t *testing.T) {
|
||||
func (s *DockerSuite) TestResizeApiResponse(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
defer deleteAllContainers()
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
|
||||
_, _, err = sockRequest("POST", endpoint, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("resize Request failed %v", err)
|
||||
c.Fatalf("resize Request failed %v", err)
|
||||
}
|
||||
|
||||
logDone("container resize - when started")
|
||||
}
|
||||
|
||||
func TestResizeApiHeightWidthNoInt(t *testing.T) {
|
||||
func (s *DockerSuite) TestResizeApiHeightWidthNoInt(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
defer deleteAllContainers()
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
endpoint := "/containers/" + cleanedContainerID + "/resize?h=foo&w=bar"
|
||||
status, _, err := sockRequest("POST", endpoint, nil)
|
||||
if err == nil {
|
||||
t.Fatal("Expected resize Request to fail")
|
||||
c.Fatal("Expected resize Request to fail")
|
||||
}
|
||||
if status != http.StatusInternalServerError {
|
||||
t.Fatalf("Status expected %d, got %d", http.StatusInternalServerError, status)
|
||||
c.Fatalf("Status expected %d, got %d", http.StatusInternalServerError, status)
|
||||
}
|
||||
|
||||
logDone("container resize - height, width no int fail")
|
||||
}
|
||||
|
||||
func TestResizeApiResponseWhenContainerNotStarted(t *testing.T) {
|
||||
func (s *DockerSuite) TestResizeApiResponseWhenContainerNotStarted(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
defer deleteAllContainers()
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
// make sure the exited container is not running
|
||||
runCmd = exec.Command(dockerBinary, "wait", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
|
||||
endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
|
||||
_, body, err := sockRequest("POST", endpoint, nil)
|
||||
if err == nil {
|
||||
t.Fatalf("resize should fail when container is not started")
|
||||
c.Fatalf("resize should fail when container is not started")
|
||||
}
|
||||
if !strings.Contains(string(body), "Cannot resize container") && !strings.Contains(string(body), cleanedContainerID) {
|
||||
t.Fatalf("resize should fail with message 'Cannot resize container' but instead received %s", string(body))
|
||||
c.Fatalf("resize should fail with message 'Cannot resize container' but instead received %s", string(body))
|
||||
}
|
||||
|
||||
logDone("container resize - when not started should not resize")
|
||||
}
|
||||
|
|
|
@ -2,23 +2,23 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/autogen/dockerversion"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestGetVersion(t *testing.T) {
|
||||
func (s *DockerSuite) TestGetVersion(c *check.C) {
|
||||
_, body, err := sockRequest("GET", "/version", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
var v types.Version
|
||||
if err := json.Unmarshal(body, &v); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if v.Version != dockerversion.VERSION {
|
||||
t.Fatal("Version mismatch")
|
||||
c.Fatal("Version mismatch")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,14 +6,14 @@ import (
|
|||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
const attachWait = 5 * time.Second
|
||||
|
||||
func TestAttachMultipleAndRestart(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestAttachMultipleAndRestart(c *check.C) {
|
||||
|
||||
endGroup := &sync.WaitGroup{}
|
||||
startGroup := &sync.WaitGroup{}
|
||||
|
@ -21,7 +21,7 @@ func TestAttachMultipleAndRestart(t *testing.T) {
|
|||
startGroup.Add(3)
|
||||
|
||||
if err := waitForContainer("attacher", "-d", "busybox", "/bin/sh", "-c", "while true; do sleep 1; echo hello; done"); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
startDone := make(chan struct{})
|
||||
|
@ -39,32 +39,32 @@ func TestAttachMultipleAndRestart(t *testing.T) {
|
|||
|
||||
for i := 0; i < 3; i++ {
|
||||
go func() {
|
||||
c := exec.Command(dockerBinary, "attach", "attacher")
|
||||
cmd := exec.Command(dockerBinary, "attach", "attacher")
|
||||
|
||||
defer func() {
|
||||
c.Wait()
|
||||
cmd.Wait()
|
||||
endGroup.Done()
|
||||
}()
|
||||
|
||||
out, err := c.StdoutPipe()
|
||||
out, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if err := c.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
if err := cmd.Start(); err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
|
||||
if _, err := out.Read(buf); err != nil && err != io.EOF {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
startGroup.Done()
|
||||
|
||||
if !strings.Contains(string(buf), "hello") {
|
||||
t.Fatalf("unexpected output %s expected hello\n", string(buf))
|
||||
c.Fatalf("unexpected output %s expected hello\n", string(buf))
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
@ -72,41 +72,39 @@ func TestAttachMultipleAndRestart(t *testing.T) {
|
|||
select {
|
||||
case <-startDone:
|
||||
case <-time.After(attachWait):
|
||||
t.Fatalf("Attaches did not initialize properly")
|
||||
c.Fatalf("Attaches did not initialize properly")
|
||||
}
|
||||
|
||||
cmd := exec.Command(dockerBinary, "kill", "attacher")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-endDone:
|
||||
case <-time.After(attachWait):
|
||||
t.Fatalf("Attaches did not finish properly")
|
||||
c.Fatalf("Attaches did not finish properly")
|
||||
}
|
||||
|
||||
logDone("attach - multiple attach")
|
||||
}
|
||||
|
||||
func TestAttachTtyWithoutStdin(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestAttachTtyWithoutStdin(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "-d", "-ti", "busybox")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start container: %v (%v)", out, err)
|
||||
c.Fatalf("failed to start container: %v (%v)", out, err)
|
||||
}
|
||||
|
||||
id := strings.TrimSpace(out)
|
||||
if err := waitRun(id); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
cmd := exec.Command(dockerBinary, "kill", id)
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
t.Fatalf("failed to kill container: %v (%v)", out, err)
|
||||
c.Fatalf("failed to kill container: %v (%v)", out, err)
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -116,70 +114,67 @@ func TestAttachTtyWithoutStdin(t *testing.T) {
|
|||
|
||||
cmd := exec.Command(dockerBinary, "attach", id)
|
||||
if _, err := cmd.StdinPipe(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
expected := "cannot enable tty mode"
|
||||
if out, _, err := runCommandWithOutput(cmd); err == nil {
|
||||
t.Fatal("attach should have failed")
|
||||
c.Fatal("attach should have failed")
|
||||
} else if !strings.Contains(out, expected) {
|
||||
t.Fatalf("attach failed with error %q: expected %q", out, expected)
|
||||
c.Fatalf("attach failed with error %q: expected %q", out, expected)
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(attachWait):
|
||||
t.Fatal("attach is running but should have failed")
|
||||
c.Fatal("attach is running but should have failed")
|
||||
}
|
||||
|
||||
logDone("attach - forbid piped stdin to tty enabled container")
|
||||
}
|
||||
|
||||
func TestAttachDisconnect(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
out, _ := dockerCmd(t, "run", "-di", "busybox", "/bin/cat")
|
||||
func (s *DockerSuite) TestAttachDisconnect(c *check.C) {
|
||||
out, _ := dockerCmd(c, "run", "-di", "busybox", "/bin/cat")
|
||||
id := strings.TrimSpace(out)
|
||||
|
||||
cmd := exec.Command(dockerBinary, "attach", id)
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer stdin.Close()
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer stdout.Close()
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
if _, err := stdin.Write([]byte("hello\n")); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
out, err = bufio.NewReader(stdout).ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if strings.TrimSpace(out) != "hello" {
|
||||
t.Fatalf("exepected 'hello', got %q", out)
|
||||
c.Fatalf("exepected 'hello', got %q", out)
|
||||
}
|
||||
|
||||
if err := stdin.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// Expect container to still be running after stdin is closed
|
||||
running, err := inspectField(id, "State.Running")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if running != "true" {
|
||||
t.Fatal("exepected container to still be running")
|
||||
c.Fatal("exepected container to still be running")
|
||||
}
|
||||
|
||||
logDone("attach - disconnect")
|
||||
}
|
||||
|
|
|
@ -6,26 +6,25 @@ import (
|
|||
"bufio"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/go-check/check"
|
||||
"github.com/kr/pty"
|
||||
)
|
||||
|
||||
// #9860
|
||||
func TestAttachClosedOnContainerStop(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "-dti", "busybox", "sleep", "2")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start container: %v (%v)", out, err)
|
||||
c.Fatalf("failed to start container: %v (%v)", out, err)
|
||||
}
|
||||
|
||||
id := strings.TrimSpace(out)
|
||||
if err := waitRun(id); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
done := make(chan struct{})
|
||||
|
@ -35,7 +34,7 @@ func TestAttachClosedOnContainerStop(t *testing.T) {
|
|||
|
||||
_, tty, err := pty.Open()
|
||||
if err != nil {
|
||||
t.Fatalf("could not open pty: %v", err)
|
||||
c.Fatalf("could not open pty: %v", err)
|
||||
}
|
||||
attachCmd := exec.Command(dockerBinary, "attach", id)
|
||||
attachCmd.Stdin = tty
|
||||
|
@ -43,31 +42,29 @@ func TestAttachClosedOnContainerStop(t *testing.T) {
|
|||
attachCmd.Stderr = tty
|
||||
|
||||
if err := attachCmd.Run(); err != nil {
|
||||
t.Fatalf("attach returned error %s", err)
|
||||
c.Fatalf("attach returned error %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
waitCmd := exec.Command(dockerBinary, "wait", id)
|
||||
if out, _, err = runCommandWithOutput(waitCmd); err != nil {
|
||||
t.Fatalf("error thrown while waiting for container: %s, %v", out, err)
|
||||
c.Fatalf("error thrown while waiting for container: %s, %v", out, err)
|
||||
}
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(attachWait):
|
||||
t.Fatal("timed out without attach returning")
|
||||
c.Fatal("timed out without attach returning")
|
||||
}
|
||||
|
||||
logDone("attach - return after container finished")
|
||||
}
|
||||
|
||||
func TestAttachAfterDetach(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestAttachAfterDetach(c *check.C) {
|
||||
|
||||
name := "detachtest"
|
||||
|
||||
cpty, tty, err := pty.Open()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not open pty: %v", err)
|
||||
c.Fatalf("Could not open pty: %v", err)
|
||||
}
|
||||
cmd := exec.Command(dockerBinary, "run", "-ti", "--name", name, "busybox")
|
||||
cmd.Stdin = tty
|
||||
|
@ -77,14 +74,14 @@ func TestAttachAfterDetach(t *testing.T) {
|
|||
detached := make(chan struct{})
|
||||
go func() {
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("attach returned error %s", err)
|
||||
c.Fatalf("attach returned error %s", err)
|
||||
}
|
||||
close(detached)
|
||||
}()
|
||||
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
if err := waitRun(name); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
cpty.Write([]byte{16})
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
@ -94,7 +91,7 @@ func TestAttachAfterDetach(t *testing.T) {
|
|||
|
||||
cpty, tty, err = pty.Open()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not open pty: %v", err)
|
||||
c.Fatalf("Could not open pty: %v", err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "attach", name)
|
||||
|
@ -103,7 +100,7 @@ func TestAttachAfterDetach(t *testing.T) {
|
|||
cmd.Stderr = tty
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
bytes := make([]byte, 10)
|
||||
|
@ -123,34 +120,33 @@ func TestAttachAfterDetach(t *testing.T) {
|
|||
select {
|
||||
case err := <-readErr:
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("timeout waiting for attach read")
|
||||
c.Fatal("timeout waiting for attach read")
|
||||
}
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if !strings.Contains(string(bytes[:nBytes]), "/ #") {
|
||||
t.Fatalf("failed to get a new prompt. got %s", string(bytes[:nBytes]))
|
||||
c.Fatalf("failed to get a new prompt. got %s", string(bytes[:nBytes]))
|
||||
}
|
||||
|
||||
logDone("attach - reconnect after detaching")
|
||||
}
|
||||
|
||||
// TestAttachDetach checks that attach in tty mode can be detached using the long container ID
|
||||
func TestAttachDetach(t *testing.T) {
|
||||
out, _ := dockerCmd(t, "run", "-itd", "busybox", "cat")
|
||||
func (s *DockerSuite) TestAttachDetach(c *check.C) {
|
||||
out, _ := dockerCmd(c, "run", "-itd", "busybox", "cat")
|
||||
id := strings.TrimSpace(out)
|
||||
if err := waitRun(id); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cpty, tty, err := pty.Open()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer cpty.Close()
|
||||
|
||||
|
@ -158,34 +154,34 @@ func TestAttachDetach(t *testing.T) {
|
|||
cmd.Stdin = tty
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer stdout.Close()
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if err := waitRun(id); err != nil {
|
||||
t.Fatalf("error waiting for container to start: %v", err)
|
||||
c.Fatalf("error waiting for container to start: %v", err)
|
||||
}
|
||||
|
||||
if _, err := cpty.Write([]byte("hello\n")); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
out, err = bufio.NewReader(stdout).ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if strings.TrimSpace(out) != "hello" {
|
||||
t.Fatalf("exepected 'hello', got %q", out)
|
||||
c.Fatalf("exepected 'hello', got %q", out)
|
||||
}
|
||||
|
||||
// escape sequence
|
||||
if _, err := cpty.Write([]byte{16}); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
if _, err := cpty.Write([]byte{17}); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
ch := make(chan struct{})
|
||||
|
@ -196,36 +192,35 @@ func TestAttachDetach(t *testing.T) {
|
|||
|
||||
running, err := inspectField(id, "State.Running")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if running != "true" {
|
||||
t.Fatal("exepected container to still be running")
|
||||
c.Fatal("exepected container to still be running")
|
||||
}
|
||||
|
||||
go func() {
|
||||
dockerCmd(t, "kill", id)
|
||||
dockerCmd(c, "kill", id)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ch:
|
||||
case <-time.After(10 * time.Millisecond):
|
||||
t.Fatal("timed out waiting for container to exit")
|
||||
c.Fatal("timed out waiting for container to exit")
|
||||
}
|
||||
|
||||
logDone("attach - detach")
|
||||
}
|
||||
|
||||
// TestAttachDetachTruncatedID checks that attach in tty mode can be detached
|
||||
func TestAttachDetachTruncatedID(t *testing.T) {
|
||||
out, _ := dockerCmd(t, "run", "-itd", "busybox", "cat")
|
||||
func (s *DockerSuite) TestAttachDetachTruncatedID(c *check.C) {
|
||||
out, _ := dockerCmd(c, "run", "-itd", "busybox", "cat")
|
||||
id := stringid.TruncateID(strings.TrimSpace(out))
|
||||
if err := waitRun(id); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cpty, tty, err := pty.Open()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer cpty.Close()
|
||||
|
||||
|
@ -233,31 +228,31 @@ func TestAttachDetachTruncatedID(t *testing.T) {
|
|||
cmd.Stdin = tty
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer stdout.Close()
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := cpty.Write([]byte("hello\n")); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
out, err = bufio.NewReader(stdout).ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if strings.TrimSpace(out) != "hello" {
|
||||
t.Fatalf("exepected 'hello', got %q", out)
|
||||
c.Fatalf("exepected 'hello', got %q", out)
|
||||
}
|
||||
|
||||
// escape sequence
|
||||
if _, err := cpty.Write([]byte{16}); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
if _, err := cpty.Write([]byte{17}); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
ch := make(chan struct{})
|
||||
|
@ -268,21 +263,20 @@ func TestAttachDetachTruncatedID(t *testing.T) {
|
|||
|
||||
running, err := inspectField(id, "State.Running")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if running != "true" {
|
||||
t.Fatal("exepected container to still be running")
|
||||
c.Fatal("exepected container to still be running")
|
||||
}
|
||||
|
||||
go func() {
|
||||
dockerCmd(t, "kill", id)
|
||||
dockerCmd(c, "kill", id)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ch:
|
||||
case <-time.After(10 * time.Millisecond):
|
||||
t.Fatal("timed out waiting for container to exit")
|
||||
c.Fatal("timed out waiting for container to exit")
|
||||
}
|
||||
|
||||
logDone("attach - detach truncated ID")
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,9 +5,9 @@ import (
|
|||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/utils"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -22,15 +22,15 @@ func setupImage() (string, error) {
|
|||
func setupImageWithTag(tag string) (string, error) {
|
||||
containerName := "busyboxbydigest"
|
||||
|
||||
c := exec.Command(dockerBinary, "run", "-d", "-e", "digest=1", "--name", containerName, "busybox")
|
||||
if _, err := runCommand(c); err != nil {
|
||||
cmd := exec.Command(dockerBinary, "run", "-d", "-e", "digest=1", "--name", containerName, "busybox")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// tag the image to upload it to the private registry
|
||||
repoAndTag := utils.ImageReference(repoName, tag)
|
||||
c = exec.Command(dockerBinary, "commit", containerName, repoAndTag)
|
||||
if out, _, err := runCommandWithOutput(c); err != nil {
|
||||
cmd = exec.Command(dockerBinary, "commit", containerName, repoAndTag)
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
return "", fmt.Errorf("image tagging failed: %s, %v", out, err)
|
||||
}
|
||||
defer deleteImages(repoAndTag)
|
||||
|
@ -41,15 +41,15 @@ func setupImageWithTag(tag string) (string, error) {
|
|||
}
|
||||
|
||||
// push the image
|
||||
c = exec.Command(dockerBinary, "push", repoAndTag)
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "push", repoAndTag)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("pushing the image to the private registry has failed: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// delete our local repo that we previously tagged
|
||||
c = exec.Command(dockerBinary, "rmi", repoAndTag)
|
||||
if out, _, err := runCommandWithOutput(c); err != nil {
|
||||
cmd = exec.Command(dockerBinary, "rmi", repoAndTag)
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
return "", fmt.Errorf("error deleting images prior to real test: %s, %v", out, err)
|
||||
}
|
||||
|
||||
|
@ -63,194 +63,189 @@ func setupImageWithTag(tag string) (string, error) {
|
|||
return pushDigest, nil
|
||||
}
|
||||
|
||||
func TestPullByTagDisplaysDigest(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestPullByTagDisplaysDigest(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
pushDigest, err := setupImage()
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up image: %v", err)
|
||||
c.Fatalf("error setting up image: %v", err)
|
||||
}
|
||||
|
||||
// pull from the registry using the tag
|
||||
c := exec.Command(dockerBinary, "pull", repoName)
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
cmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error pulling by tag: %s, %v", out, err)
|
||||
c.Fatalf("error pulling by tag: %s, %v", out, err)
|
||||
}
|
||||
defer deleteImages(repoName)
|
||||
|
||||
// the pull output includes "Digest: <digest>", so find that
|
||||
matches := digestRegex.FindStringSubmatch(out)
|
||||
if len(matches) != 2 {
|
||||
t.Fatalf("unable to parse digest from pull output: %s", out)
|
||||
c.Fatalf("unable to parse digest from pull output: %s", out)
|
||||
}
|
||||
pullDigest := matches[1]
|
||||
|
||||
// make sure the pushed and pull digests match
|
||||
if pushDigest != pullDigest {
|
||||
t.Fatalf("push digest %q didn't match pull digest %q", pushDigest, pullDigest)
|
||||
c.Fatalf("push digest %q didn't match pull digest %q", pushDigest, pullDigest)
|
||||
}
|
||||
|
||||
logDone("by_digest - pull by tag displays digest")
|
||||
}
|
||||
|
||||
func TestPullByDigest(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestPullByDigest(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
pushDigest, err := setupImage()
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up image: %v", err)
|
||||
c.Fatalf("error setting up image: %v", err)
|
||||
}
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest)
|
||||
c := exec.Command(dockerBinary, "pull", imageReference)
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
cmd := exec.Command(dockerBinary, "pull", imageReference)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
c.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
}
|
||||
defer deleteImages(imageReference)
|
||||
|
||||
// the pull output includes "Digest: <digest>", so find that
|
||||
matches := digestRegex.FindStringSubmatch(out)
|
||||
if len(matches) != 2 {
|
||||
t.Fatalf("unable to parse digest from pull output: %s", out)
|
||||
c.Fatalf("unable to parse digest from pull output: %s", out)
|
||||
}
|
||||
pullDigest := matches[1]
|
||||
|
||||
// make sure the pushed and pull digests match
|
||||
if pushDigest != pullDigest {
|
||||
t.Fatalf("push digest %q didn't match pull digest %q", pushDigest, pullDigest)
|
||||
c.Fatalf("push digest %q didn't match pull digest %q", pushDigest, pullDigest)
|
||||
}
|
||||
|
||||
logDone("by_digest - pull by digest")
|
||||
}
|
||||
|
||||
func TestCreateByDigest(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestCreateByDigest(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
pushDigest, err := setupImage()
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up image: %v", err)
|
||||
c.Fatalf("error setting up image: %v", err)
|
||||
}
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest)
|
||||
|
||||
containerName := "createByDigest"
|
||||
c := exec.Command(dockerBinary, "create", "--name", containerName, imageReference)
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
cmd := exec.Command(dockerBinary, "create", "--name", containerName, imageReference)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating by digest: %s, %v", out, err)
|
||||
c.Fatalf("error creating by digest: %s, %v", out, err)
|
||||
}
|
||||
defer deleteContainer(containerName)
|
||||
|
||||
res, err := inspectField(containerName, "Config.Image")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get Config.Image: %s, %v", out, err)
|
||||
c.Fatalf("failed to get Config.Image: %s, %v", out, err)
|
||||
}
|
||||
if res != imageReference {
|
||||
t.Fatalf("unexpected Config.Image: %s (expected %s)", res, imageReference)
|
||||
c.Fatalf("unexpected Config.Image: %s (expected %s)", res, imageReference)
|
||||
}
|
||||
|
||||
logDone("by_digest - create by digest")
|
||||
}
|
||||
|
||||
func TestRunByDigest(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestRunByDigest(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
pushDigest, err := setupImage()
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up image: %v", err)
|
||||
c.Fatalf("error setting up image: %v", err)
|
||||
}
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest)
|
||||
|
||||
containerName := "runByDigest"
|
||||
c := exec.Command(dockerBinary, "run", "--name", containerName, imageReference, "sh", "-c", "echo found=$digest")
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
cmd := exec.Command(dockerBinary, "run", "--name", containerName, imageReference, "sh", "-c", "echo found=$digest")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error run by digest: %s, %v", out, err)
|
||||
c.Fatalf("error run by digest: %s, %v", out, err)
|
||||
}
|
||||
defer deleteContainer(containerName)
|
||||
|
||||
foundRegex := regexp.MustCompile("found=([^\n]+)")
|
||||
matches := foundRegex.FindStringSubmatch(out)
|
||||
if len(matches) != 2 {
|
||||
t.Fatalf("error locating expected 'found=1' output: %s", out)
|
||||
c.Fatalf("error locating expected 'found=1' output: %s", out)
|
||||
}
|
||||
if matches[1] != "1" {
|
||||
t.Fatalf("Expected %q, got %q", "1", matches[1])
|
||||
c.Fatalf("Expected %q, got %q", "1", matches[1])
|
||||
}
|
||||
|
||||
res, err := inspectField(containerName, "Config.Image")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get Config.Image: %s, %v", out, err)
|
||||
c.Fatalf("failed to get Config.Image: %s, %v", out, err)
|
||||
}
|
||||
if res != imageReference {
|
||||
t.Fatalf("unexpected Config.Image: %s (expected %s)", res, imageReference)
|
||||
c.Fatalf("unexpected Config.Image: %s (expected %s)", res, imageReference)
|
||||
}
|
||||
|
||||
logDone("by_digest - run by digest")
|
||||
}
|
||||
|
||||
func TestRemoveImageByDigest(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestRemoveImageByDigest(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
digest, err := setupImage()
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up image: %v", err)
|
||||
c.Fatalf("error setting up image: %v", err)
|
||||
}
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, digest)
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
c := exec.Command(dockerBinary, "pull", imageReference)
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
cmd := exec.Command(dockerBinary, "pull", imageReference)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
c.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// make sure inspect runs ok
|
||||
if _, err := inspectField(imageReference, "Id"); err != nil {
|
||||
t.Fatalf("failed to inspect image: %v", err)
|
||||
c.Fatalf("failed to inspect image: %v", err)
|
||||
}
|
||||
|
||||
// do the delete
|
||||
if err := deleteImages(imageReference); err != nil {
|
||||
t.Fatalf("unexpected error deleting image: %v", err)
|
||||
c.Fatalf("unexpected error deleting image: %v", err)
|
||||
}
|
||||
|
||||
// try to inspect again - it should error this time
|
||||
if _, err := inspectField(imageReference, "Id"); err == nil {
|
||||
t.Fatalf("unexpected nil err trying to inspect what should be a non-existent image")
|
||||
c.Fatalf("unexpected nil err trying to inspect what should be a non-existent image")
|
||||
} else if !strings.Contains(err.Error(), "No such image") {
|
||||
t.Fatalf("expected 'No such image' output, got %v", err)
|
||||
c.Fatalf("expected 'No such image' output, got %v", err)
|
||||
}
|
||||
|
||||
logDone("by_digest - remove image by digest")
|
||||
}
|
||||
|
||||
func TestBuildByDigest(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestBuildByDigest(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
digest, err := setupImage()
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up image: %v", err)
|
||||
c.Fatalf("error setting up image: %v", err)
|
||||
}
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, digest)
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
c := exec.Command(dockerBinary, "pull", imageReference)
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
cmd := exec.Command(dockerBinary, "pull", imageReference)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
c.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// get the image id
|
||||
imageID, err := inspectField(imageReference, "Id")
|
||||
if err != nil {
|
||||
t.Fatalf("error getting image id: %v", err)
|
||||
c.Fatalf("error getting image id: %v", err)
|
||||
}
|
||||
|
||||
// do the build
|
||||
|
@ -261,275 +256,270 @@ func TestBuildByDigest(t *testing.T) {
|
|||
CMD ["/bin/echo", "Hello World"]`, imageReference),
|
||||
true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// get the build's image id
|
||||
res, err := inspectField(name, "Config.Image")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
// make sure they match
|
||||
if res != imageID {
|
||||
t.Fatalf("Image %s, expected %s", res, imageID)
|
||||
c.Fatalf("Image %s, expected %s", res, imageID)
|
||||
}
|
||||
|
||||
logDone("by_digest - build by digest")
|
||||
}
|
||||
|
||||
func TestTagByDigest(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestTagByDigest(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
digest, err := setupImage()
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up image: %v", err)
|
||||
c.Fatalf("error setting up image: %v", err)
|
||||
}
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, digest)
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
c := exec.Command(dockerBinary, "pull", imageReference)
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
cmd := exec.Command(dockerBinary, "pull", imageReference)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
c.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// tag it
|
||||
tag := "tagbydigest"
|
||||
c = exec.Command(dockerBinary, "tag", imageReference, tag)
|
||||
if _, err := runCommand(c); err != nil {
|
||||
t.Fatalf("unexpected error tagging: %v", err)
|
||||
cmd = exec.Command(dockerBinary, "tag", imageReference, tag)
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
c.Fatalf("unexpected error tagging: %v", err)
|
||||
}
|
||||
|
||||
expectedID, err := inspectField(imageReference, "Id")
|
||||
if err != nil {
|
||||
t.Fatalf("error getting original image id: %v", err)
|
||||
c.Fatalf("error getting original image id: %v", err)
|
||||
}
|
||||
|
||||
tagID, err := inspectField(tag, "Id")
|
||||
if err != nil {
|
||||
t.Fatalf("error getting tagged image id: %v", err)
|
||||
c.Fatalf("error getting tagged image id: %v", err)
|
||||
}
|
||||
|
||||
if tagID != expectedID {
|
||||
t.Fatalf("expected image id %q, got %q", expectedID, tagID)
|
||||
c.Fatalf("expected image id %q, got %q", expectedID, tagID)
|
||||
}
|
||||
|
||||
logDone("by_digest - tag by digest")
|
||||
}
|
||||
|
||||
func TestListImagesWithoutDigests(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestListImagesWithoutDigests(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
digest, err := setupImage()
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up image: %v", err)
|
||||
c.Fatalf("error setting up image: %v", err)
|
||||
}
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, digest)
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
c := exec.Command(dockerBinary, "pull", imageReference)
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
cmd := exec.Command(dockerBinary, "pull", imageReference)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
c.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
}
|
||||
|
||||
c = exec.Command(dockerBinary, "images")
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "images")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error listing images: %s, %v", out, err)
|
||||
c.Fatalf("error listing images: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if strings.Contains(out, "DIGEST") {
|
||||
t.Fatalf("list output should not have contained DIGEST header: %s", out)
|
||||
c.Fatalf("list output should not have contained DIGEST header: %s", out)
|
||||
}
|
||||
|
||||
logDone("by_digest - list images - digest header not displayed by default")
|
||||
}
|
||||
|
||||
func TestListImagesWithDigests(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestListImagesWithDigests(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
defer deleteImages(repoName+":tag1", repoName+":tag2")
|
||||
|
||||
// setup image1
|
||||
digest1, err := setupImageWithTag("tag1")
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up image: %v", err)
|
||||
c.Fatalf("error setting up image: %v", err)
|
||||
}
|
||||
imageReference1 := fmt.Sprintf("%s@%s", repoName, digest1)
|
||||
defer deleteImages(imageReference1)
|
||||
t.Logf("imageReference1 = %s", imageReference1)
|
||||
c.Logf("imageReference1 = %s", imageReference1)
|
||||
|
||||
// pull image1 by digest
|
||||
c := exec.Command(dockerBinary, "pull", imageReference1)
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
cmd := exec.Command(dockerBinary, "pull", imageReference1)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
c.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// list images
|
||||
c = exec.Command(dockerBinary, "images", "--digests")
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "images", "--digests")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error listing images: %s, %v", out, err)
|
||||
c.Fatalf("error listing images: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// make sure repo shown, tag=<none>, digest = $digest1
|
||||
re1 := regexp.MustCompile(`\s*` + repoName + `\s*<none>\s*` + digest1 + `\s`)
|
||||
if !re1.MatchString(out) {
|
||||
t.Fatalf("expected %q: %s", re1.String(), out)
|
||||
c.Fatalf("expected %q: %s", re1.String(), out)
|
||||
}
|
||||
|
||||
// setup image2
|
||||
digest2, err := setupImageWithTag("tag2")
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up image: %v", err)
|
||||
c.Fatalf("error setting up image: %v", err)
|
||||
}
|
||||
imageReference2 := fmt.Sprintf("%s@%s", repoName, digest2)
|
||||
defer deleteImages(imageReference2)
|
||||
t.Logf("imageReference2 = %s", imageReference2)
|
||||
c.Logf("imageReference2 = %s", imageReference2)
|
||||
|
||||
// pull image1 by digest
|
||||
c = exec.Command(dockerBinary, "pull", imageReference1)
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "pull", imageReference1)
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
c.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// pull image2 by digest
|
||||
c = exec.Command(dockerBinary, "pull", imageReference2)
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "pull", imageReference2)
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
c.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// list images
|
||||
c = exec.Command(dockerBinary, "images", "--digests")
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "images", "--digests")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error listing images: %s, %v", out, err)
|
||||
c.Fatalf("error listing images: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// make sure repo shown, tag=<none>, digest = $digest1
|
||||
if !re1.MatchString(out) {
|
||||
t.Fatalf("expected %q: %s", re1.String(), out)
|
||||
c.Fatalf("expected %q: %s", re1.String(), out)
|
||||
}
|
||||
|
||||
// make sure repo shown, tag=<none>, digest = $digest2
|
||||
re2 := regexp.MustCompile(`\s*` + repoName + `\s*<none>\s*` + digest2 + `\s`)
|
||||
if !re2.MatchString(out) {
|
||||
t.Fatalf("expected %q: %s", re2.String(), out)
|
||||
c.Fatalf("expected %q: %s", re2.String(), out)
|
||||
}
|
||||
|
||||
// pull tag1
|
||||
c = exec.Command(dockerBinary, "pull", repoName+":tag1")
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "pull", repoName+":tag1")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error pulling tag1: %s, %v", out, err)
|
||||
c.Fatalf("error pulling tag1: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// list images
|
||||
c = exec.Command(dockerBinary, "images", "--digests")
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "images", "--digests")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error listing images: %s, %v", out, err)
|
||||
c.Fatalf("error listing images: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// make sure image 1 has repo, tag, <none> AND repo, <none>, digest
|
||||
reWithTag1 := regexp.MustCompile(`\s*` + repoName + `\s*tag1\s*<none>\s`)
|
||||
reWithDigest1 := regexp.MustCompile(`\s*` + repoName + `\s*<none>\s*` + digest1 + `\s`)
|
||||
if !reWithTag1.MatchString(out) {
|
||||
t.Fatalf("expected %q: %s", reWithTag1.String(), out)
|
||||
c.Fatalf("expected %q: %s", reWithTag1.String(), out)
|
||||
}
|
||||
if !reWithDigest1.MatchString(out) {
|
||||
t.Fatalf("expected %q: %s", reWithDigest1.String(), out)
|
||||
c.Fatalf("expected %q: %s", reWithDigest1.String(), out)
|
||||
}
|
||||
// make sure image 2 has repo, <none>, digest
|
||||
if !re2.MatchString(out) {
|
||||
t.Fatalf("expected %q: %s", re2.String(), out)
|
||||
c.Fatalf("expected %q: %s", re2.String(), out)
|
||||
}
|
||||
|
||||
// pull tag 2
|
||||
c = exec.Command(dockerBinary, "pull", repoName+":tag2")
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "pull", repoName+":tag2")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error pulling tag2: %s, %v", out, err)
|
||||
c.Fatalf("error pulling tag2: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// list images
|
||||
c = exec.Command(dockerBinary, "images", "--digests")
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "images", "--digests")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error listing images: %s, %v", out, err)
|
||||
c.Fatalf("error listing images: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// make sure image 1 has repo, tag, digest
|
||||
if !reWithTag1.MatchString(out) {
|
||||
t.Fatalf("expected %q: %s", re1.String(), out)
|
||||
c.Fatalf("expected %q: %s", re1.String(), out)
|
||||
}
|
||||
|
||||
// make sure image 2 has repo, tag, digest
|
||||
reWithTag2 := regexp.MustCompile(`\s*` + repoName + `\s*tag2\s*<none>\s`)
|
||||
reWithDigest2 := regexp.MustCompile(`\s*` + repoName + `\s*<none>\s*` + digest2 + `\s`)
|
||||
if !reWithTag2.MatchString(out) {
|
||||
t.Fatalf("expected %q: %s", reWithTag2.String(), out)
|
||||
c.Fatalf("expected %q: %s", reWithTag2.String(), out)
|
||||
}
|
||||
if !reWithDigest2.MatchString(out) {
|
||||
t.Fatalf("expected %q: %s", reWithDigest2.String(), out)
|
||||
c.Fatalf("expected %q: %s", reWithDigest2.String(), out)
|
||||
}
|
||||
|
||||
// list images
|
||||
c = exec.Command(dockerBinary, "images", "--digests")
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "images", "--digests")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error listing images: %s, %v", out, err)
|
||||
c.Fatalf("error listing images: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// make sure image 1 has repo, tag, digest
|
||||
if !reWithTag1.MatchString(out) {
|
||||
t.Fatalf("expected %q: %s", re1.String(), out)
|
||||
c.Fatalf("expected %q: %s", re1.String(), out)
|
||||
}
|
||||
// make sure image 2 has repo, tag, digest
|
||||
if !reWithTag2.MatchString(out) {
|
||||
t.Fatalf("expected %q: %s", re2.String(), out)
|
||||
c.Fatalf("expected %q: %s", re2.String(), out)
|
||||
}
|
||||
// make sure busybox has tag, but not digest
|
||||
busyboxRe := regexp.MustCompile(`\s*busybox\s*latest\s*<none>\s`)
|
||||
if !busyboxRe.MatchString(out) {
|
||||
t.Fatalf("expected %q: %s", busyboxRe.String(), out)
|
||||
c.Fatalf("expected %q: %s", busyboxRe.String(), out)
|
||||
}
|
||||
|
||||
logDone("by_digest - list images with digests")
|
||||
}
|
||||
|
||||
func TestDeleteImageByIDOnlyPulledByDigest(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestDeleteImageByIDOnlyPulledByDigest(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
pushDigest, err := setupImage()
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up image: %v", err)
|
||||
c.Fatalf("error setting up image: %v", err)
|
||||
}
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest)
|
||||
c := exec.Command(dockerBinary, "pull", imageReference)
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
cmd := exec.Command(dockerBinary, "pull", imageReference)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
c.Fatalf("error pulling by digest: %s, %v", out, err)
|
||||
}
|
||||
// just in case...
|
||||
defer deleteImages(imageReference)
|
||||
|
||||
imageID, err := inspectField(imageReference, ".Id")
|
||||
if err != nil {
|
||||
t.Fatalf("error inspecting image id: %v", err)
|
||||
c.Fatalf("error inspecting image id: %v", err)
|
||||
}
|
||||
|
||||
c = exec.Command(dockerBinary, "rmi", imageID)
|
||||
if _, err := runCommand(c); err != nil {
|
||||
t.Fatalf("error deleting image by id: %v", err)
|
||||
cmd = exec.Command(dockerBinary, "rmi", imageID)
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
c.Fatalf("error deleting image by id: %v", err)
|
||||
}
|
||||
|
||||
logDone("by_digest - delete image by id only pulled by digest")
|
||||
}
|
||||
|
|
|
@ -3,96 +3,94 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestCommitAfterContainerIsDone(t *testing.T) {
|
||||
func (s *DockerSuite) TestCommitAfterContainerIsDone(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-i", "-a", "stdin", "busybox", "echo", "foo")
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run container: %s, %v", out, err)
|
||||
c.Fatalf("failed to run container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
waitCmd := exec.Command(dockerBinary, "wait", cleanedContainerID)
|
||||
if _, _, err = runCommandWithOutput(waitCmd); err != nil {
|
||||
t.Fatalf("error thrown while waiting for container: %s, %v", out, err)
|
||||
c.Fatalf("error thrown while waiting for container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(commitCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit container to image: %s, %v", out, err)
|
||||
c.Fatalf("failed to commit container to image: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
|
||||
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedImageID)
|
||||
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
|
||||
t.Fatalf("failed to inspect image: %s, %v", out, err)
|
||||
c.Fatalf("failed to inspect image: %s, %v", out, err)
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
deleteImages(cleanedImageID)
|
||||
|
||||
logDone("commit - echo foo and commit the image")
|
||||
}
|
||||
|
||||
func TestCommitWithoutPause(t *testing.T) {
|
||||
func (s *DockerSuite) TestCommitWithoutPause(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-i", "-a", "stdin", "busybox", "echo", "foo")
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run container: %s, %v", out, err)
|
||||
c.Fatalf("failed to run container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
waitCmd := exec.Command(dockerBinary, "wait", cleanedContainerID)
|
||||
if _, _, err = runCommandWithOutput(waitCmd); err != nil {
|
||||
t.Fatalf("error thrown while waiting for container: %s, %v", out, err)
|
||||
c.Fatalf("error thrown while waiting for container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
commitCmd := exec.Command(dockerBinary, "commit", "-p=false", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(commitCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit container to image: %s, %v", out, err)
|
||||
c.Fatalf("failed to commit container to image: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
|
||||
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedImageID)
|
||||
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
|
||||
t.Fatalf("failed to inspect image: %s, %v", out, err)
|
||||
c.Fatalf("failed to inspect image: %s, %v", out, err)
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
deleteImages(cleanedImageID)
|
||||
|
||||
logDone("commit - echo foo and commit the image with --pause=false")
|
||||
}
|
||||
|
||||
//test commit a paused container should not unpause it after commit
|
||||
func TestCommitPausedContainer(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestCommitPausedContainer(c *check.C) {
|
||||
defer unpauseAllContainers()
|
||||
cmd := exec.Command(dockerBinary, "run", "-i", "-d", "busybox")
|
||||
out, _, _, err := runCommandWithStdoutStderr(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run container: %v, output: %q", err, out)
|
||||
c.Fatalf("failed to run container: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
cmd = exec.Command(dockerBinary, "pause", cleanedContainerID)
|
||||
out, _, _, err = runCommandWithStdoutStderr(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to pause container: %v, output: %q", err, out)
|
||||
c.Fatalf("failed to pause container: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(commitCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit container to image: %s, %v", out, err)
|
||||
c.Fatalf("failed to commit container to image: %s, %v", out, err)
|
||||
}
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
defer deleteImages(cleanedImageID)
|
||||
|
@ -100,28 +98,26 @@ func TestCommitPausedContainer(t *testing.T) {
|
|||
cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Paused}}", cleanedContainerID)
|
||||
out, _, _, err = runCommandWithStdoutStderr(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to inspect container: %v, output: %q", err, out)
|
||||
c.Fatalf("failed to inspect container: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
if !strings.Contains(out, "true") {
|
||||
t.Fatalf("commit should not unpause a paused container")
|
||||
c.Fatalf("commit should not unpause a paused container")
|
||||
}
|
||||
|
||||
logDone("commit - commit a paused container will not unpause it")
|
||||
}
|
||||
|
||||
func TestCommitNewFile(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestCommitNewFile(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "--name", "commiter", "busybox", "/bin/sh", "-c", "echo koye > /foo")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "commit", "commiter")
|
||||
imageID, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
imageID = strings.Trim(imageID, "\r\n")
|
||||
defer deleteImages(imageID)
|
||||
|
@ -130,22 +126,20 @@ func TestCommitNewFile(t *testing.T) {
|
|||
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
if actual := strings.Trim(out, "\r\n"); actual != "koye" {
|
||||
t.Fatalf("expected output koye received %q", actual)
|
||||
c.Fatalf("expected output koye received %q", actual)
|
||||
}
|
||||
|
||||
logDone("commit - commit file and read")
|
||||
}
|
||||
|
||||
func TestCommitHardlink(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestCommitHardlink(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "-t", "--name", "hardlinks", "busybox", "sh", "-c", "touch file1 && ln file1 file2 && ls -di file1 file2")
|
||||
firstOuput, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
chunks := strings.Split(strings.TrimSpace(firstOuput), " ")
|
||||
|
@ -158,13 +152,13 @@ func TestCommitHardlink(t *testing.T) {
|
|||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("Failed to create hardlink in a container. Expected to find %q in %q", inode, chunks[1:])
|
||||
c.Fatalf("Failed to create hardlink in a container. Expected to find %q in %q", inode, chunks[1:])
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "commit", "hardlinks", "hardlinks")
|
||||
imageID, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(imageID, err)
|
||||
c.Fatal(imageID, err)
|
||||
}
|
||||
imageID = strings.Trim(imageID, "\r\n")
|
||||
defer deleteImages(imageID)
|
||||
|
@ -172,7 +166,7 @@ func TestCommitHardlink(t *testing.T) {
|
|||
cmd = exec.Command(dockerBinary, "run", "-t", "hardlinks", "ls", "-di", "file1", "file2")
|
||||
secondOuput, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
chunks = strings.Split(strings.TrimSpace(secondOuput), " ")
|
||||
|
@ -185,48 +179,44 @@ func TestCommitHardlink(t *testing.T) {
|
|||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("Failed to create hardlink in a container. Expected to find %q in %q", inode, chunks[1:])
|
||||
c.Fatalf("Failed to create hardlink in a container. Expected to find %q in %q", inode, chunks[1:])
|
||||
}
|
||||
|
||||
logDone("commit - commit hardlinks")
|
||||
}
|
||||
|
||||
func TestCommitTTY(t *testing.T) {
|
||||
func (s *DockerSuite) TestCommitTTY(c *check.C) {
|
||||
defer deleteImages("ttytest")
|
||||
defer deleteAllContainers()
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "-t", "--name", "tty", "busybox", "/bin/ls")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "commit", "tty", "ttytest")
|
||||
imageID, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
imageID = strings.Trim(imageID, "\r\n")
|
||||
|
||||
cmd = exec.Command(dockerBinary, "run", "ttytest", "/bin/ls")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
logDone("commit - commit tty")
|
||||
}
|
||||
|
||||
func TestCommitWithHostBindMount(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestCommitWithHostBindMount(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "--name", "bind-commit", "-v", "/dev/null:/winning", "busybox", "true")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "commit", "bind-commit", "bindtest")
|
||||
imageID, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(imageID, err)
|
||||
c.Fatal(imageID, err)
|
||||
}
|
||||
|
||||
imageID = strings.Trim(imageID, "\r\n")
|
||||
|
@ -235,18 +225,16 @@ func TestCommitWithHostBindMount(t *testing.T) {
|
|||
cmd = exec.Command(dockerBinary, "run", "bindtest", "true")
|
||||
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
logDone("commit - commit bind mounted file")
|
||||
}
|
||||
|
||||
func TestCommitChange(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestCommitChange(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "--name", "test", "busybox", "true")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "commit",
|
||||
|
@ -257,7 +245,7 @@ func TestCommitChange(t *testing.T) {
|
|||
"test", "test-commit")
|
||||
imageId, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(imageId, err)
|
||||
c.Fatal(imageId, err)
|
||||
}
|
||||
imageId = strings.Trim(imageId, "\r\n")
|
||||
defer deleteImages(imageId)
|
||||
|
@ -270,29 +258,27 @@ func TestCommitChange(t *testing.T) {
|
|||
for conf, value := range expected {
|
||||
res, err := inspectField(imageId, conf)
|
||||
if err != nil {
|
||||
t.Errorf("failed to get value %s, error: %s", conf, err)
|
||||
c.Errorf("failed to get value %s, error: %s", conf, err)
|
||||
}
|
||||
if res != value {
|
||||
t.Errorf("%s('%s'), expected %s", conf, res, value)
|
||||
c.Errorf("%s('%s'), expected %s", conf, res, value)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("commit - commit --change")
|
||||
}
|
||||
|
||||
// TODO: commit --run is deprecated, remove this once --run is removed
|
||||
func TestCommitMergeConfigRun(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestCommitMergeConfigRun(c *check.C) {
|
||||
name := "commit-test"
|
||||
out, _ := dockerCmd(t, "run", "-d", "-e=FOO=bar", "busybox", "/bin/sh", "-c", "echo testing > /tmp/foo")
|
||||
out, _ := dockerCmd(c, "run", "-d", "-e=FOO=bar", "busybox", "/bin/sh", "-c", "echo testing > /tmp/foo")
|
||||
id := strings.TrimSpace(out)
|
||||
|
||||
dockerCmd(t, "commit", `--run={"Cmd": ["cat", "/tmp/foo"]}`, id, "commit-test")
|
||||
dockerCmd(c, "commit", `--run={"Cmd": ["cat", "/tmp/foo"]}`, id, "commit-test")
|
||||
defer deleteImages("commit-test")
|
||||
|
||||
out, _ = dockerCmd(t, "run", "--name", name, "commit-test")
|
||||
out, _ = dockerCmd(c, "run", "--name", name, "commit-test")
|
||||
if strings.TrimSpace(out) != "testing" {
|
||||
t.Fatal("run config in commited container was not merged")
|
||||
c.Fatal("run config in commited container was not merged")
|
||||
}
|
||||
|
||||
type cfg struct {
|
||||
|
@ -301,11 +287,11 @@ func TestCommitMergeConfigRun(t *testing.T) {
|
|||
}
|
||||
config1 := cfg{}
|
||||
if err := inspectFieldAndMarshall(id, "Config", &config1); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
config2 := cfg{}
|
||||
if err := inspectFieldAndMarshall(name, "Config", &config2); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// Env has at least PATH loaded as well here, so let's just grab the FOO one
|
||||
|
@ -324,8 +310,7 @@ func TestCommitMergeConfigRun(t *testing.T) {
|
|||
}
|
||||
|
||||
if len(config1.Env) != len(config2.Env) || env1 != env2 && env2 != "" {
|
||||
t.Fatalf("expected envs to match: %v - %v", config1.Env, config2.Env)
|
||||
c.Fatalf("expected envs to match: %v - %v", config1.Env, config2.Env)
|
||||
}
|
||||
|
||||
logDone("commit - configs are merged with --run")
|
||||
}
|
||||
|
|
|
@ -7,13 +7,13 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/pkg/homedir"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestConfigHttpHeader(t *testing.T) {
|
||||
testRequires(t, UnixCli) // Can't set/unset HOME on windows right now
|
||||
func (s *DockerSuite) TestConfigHttpHeader(c *check.C) {
|
||||
testRequires(c, UnixCli) // Can't set/unset HOME on windows right now
|
||||
// We either need a level of Go that supports Unsetenv (for cases
|
||||
// when HOME/USERPROFILE isn't set), or we need to be able to use
|
||||
// os/user but user.Current() only works if we aren't statically compiling
|
||||
|
@ -44,15 +44,13 @@ func TestConfigHttpHeader(t *testing.T) {
|
|||
|
||||
err := ioutil.WriteFile(tmpCfg, []byte(data), 0600)
|
||||
if err != nil {
|
||||
t.Fatalf("Err creating file(%s): %v", tmpCfg, err)
|
||||
c.Fatalf("Err creating file(%s): %v", tmpCfg, err)
|
||||
}
|
||||
|
||||
cmd := exec.Command(dockerBinary, "-H="+server.URL[7:], "ps")
|
||||
out, _, _ := runCommandWithOutput(cmd)
|
||||
|
||||
if headers["Myheader"] == nil || headers["Myheader"][0] != "MyValue" {
|
||||
t.Fatalf("Missing/bad header: %q\nout:%v", headers, out)
|
||||
c.Fatalf("Missing/bad header: %q\nout:%v", headers, out)
|
||||
}
|
||||
|
||||
logDone("config - add new http headers")
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ import (
|
|||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -24,27 +25,27 @@ const (
|
|||
|
||||
// Test for #5656
|
||||
// Check that garbage paths don't escape the container's rootfs
|
||||
func TestCpGarbagePath(t *testing.T) {
|
||||
out, exitCode := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
|
||||
func (s *DockerSuite) TestCpGarbagePath(c *check.C) {
|
||||
out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
|
||||
if exitCode != 0 {
|
||||
t.Fatal("failed to create a container", out)
|
||||
c.Fatal("failed to create a container", out)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
defer deleteContainer(cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(t, "wait", cleanedContainerID)
|
||||
out, _ = dockerCmd(c, "wait", cleanedContainerID)
|
||||
if strings.TrimSpace(out) != "0" {
|
||||
t.Fatal("failed to set up container", out)
|
||||
c.Fatal("failed to set up container", out)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(cpTestPath, os.ModeDir); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
hostFile, err := os.Create(cpFullPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer hostFile.Close()
|
||||
defer os.RemoveAll(cpTestPathParent)
|
||||
|
@ -53,7 +54,7 @@ func TestCpGarbagePath(t *testing.T) {
|
|||
|
||||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
tmpname := filepath.Join(tmpdir, cpTestName)
|
||||
|
@ -61,49 +62,48 @@ func TestCpGarbagePath(t *testing.T) {
|
|||
|
||||
path := path.Join("../../../../../../../../../../../../", cpFullPath)
|
||||
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":"+path, tmpdir)
|
||||
|
||||
file, _ := os.Open(tmpname)
|
||||
defer file.Close()
|
||||
|
||||
test, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if string(test) == cpHostContents {
|
||||
t.Errorf("output matched host file -- garbage path can escape container rootfs")
|
||||
c.Errorf("output matched host file -- garbage path can escape container rootfs")
|
||||
}
|
||||
|
||||
if string(test) != cpContainerContents {
|
||||
t.Errorf("output doesn't match the input for garbage path")
|
||||
c.Errorf("output doesn't match the input for garbage path")
|
||||
}
|
||||
|
||||
logDone("cp - garbage paths relative to container's rootfs")
|
||||
}
|
||||
|
||||
// Check that relative paths are relative to the container's rootfs
|
||||
func TestCpRelativePath(t *testing.T) {
|
||||
out, exitCode := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
|
||||
func (s *DockerSuite) TestCpRelativePath(c *check.C) {
|
||||
out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
|
||||
if exitCode != 0 {
|
||||
t.Fatal("failed to create a container", out)
|
||||
c.Fatal("failed to create a container", out)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
defer deleteContainer(cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(t, "wait", cleanedContainerID)
|
||||
out, _ = dockerCmd(c, "wait", cleanedContainerID)
|
||||
if strings.TrimSpace(out) != "0" {
|
||||
t.Fatal("failed to set up container", out)
|
||||
c.Fatal("failed to set up container", out)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(cpTestPath, os.ModeDir); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
hostFile, err := os.Create(cpFullPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer hostFile.Close()
|
||||
defer os.RemoveAll(cpTestPathParent)
|
||||
|
@ -113,7 +113,7 @@ func TestCpRelativePath(t *testing.T) {
|
|||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
tmpname := filepath.Join(tmpdir, cpTestName)
|
||||
|
@ -125,52 +125,51 @@ func TestCpRelativePath(t *testing.T) {
|
|||
// get this unix-path manipulation on windows with filepath.
|
||||
relPath = cpFullPath[1:]
|
||||
} else {
|
||||
t.Fatalf("path %s was assumed to be an absolute path", cpFullPath)
|
||||
c.Fatalf("path %s was assumed to be an absolute path", cpFullPath)
|
||||
}
|
||||
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":"+relPath, tmpdir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":"+relPath, tmpdir)
|
||||
|
||||
file, _ := os.Open(tmpname)
|
||||
defer file.Close()
|
||||
|
||||
test, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if string(test) == cpHostContents {
|
||||
t.Errorf("output matched host file -- relative path can escape container rootfs")
|
||||
c.Errorf("output matched host file -- relative path can escape container rootfs")
|
||||
}
|
||||
|
||||
if string(test) != cpContainerContents {
|
||||
t.Errorf("output doesn't match the input for relative path")
|
||||
c.Errorf("output doesn't match the input for relative path")
|
||||
}
|
||||
|
||||
logDone("cp - relative paths relative to container's rootfs")
|
||||
}
|
||||
|
||||
// Check that absolute paths are relative to the container's rootfs
|
||||
func TestCpAbsolutePath(t *testing.T) {
|
||||
out, exitCode := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
|
||||
func (s *DockerSuite) TestCpAbsolutePath(c *check.C) {
|
||||
out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
|
||||
if exitCode != 0 {
|
||||
t.Fatal("failed to create a container", out)
|
||||
c.Fatal("failed to create a container", out)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
defer deleteContainer(cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(t, "wait", cleanedContainerID)
|
||||
out, _ = dockerCmd(c, "wait", cleanedContainerID)
|
||||
if strings.TrimSpace(out) != "0" {
|
||||
t.Fatal("failed to set up container", out)
|
||||
c.Fatal("failed to set up container", out)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(cpTestPath, os.ModeDir); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
hostFile, err := os.Create(cpFullPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer hostFile.Close()
|
||||
defer os.RemoveAll(cpTestPathParent)
|
||||
|
@ -180,7 +179,7 @@ func TestCpAbsolutePath(t *testing.T) {
|
|||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
tmpname := filepath.Join(tmpdir, cpTestName)
|
||||
|
@ -188,50 +187,49 @@ func TestCpAbsolutePath(t *testing.T) {
|
|||
|
||||
path := cpFullPath
|
||||
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":"+path, tmpdir)
|
||||
|
||||
file, _ := os.Open(tmpname)
|
||||
defer file.Close()
|
||||
|
||||
test, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if string(test) == cpHostContents {
|
||||
t.Errorf("output matched host file -- absolute path can escape container rootfs")
|
||||
c.Errorf("output matched host file -- absolute path can escape container rootfs")
|
||||
}
|
||||
|
||||
if string(test) != cpContainerContents {
|
||||
t.Errorf("output doesn't match the input for absolute path")
|
||||
c.Errorf("output doesn't match the input for absolute path")
|
||||
}
|
||||
|
||||
logDone("cp - absolute paths relative to container's rootfs")
|
||||
}
|
||||
|
||||
// Test for #5619
|
||||
// Check that absolute symlinks are still relative to the container's rootfs
|
||||
func TestCpAbsoluteSymlink(t *testing.T) {
|
||||
out, exitCode := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpFullPath+" container_path")
|
||||
func (s *DockerSuite) TestCpAbsoluteSymlink(c *check.C) {
|
||||
out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpFullPath+" container_path")
|
||||
if exitCode != 0 {
|
||||
t.Fatal("failed to create a container", out)
|
||||
c.Fatal("failed to create a container", out)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
defer deleteContainer(cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(t, "wait", cleanedContainerID)
|
||||
out, _ = dockerCmd(c, "wait", cleanedContainerID)
|
||||
if strings.TrimSpace(out) != "0" {
|
||||
t.Fatal("failed to set up container", out)
|
||||
c.Fatal("failed to set up container", out)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(cpTestPath, os.ModeDir); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
hostFile, err := os.Create(cpFullPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer hostFile.Close()
|
||||
defer os.RemoveAll(cpTestPathParent)
|
||||
|
@ -241,7 +239,7 @@ func TestCpAbsoluteSymlink(t *testing.T) {
|
|||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
tmpname := filepath.Join(tmpdir, cpTestName)
|
||||
|
@ -249,50 +247,49 @@ func TestCpAbsoluteSymlink(t *testing.T) {
|
|||
|
||||
path := path.Join("/", "container_path")
|
||||
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":"+path, tmpdir)
|
||||
|
||||
file, _ := os.Open(tmpname)
|
||||
defer file.Close()
|
||||
|
||||
test, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if string(test) == cpHostContents {
|
||||
t.Errorf("output matched host file -- absolute symlink can escape container rootfs")
|
||||
c.Errorf("output matched host file -- absolute symlink can escape container rootfs")
|
||||
}
|
||||
|
||||
if string(test) != cpContainerContents {
|
||||
t.Errorf("output doesn't match the input for absolute symlink")
|
||||
c.Errorf("output doesn't match the input for absolute symlink")
|
||||
}
|
||||
|
||||
logDone("cp - absolute symlink relative to container's rootfs")
|
||||
}
|
||||
|
||||
// Test for #5619
|
||||
// Check that symlinks which are part of the resource path are still relative to the container's rootfs
|
||||
func TestCpSymlinkComponent(t *testing.T) {
|
||||
out, exitCode := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpTestPath+" container_path")
|
||||
func (s *DockerSuite) TestCpSymlinkComponent(c *check.C) {
|
||||
out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpTestPath+" container_path")
|
||||
if exitCode != 0 {
|
||||
t.Fatal("failed to create a container", out)
|
||||
c.Fatal("failed to create a container", out)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
defer deleteContainer(cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(t, "wait", cleanedContainerID)
|
||||
out, _ = dockerCmd(c, "wait", cleanedContainerID)
|
||||
if strings.TrimSpace(out) != "0" {
|
||||
t.Fatal("failed to set up container", out)
|
||||
c.Fatal("failed to set up container", out)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(cpTestPath, os.ModeDir); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
hostFile, err := os.Create(cpFullPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer hostFile.Close()
|
||||
defer os.RemoveAll(cpTestPathParent)
|
||||
|
@ -302,7 +299,7 @@ func TestCpSymlinkComponent(t *testing.T) {
|
|||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
tmpname := filepath.Join(tmpdir, cpTestName)
|
||||
|
@ -310,268 +307,263 @@ func TestCpSymlinkComponent(t *testing.T) {
|
|||
|
||||
path := path.Join("/", "container_path", cpTestName)
|
||||
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":"+path, tmpdir)
|
||||
|
||||
file, _ := os.Open(tmpname)
|
||||
defer file.Close()
|
||||
|
||||
test, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if string(test) == cpHostContents {
|
||||
t.Errorf("output matched host file -- symlink path component can escape container rootfs")
|
||||
c.Errorf("output matched host file -- symlink path component can escape container rootfs")
|
||||
}
|
||||
|
||||
if string(test) != cpContainerContents {
|
||||
t.Errorf("output doesn't match the input for symlink path component")
|
||||
c.Errorf("output doesn't match the input for symlink path component")
|
||||
}
|
||||
|
||||
logDone("cp - symlink path components relative to container's rootfs")
|
||||
}
|
||||
|
||||
// Check that cp with unprivileged user doesn't return any error
|
||||
func TestCpUnprivilegedUser(t *testing.T) {
|
||||
testRequires(t, UnixCli) // uses chmod/su: not available on windows
|
||||
func (s *DockerSuite) TestCpUnprivilegedUser(c *check.C) {
|
||||
testRequires(c, UnixCli) // uses chmod/su: not available on windows
|
||||
|
||||
out, exitCode := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "touch "+cpTestName)
|
||||
out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "touch "+cpTestName)
|
||||
if exitCode != 0 {
|
||||
t.Fatal("failed to create a container", out)
|
||||
c.Fatal("failed to create a container", out)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
defer deleteContainer(cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(t, "wait", cleanedContainerID)
|
||||
out, _ = dockerCmd(c, "wait", cleanedContainerID)
|
||||
if strings.TrimSpace(out) != "0" {
|
||||
t.Fatal("failed to set up container", out)
|
||||
c.Fatal("failed to set up container", out)
|
||||
}
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
if err = os.Chmod(tmpdir, 0777); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
path := cpTestName
|
||||
|
||||
_, _, err = runCommandWithOutput(exec.Command("su", "unprivilegeduser", "-c", dockerBinary+" cp "+cleanedContainerID+":"+path+" "+tmpdir))
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't copy with unprivileged user: %s:%s %s", cleanedContainerID, path, err)
|
||||
c.Fatalf("couldn't copy with unprivileged user: %s:%s %s", cleanedContainerID, path, err)
|
||||
}
|
||||
|
||||
logDone("cp - unprivileged user")
|
||||
}
|
||||
|
||||
func TestCpSpecialFiles(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon)
|
||||
func (s *DockerSuite) TestCpSpecialFiles(c *check.C) {
|
||||
testRequires(c, SameHostDaemon)
|
||||
|
||||
outDir, err := ioutil.TempDir("", "cp-test-special-files")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(outDir)
|
||||
|
||||
out, exitCode := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "touch /foo")
|
||||
out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "touch /foo")
|
||||
if exitCode != 0 {
|
||||
t.Fatal("failed to create a container", out)
|
||||
c.Fatal("failed to create a container", out)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
defer deleteContainer(cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(t, "wait", cleanedContainerID)
|
||||
out, _ = dockerCmd(c, "wait", cleanedContainerID)
|
||||
if strings.TrimSpace(out) != "0" {
|
||||
t.Fatal("failed to set up container", out)
|
||||
c.Fatal("failed to set up container", out)
|
||||
}
|
||||
|
||||
// Copy actual /etc/resolv.conf
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":/etc/resolv.conf", outDir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":/etc/resolv.conf", outDir)
|
||||
|
||||
expected, err := ioutil.ReadFile("/var/lib/docker/containers/" + cleanedContainerID + "/resolv.conf")
|
||||
actual, err := ioutil.ReadFile(outDir + "/resolv.conf")
|
||||
|
||||
if !bytes.Equal(actual, expected) {
|
||||
t.Fatalf("Expected copied file to be duplicate of the container resolvconf")
|
||||
c.Fatalf("Expected copied file to be duplicate of the container resolvconf")
|
||||
}
|
||||
|
||||
// Copy actual /etc/hosts
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":/etc/hosts", outDir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":/etc/hosts", outDir)
|
||||
|
||||
expected, err = ioutil.ReadFile("/var/lib/docker/containers/" + cleanedContainerID + "/hosts")
|
||||
actual, err = ioutil.ReadFile(outDir + "/hosts")
|
||||
|
||||
if !bytes.Equal(actual, expected) {
|
||||
t.Fatalf("Expected copied file to be duplicate of the container hosts")
|
||||
c.Fatalf("Expected copied file to be duplicate of the container hosts")
|
||||
}
|
||||
|
||||
// Copy actual /etc/resolv.conf
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":/etc/hostname", outDir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":/etc/hostname", outDir)
|
||||
|
||||
expected, err = ioutil.ReadFile("/var/lib/docker/containers/" + cleanedContainerID + "/hostname")
|
||||
actual, err = ioutil.ReadFile(outDir + "/hostname")
|
||||
|
||||
if !bytes.Equal(actual, expected) {
|
||||
t.Fatalf("Expected copied file to be duplicate of the container resolvconf")
|
||||
c.Fatalf("Expected copied file to be duplicate of the container resolvconf")
|
||||
}
|
||||
|
||||
logDone("cp - special files (resolv.conf, hosts, hostname)")
|
||||
}
|
||||
|
||||
func TestCpVolumePath(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon)
|
||||
func (s *DockerSuite) TestCpVolumePath(c *check.C) {
|
||||
testRequires(c, SameHostDaemon)
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "cp-test-volumepath")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
outDir, err := ioutil.TempDir("", "cp-test-volumepath-out")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(outDir)
|
||||
_, err = os.Create(tmpDir + "/test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
out, exitCode := dockerCmd(t, "run", "-d", "-v", "/foo", "-v", tmpDir+"/test:/test", "-v", tmpDir+":/baz", "busybox", "/bin/sh", "-c", "touch /foo/bar")
|
||||
out, exitCode := dockerCmd(c, "run", "-d", "-v", "/foo", "-v", tmpDir+"/test:/test", "-v", tmpDir+":/baz", "busybox", "/bin/sh", "-c", "touch /foo/bar")
|
||||
if exitCode != 0 {
|
||||
t.Fatal("failed to create a container", out)
|
||||
c.Fatal("failed to create a container", out)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
defer dockerCmd(t, "rm", "-fv", cleanedContainerID)
|
||||
defer dockerCmd(c, "rm", "-fv", cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(t, "wait", cleanedContainerID)
|
||||
out, _ = dockerCmd(c, "wait", cleanedContainerID)
|
||||
if strings.TrimSpace(out) != "0" {
|
||||
t.Fatal("failed to set up container", out)
|
||||
c.Fatal("failed to set up container", out)
|
||||
}
|
||||
|
||||
// Copy actual volume path
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":/foo", outDir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":/foo", outDir)
|
||||
|
||||
stat, err := os.Stat(outDir + "/foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if !stat.IsDir() {
|
||||
t.Fatal("expected copied content to be dir")
|
||||
c.Fatal("expected copied content to be dir")
|
||||
}
|
||||
stat, err = os.Stat(outDir + "/foo/bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if stat.IsDir() {
|
||||
t.Fatal("Expected file `bar` to be a file")
|
||||
c.Fatal("Expected file `bar` to be a file")
|
||||
}
|
||||
|
||||
// Copy file nested in volume
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":/foo/bar", outDir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":/foo/bar", outDir)
|
||||
|
||||
stat, err = os.Stat(outDir + "/bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if stat.IsDir() {
|
||||
t.Fatal("Expected file `bar` to be a file")
|
||||
c.Fatal("Expected file `bar` to be a file")
|
||||
}
|
||||
|
||||
// Copy Bind-mounted dir
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":/baz", outDir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":/baz", outDir)
|
||||
stat, err = os.Stat(outDir + "/baz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if !stat.IsDir() {
|
||||
t.Fatal("Expected `baz` to be a dir")
|
||||
c.Fatal("Expected `baz` to be a dir")
|
||||
}
|
||||
|
||||
// Copy file nested in bind-mounted dir
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":/baz/test", outDir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":/baz/test", outDir)
|
||||
fb, err := ioutil.ReadFile(outDir + "/baz/test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
fb2, err := ioutil.ReadFile(tmpDir + "/test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(fb, fb2) {
|
||||
t.Fatalf("Expected copied file to be duplicate of bind-mounted file")
|
||||
c.Fatalf("Expected copied file to be duplicate of bind-mounted file")
|
||||
}
|
||||
|
||||
// Copy bind-mounted file
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":/test", outDir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":/test", outDir)
|
||||
fb, err = ioutil.ReadFile(outDir + "/test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
fb2, err = ioutil.ReadFile(tmpDir + "/test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(fb, fb2) {
|
||||
t.Fatalf("Expected copied file to be duplicate of bind-mounted file")
|
||||
c.Fatalf("Expected copied file to be duplicate of bind-mounted file")
|
||||
}
|
||||
|
||||
logDone("cp - volume path")
|
||||
}
|
||||
|
||||
func TestCpToDot(t *testing.T) {
|
||||
out, exitCode := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "echo lololol > /test")
|
||||
func (s *DockerSuite) TestCpToDot(c *check.C) {
|
||||
out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "echo lololol > /test")
|
||||
if exitCode != 0 {
|
||||
t.Fatal("failed to create a container", out)
|
||||
c.Fatal("failed to create a container", out)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
defer deleteContainer(cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(t, "wait", cleanedContainerID)
|
||||
out, _ = dockerCmd(c, "wait", cleanedContainerID)
|
||||
if strings.TrimSpace(out) != "0" {
|
||||
t.Fatal("failed to set up container", out)
|
||||
c.Fatal("failed to set up container", out)
|
||||
}
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpdir)
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer os.Chdir(cwd)
|
||||
if err := os.Chdir(tmpdir); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":/test", ".")
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":/test", ".")
|
||||
content, err := ioutil.ReadFile("./test")
|
||||
if string(content) != "lololol\n" {
|
||||
t.Fatalf("Wrong content in copied file %q, should be %q", content, "lololol\n")
|
||||
c.Fatalf("Wrong content in copied file %q, should be %q", content, "lololol\n")
|
||||
}
|
||||
logDone("cp - to dot path")
|
||||
}
|
||||
|
||||
func TestCpToStdout(t *testing.T) {
|
||||
out, exitCode := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "echo lololol > /test")
|
||||
func (s *DockerSuite) TestCpToStdout(c *check.C) {
|
||||
out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "echo lololol > /test")
|
||||
if exitCode != 0 {
|
||||
t.Fatalf("failed to create a container:%s\n", out)
|
||||
c.Fatalf("failed to create a container:%s\n", out)
|
||||
}
|
||||
|
||||
cID := strings.TrimSpace(out)
|
||||
defer deleteContainer(cID)
|
||||
|
||||
out, _ = dockerCmd(t, "wait", cID)
|
||||
out, _ = dockerCmd(c, "wait", cID)
|
||||
if strings.TrimSpace(out) != "0" {
|
||||
t.Fatalf("failed to set up container:%s\n", out)
|
||||
c.Fatalf("failed to set up container:%s\n", out)
|
||||
}
|
||||
|
||||
out, _, err := runCommandPipelineWithOutput(
|
||||
|
@ -579,40 +571,38 @@ func TestCpToStdout(t *testing.T) {
|
|||
exec.Command("tar", "-vtf", "-"))
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to run commands: %s", err)
|
||||
c.Fatalf("Failed to run commands: %s", err)
|
||||
}
|
||||
|
||||
if !strings.Contains(out, "test") || !strings.Contains(out, "-rw") {
|
||||
t.Fatalf("Missing file from tar TOC:\n%s", out)
|
||||
c.Fatalf("Missing file from tar TOC:\n%s", out)
|
||||
}
|
||||
logDone("cp - to stdout")
|
||||
}
|
||||
|
||||
func TestCpNameHasColon(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon)
|
||||
func (s *DockerSuite) TestCpNameHasColon(c *check.C) {
|
||||
testRequires(c, SameHostDaemon)
|
||||
|
||||
out, exitCode := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "echo lololol > /te:s:t")
|
||||
out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "echo lololol > /te:s:t")
|
||||
if exitCode != 0 {
|
||||
t.Fatal("failed to create a container", out)
|
||||
c.Fatal("failed to create a container", out)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
defer deleteContainer(cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(t, "wait", cleanedContainerID)
|
||||
out, _ = dockerCmd(c, "wait", cleanedContainerID)
|
||||
if strings.TrimSpace(out) != "0" {
|
||||
t.Fatal("failed to set up container", out)
|
||||
c.Fatal("failed to set up container", out)
|
||||
}
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpdir)
|
||||
_, _ = dockerCmd(t, "cp", cleanedContainerID+":/te:s:t", tmpdir)
|
||||
_, _ = dockerCmd(c, "cp", cleanedContainerID+":/te:s:t", tmpdir)
|
||||
content, err := ioutil.ReadFile(tmpdir + "/te:s:t")
|
||||
if string(content) != "lololol\n" {
|
||||
t.Fatalf("Wrong content in copied file %q, should be %q", content, "lololol\n")
|
||||
c.Fatalf("Wrong content in copied file %q, should be %q", content, "lololol\n")
|
||||
}
|
||||
logDone("cp - copy filename has ':'")
|
||||
}
|
||||
|
|
|
@ -6,20 +6,19 @@ import (
|
|||
"os/exec"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/nat"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// Make sure we can create a simple container with some args
|
||||
func TestCreateArgs(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestCreateArgs(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "create", "busybox", "command", "arg1", "arg2", "arg with space")
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -27,7 +26,7 @@ func TestCreateArgs(t *testing.T) {
|
|||
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("out should've been a container id: %s, %v", out, err)
|
||||
c.Fatalf("out should've been a container id: %s, %v", out, err)
|
||||
}
|
||||
|
||||
containers := []struct {
|
||||
|
@ -38,40 +37,38 @@ func TestCreateArgs(t *testing.T) {
|
|||
Image string
|
||||
}{}
|
||||
if err := json.Unmarshal([]byte(out), &containers); err != nil {
|
||||
t.Fatalf("Error inspecting the container: %s", err)
|
||||
c.Fatalf("Error inspecting the container: %s", err)
|
||||
}
|
||||
if len(containers) != 1 {
|
||||
t.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
|
||||
c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
|
||||
}
|
||||
|
||||
c := containers[0]
|
||||
if c.Path != "command" {
|
||||
t.Fatalf("Unexpected container path. Expected command, received: %s", c.Path)
|
||||
cont := containers[0]
|
||||
if cont.Path != "command" {
|
||||
c.Fatalf("Unexpected container path. Expected command, received: %s", cont.Path)
|
||||
}
|
||||
|
||||
b := false
|
||||
expected := []string{"arg1", "arg2", "arg with space"}
|
||||
for i, arg := range expected {
|
||||
if arg != c.Args[i] {
|
||||
if arg != cont.Args[i] {
|
||||
b = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(c.Args) != len(expected) || b {
|
||||
t.Fatalf("Unexpected args. Expected %v, received: %v", expected, c.Args)
|
||||
if len(cont.Args) != len(expected) || b {
|
||||
c.Fatalf("Unexpected args. Expected %v, received: %v", expected, cont.Args)
|
||||
}
|
||||
|
||||
logDone("create - args")
|
||||
}
|
||||
|
||||
// Make sure we can set hostconfig options too
|
||||
func TestCreateHostConfig(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestCreateHostConfig(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "create", "-P", "busybox", "echo")
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -79,7 +76,7 @@ func TestCreateHostConfig(t *testing.T) {
|
|||
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("out should've been a container id: %s, %v", out, err)
|
||||
c.Fatalf("out should've been a container id: %s, %v", out, err)
|
||||
}
|
||||
|
||||
containers := []struct {
|
||||
|
@ -88,31 +85,29 @@ func TestCreateHostConfig(t *testing.T) {
|
|||
}
|
||||
}{}
|
||||
if err := json.Unmarshal([]byte(out), &containers); err != nil {
|
||||
t.Fatalf("Error inspecting the container: %s", err)
|
||||
c.Fatalf("Error inspecting the container: %s", err)
|
||||
}
|
||||
if len(containers) != 1 {
|
||||
t.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
|
||||
c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
|
||||
}
|
||||
|
||||
c := containers[0]
|
||||
if c.HostConfig == nil {
|
||||
t.Fatalf("Expected HostConfig, got none")
|
||||
cont := containers[0]
|
||||
if cont.HostConfig == nil {
|
||||
c.Fatalf("Expected HostConfig, got none")
|
||||
}
|
||||
|
||||
if !c.HostConfig.PublishAllPorts {
|
||||
t.Fatalf("Expected PublishAllPorts, got false")
|
||||
if !cont.HostConfig.PublishAllPorts {
|
||||
c.Fatalf("Expected PublishAllPorts, got false")
|
||||
}
|
||||
|
||||
logDone("create - hostconfig")
|
||||
}
|
||||
|
||||
func TestCreateWithPortRange(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestCreateWithPortRange(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "create", "-p", "3300-3303:3300-3303/tcp", "busybox", "echo")
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -120,7 +115,7 @@ func TestCreateWithPortRange(t *testing.T) {
|
|||
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("out should've been a container id: %s, %v", out, err)
|
||||
c.Fatalf("out should've been a container id: %s, %v", out, err)
|
||||
}
|
||||
|
||||
containers := []struct {
|
||||
|
@ -129,39 +124,37 @@ func TestCreateWithPortRange(t *testing.T) {
|
|||
}
|
||||
}{}
|
||||
if err := json.Unmarshal([]byte(out), &containers); err != nil {
|
||||
t.Fatalf("Error inspecting the container: %s", err)
|
||||
c.Fatalf("Error inspecting the container: %s", err)
|
||||
}
|
||||
if len(containers) != 1 {
|
||||
t.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
|
||||
c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
|
||||
}
|
||||
|
||||
c := containers[0]
|
||||
if c.HostConfig == nil {
|
||||
t.Fatalf("Expected HostConfig, got none")
|
||||
cont := containers[0]
|
||||
if cont.HostConfig == nil {
|
||||
c.Fatalf("Expected HostConfig, got none")
|
||||
}
|
||||
|
||||
if len(c.HostConfig.PortBindings) != 4 {
|
||||
t.Fatalf("Expected 4 ports bindings, got %d", len(c.HostConfig.PortBindings))
|
||||
if len(cont.HostConfig.PortBindings) != 4 {
|
||||
c.Fatalf("Expected 4 ports bindings, got %d", len(cont.HostConfig.PortBindings))
|
||||
}
|
||||
for k, v := range c.HostConfig.PortBindings {
|
||||
for k, v := range cont.HostConfig.PortBindings {
|
||||
if len(v) != 1 {
|
||||
t.Fatalf("Expected 1 ports binding, for the port %s but found %s", k, v)
|
||||
c.Fatalf("Expected 1 ports binding, for the port %s but found %s", k, v)
|
||||
}
|
||||
if k.Port() != v[0].HostPort {
|
||||
t.Fatalf("Expected host port %d to match published port %d", k.Port(), v[0].HostPort)
|
||||
c.Fatalf("Expected host port %d to match published port %d", k.Port(), v[0].HostPort)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("create - port range")
|
||||
}
|
||||
|
||||
func TestCreateWithiLargePortRange(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestCreateWithiLargePortRange(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "create", "-p", "1-65535:1-65535/tcp", "busybox", "echo")
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -169,7 +162,7 @@ func TestCreateWithiLargePortRange(t *testing.T) {
|
|||
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("out should've been a container id: %s, %v", out, err)
|
||||
c.Fatalf("out should've been a container id: %s, %v", out, err)
|
||||
}
|
||||
|
||||
containers := []struct {
|
||||
|
@ -178,40 +171,38 @@ func TestCreateWithiLargePortRange(t *testing.T) {
|
|||
}
|
||||
}{}
|
||||
if err := json.Unmarshal([]byte(out), &containers); err != nil {
|
||||
t.Fatalf("Error inspecting the container: %s", err)
|
||||
c.Fatalf("Error inspecting the container: %s", err)
|
||||
}
|
||||
if len(containers) != 1 {
|
||||
t.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
|
||||
c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
|
||||
}
|
||||
|
||||
c := containers[0]
|
||||
if c.HostConfig == nil {
|
||||
t.Fatalf("Expected HostConfig, got none")
|
||||
cont := containers[0]
|
||||
if cont.HostConfig == nil {
|
||||
c.Fatalf("Expected HostConfig, got none")
|
||||
}
|
||||
|
||||
if len(c.HostConfig.PortBindings) != 65535 {
|
||||
t.Fatalf("Expected 65535 ports bindings, got %d", len(c.HostConfig.PortBindings))
|
||||
if len(cont.HostConfig.PortBindings) != 65535 {
|
||||
c.Fatalf("Expected 65535 ports bindings, got %d", len(cont.HostConfig.PortBindings))
|
||||
}
|
||||
for k, v := range c.HostConfig.PortBindings {
|
||||
for k, v := range cont.HostConfig.PortBindings {
|
||||
if len(v) != 1 {
|
||||
t.Fatalf("Expected 1 ports binding, for the port %s but found %s", k, v)
|
||||
c.Fatalf("Expected 1 ports binding, for the port %s but found %s", k, v)
|
||||
}
|
||||
if k.Port() != v[0].HostPort {
|
||||
t.Fatalf("Expected host port %d to match published port %d", k.Port(), v[0].HostPort)
|
||||
c.Fatalf("Expected host port %d to match published port %d", k.Port(), v[0].HostPort)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("create - large port range")
|
||||
}
|
||||
|
||||
// "test123" should be printed by docker create + start
|
||||
func TestCreateEchoStdout(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestCreateEchoStdout(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "create", "busybox", "echo", "test123")
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -219,62 +210,58 @@ func TestCreateEchoStdout(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "start", "-ai", cleanedContainerID)
|
||||
out, _, _, err = runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if out != "test123\n" {
|
||||
t.Errorf("container should've printed 'test123', got %q", out)
|
||||
c.Errorf("container should've printed 'test123', got %q", out)
|
||||
}
|
||||
|
||||
logDone("create - echo test123")
|
||||
}
|
||||
|
||||
func TestCreateVolumesCreated(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon)
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestCreateVolumesCreated(c *check.C) {
|
||||
testRequires(c, SameHostDaemon)
|
||||
|
||||
name := "test_create_volume"
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "create", "--name", name, "-v", "/foo", "busybox")); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
dir, err := inspectFieldMap(name, "Volumes", "/foo")
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting volume host path: %q", err)
|
||||
c.Fatalf("Error getting volume host path: %q", err)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
|
||||
t.Fatalf("Volume was not created")
|
||||
c.Fatalf("Volume was not created")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("Error statting volume host path: %q", err)
|
||||
c.Fatalf("Error statting volume host path: %q", err)
|
||||
}
|
||||
|
||||
logDone("create - volumes are created")
|
||||
}
|
||||
|
||||
func TestCreateLabels(t *testing.T) {
|
||||
func (s *DockerSuite) TestCreateLabels(c *check.C) {
|
||||
name := "test_create_labels"
|
||||
expected := map[string]string{"k1": "v1", "k2": "v2"}
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "create", "--name", name, "-l", "k1=v1", "--label", "k2=v2", "busybox")); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
actual := make(map[string]string)
|
||||
err := inspectFieldAndMarshall(name, "Config.Labels", &actual)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected, actual) {
|
||||
t.Fatalf("Expected %s got %s", expected, actual)
|
||||
c.Fatalf("Expected %s got %s", expected, actual)
|
||||
}
|
||||
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("create - labels")
|
||||
}
|
||||
|
||||
func TestCreateLabelFromImage(t *testing.T) {
|
||||
func (s *DockerSuite) TestCreateLabelFromImage(c *check.C) {
|
||||
imageName := "testcreatebuildlabel"
|
||||
defer deleteImages(imageName)
|
||||
_, err := buildImage(imageName,
|
||||
|
@ -282,34 +269,32 @@ func TestCreateLabelFromImage(t *testing.T) {
|
|||
LABEL k1=v1 k2=v2`,
|
||||
true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
name := "test_create_labels_from_image"
|
||||
expected := map[string]string{"k2": "x", "k3": "v3", "k1": "v1"}
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "create", "--name", name, "-l", "k2=x", "--label", "k3=v3", imageName)); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
actual := make(map[string]string)
|
||||
err = inspectFieldAndMarshall(name, "Config.Labels", &actual)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected, actual) {
|
||||
t.Fatalf("Expected %s got %s", expected, actual)
|
||||
c.Fatalf("Expected %s got %s", expected, actual)
|
||||
}
|
||||
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("create - labels from image")
|
||||
}
|
||||
|
||||
func TestCreateHostnameWithNumber(t *testing.T) {
|
||||
out, _ := dockerCmd(t, "run", "-h", "web.0", "busybox", "hostname")
|
||||
func (s *DockerSuite) TestCreateHostnameWithNumber(c *check.C) {
|
||||
out, _ := dockerCmd(c, "run", "-h", "web.0", "busybox", "hostname")
|
||||
if strings.TrimSpace(out) != "web.0" {
|
||||
t.Fatalf("hostname not set, expected `web.0`, got: %s", out)
|
||||
c.Fatalf("hostname not set, expected `web.0`, got: %s", out)
|
||||
}
|
||||
logDone("create - use hostname with number")
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,16 +3,17 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// ensure that an added file shows up in docker diff
|
||||
func TestDiffFilenameShownInOutput(t *testing.T) {
|
||||
func (s *DockerSuite) TestDiffFilenameShownInOutput(c *check.C) {
|
||||
containerCmd := `echo foo > /root/bar`
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", containerCmd)
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start the container: %s, %v", out, err)
|
||||
c.Fatalf("failed to start the container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanCID := strings.TrimSpace(out)
|
||||
|
@ -20,7 +21,7 @@ func TestDiffFilenameShownInOutput(t *testing.T) {
|
|||
diffCmd := exec.Command(dockerBinary, "diff", cleanCID)
|
||||
out, _, err = runCommandWithOutput(diffCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run diff: %s %v", out, err)
|
||||
c.Fatalf("failed to run diff: %s %v", out, err)
|
||||
}
|
||||
|
||||
found := false
|
||||
|
@ -31,15 +32,12 @@ func TestDiffFilenameShownInOutput(t *testing.T) {
|
|||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("couldn't find the new file in docker diff's output: %v", out)
|
||||
c.Errorf("couldn't find the new file in docker diff's output: %v", out)
|
||||
}
|
||||
deleteContainer(cleanCID)
|
||||
|
||||
logDone("diff - check if created file shows up")
|
||||
}
|
||||
|
||||
// test to ensure GH #3840 doesn't occur any more
|
||||
func TestDiffEnsureDockerinitFilesAreIgnored(t *testing.T) {
|
||||
func (s *DockerSuite) TestDiffEnsureDockerinitFilesAreIgnored(c *check.C) {
|
||||
// this is a list of files which shouldn't show up in `docker diff`
|
||||
dockerinitFiles := []string{"/etc/resolv.conf", "/etc/hostname", "/etc/hosts", "/.dockerinit", "/.dockerenv"}
|
||||
|
||||
|
@ -49,7 +47,7 @@ func TestDiffEnsureDockerinitFilesAreIgnored(t *testing.T) {
|
|||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", containerCmd)
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanCID := strings.TrimSpace(out)
|
||||
|
@ -57,26 +55,22 @@ func TestDiffEnsureDockerinitFilesAreIgnored(t *testing.T) {
|
|||
diffCmd := exec.Command(dockerBinary, "diff", cleanCID)
|
||||
out, _, err = runCommandWithOutput(diffCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run diff: %s, %v", out, err)
|
||||
c.Fatalf("failed to run diff: %s, %v", out, err)
|
||||
}
|
||||
|
||||
deleteContainer(cleanCID)
|
||||
|
||||
for _, filename := range dockerinitFiles {
|
||||
if strings.Contains(out, filename) {
|
||||
t.Errorf("found file which should've been ignored %v in diff output", filename)
|
||||
c.Errorf("found file which should've been ignored %v in diff output", filename)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logDone("diff - check if ignored files show up in diff")
|
||||
}
|
||||
|
||||
func TestDiffEnsureOnlyKmsgAndPtmx(t *testing.T) {
|
||||
func (s *DockerSuite) TestDiffEnsureOnlyKmsgAndPtmx(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sleep", "0")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanCID := strings.TrimSpace(out)
|
||||
|
@ -84,9 +78,8 @@ func TestDiffEnsureOnlyKmsgAndPtmx(t *testing.T) {
|
|||
diffCmd := exec.Command(dockerBinary, "diff", cleanCID)
|
||||
out, _, err = runCommandWithOutput(diffCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run diff: %s, %v", out, err)
|
||||
c.Fatalf("failed to run diff: %s, %v", out, err)
|
||||
}
|
||||
deleteContainer(cleanCID)
|
||||
|
||||
expected := map[string]bool{
|
||||
"C /dev": true,
|
||||
|
@ -109,9 +102,7 @@ func TestDiffEnsureOnlyKmsgAndPtmx(t *testing.T) {
|
|||
|
||||
for _, line := range strings.Split(out, "\n") {
|
||||
if line != "" && !expected[line] {
|
||||
t.Errorf("%q is shown in the diff but shouldn't", line)
|
||||
c.Errorf("%q is shown in the diff but shouldn't", line)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("diff - ensure that only kmsg and ptmx in diff")
|
||||
}
|
||||
|
|
|
@ -7,20 +7,21 @@ import (
|
|||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestEventsUntag(t *testing.T) {
|
||||
func (s *DockerSuite) TestEventsUntag(c *check.C) {
|
||||
image := "busybox"
|
||||
dockerCmd(t, "tag", image, "utest:tag1")
|
||||
dockerCmd(t, "tag", image, "utest:tag2")
|
||||
dockerCmd(t, "rmi", "utest:tag1")
|
||||
dockerCmd(t, "rmi", "utest:tag2")
|
||||
dockerCmd(c, "tag", image, "utest:tag1")
|
||||
dockerCmd(c, "tag", image, "utest:tag2")
|
||||
dockerCmd(c, "rmi", "utest:tag1")
|
||||
dockerCmd(c, "rmi", "utest:tag2")
|
||||
eventsCmd := exec.Command(dockerBinary, "events", "--since=1")
|
||||
out, exitCode, _, err := runCommandWithOutputForDuration(eventsCmd, time.Duration(time.Millisecond*200))
|
||||
if exitCode != 0 || err != nil {
|
||||
t.Fatalf("Failed to get events - exit code %d: %s", exitCode, err)
|
||||
c.Fatalf("Failed to get events - exit code %d: %s", exitCode, err)
|
||||
}
|
||||
events := strings.Split(out, "\n")
|
||||
nEvents := len(events)
|
||||
|
@ -29,126 +30,119 @@ func TestEventsUntag(t *testing.T) {
|
|||
// looking for.
|
||||
for _, v := range events[nEvents-3 : nEvents-1] {
|
||||
if !strings.Contains(v, "untag") {
|
||||
t.Fatalf("event should be untag, not %#v", v)
|
||||
c.Fatalf("event should be untag, not %#v", v)
|
||||
}
|
||||
}
|
||||
logDone("events - untags are logged")
|
||||
}
|
||||
|
||||
func TestEventsContainerFailStartDie(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestEventsContainerFailStartDie(c *check.C) {
|
||||
|
||||
out, _ := dockerCmd(t, "images", "-q")
|
||||
out, _ := dockerCmd(c, "images", "-q")
|
||||
image := strings.Split(out, "\n")[0]
|
||||
eventsCmd := exec.Command(dockerBinary, "run", "--name", "testeventdie", image, "blerg")
|
||||
_, _, err := runCommandWithOutput(eventsCmd)
|
||||
if err == nil {
|
||||
t.Fatalf("Container run with command blerg should have failed, but it did not")
|
||||
c.Fatalf("Container run with command blerg should have failed, but it did not")
|
||||
}
|
||||
|
||||
eventsCmd = exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
|
||||
eventsCmd = exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
out, _, _ = runCommandWithOutput(eventsCmd)
|
||||
events := strings.Split(out, "\n")
|
||||
if len(events) <= 1 {
|
||||
t.Fatalf("Missing expected event")
|
||||
c.Fatalf("Missing expected event")
|
||||
}
|
||||
|
||||
startEvent := strings.Fields(events[len(events)-3])
|
||||
dieEvent := strings.Fields(events[len(events)-2])
|
||||
|
||||
if startEvent[len(startEvent)-1] != "start" {
|
||||
t.Fatalf("event should be start, not %#v", startEvent)
|
||||
c.Fatalf("event should be start, not %#v", startEvent)
|
||||
}
|
||||
if dieEvent[len(dieEvent)-1] != "die" {
|
||||
t.Fatalf("event should be die, not %#v", dieEvent)
|
||||
c.Fatalf("event should be die, not %#v", dieEvent)
|
||||
}
|
||||
|
||||
logDone("events - container unwilling to start logs die")
|
||||
}
|
||||
|
||||
func TestEventsLimit(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestEventsLimit(c *check.C) {
|
||||
for i := 0; i < 30; i++ {
|
||||
dockerCmd(t, "run", "busybox", "echo", strconv.Itoa(i))
|
||||
dockerCmd(c, "run", "busybox", "echo", strconv.Itoa(i))
|
||||
}
|
||||
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
|
||||
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
out, _, _ := runCommandWithOutput(eventsCmd)
|
||||
events := strings.Split(out, "\n")
|
||||
nEvents := len(events) - 1
|
||||
if nEvents != 64 {
|
||||
t.Fatalf("events should be limited to 64, but received %d", nEvents)
|
||||
c.Fatalf("events should be limited to 64, but received %d", nEvents)
|
||||
}
|
||||
logDone("events - limited to 64 entries")
|
||||
}
|
||||
|
||||
func TestEventsContainerEvents(t *testing.T) {
|
||||
dockerCmd(t, "run", "--rm", "busybox", "true")
|
||||
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
|
||||
func (s *DockerSuite) TestEventsContainerEvents(c *check.C) {
|
||||
dockerCmd(c, "run", "--rm", "busybox", "true")
|
||||
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
out, exitCode, err := runCommandWithOutput(eventsCmd)
|
||||
if exitCode != 0 || err != nil {
|
||||
t.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
|
||||
c.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
|
||||
}
|
||||
events := strings.Split(out, "\n")
|
||||
events = events[:len(events)-1]
|
||||
if len(events) < 4 {
|
||||
t.Fatalf("Missing expected event")
|
||||
c.Fatalf("Missing expected event")
|
||||
}
|
||||
createEvent := strings.Fields(events[len(events)-4])
|
||||
startEvent := strings.Fields(events[len(events)-3])
|
||||
dieEvent := strings.Fields(events[len(events)-2])
|
||||
destroyEvent := strings.Fields(events[len(events)-1])
|
||||
if createEvent[len(createEvent)-1] != "create" {
|
||||
t.Fatalf("event should be create, not %#v", createEvent)
|
||||
c.Fatalf("event should be create, not %#v", createEvent)
|
||||
}
|
||||
if startEvent[len(startEvent)-1] != "start" {
|
||||
t.Fatalf("event should be start, not %#v", startEvent)
|
||||
c.Fatalf("event should be start, not %#v", startEvent)
|
||||
}
|
||||
if dieEvent[len(dieEvent)-1] != "die" {
|
||||
t.Fatalf("event should be die, not %#v", dieEvent)
|
||||
c.Fatalf("event should be die, not %#v", dieEvent)
|
||||
}
|
||||
if destroyEvent[len(destroyEvent)-1] != "destroy" {
|
||||
t.Fatalf("event should be destroy, not %#v", destroyEvent)
|
||||
c.Fatalf("event should be destroy, not %#v", destroyEvent)
|
||||
}
|
||||
|
||||
logDone("events - container create, start, die, destroy is logged")
|
||||
}
|
||||
|
||||
func TestEventsContainerEventsSinceUnixEpoch(t *testing.T) {
|
||||
dockerCmd(t, "run", "--rm", "busybox", "true")
|
||||
func (s *DockerSuite) TestEventsContainerEventsSinceUnixEpoch(c *check.C) {
|
||||
dockerCmd(c, "run", "--rm", "busybox", "true")
|
||||
timeBeginning := time.Unix(0, 0).Format(time.RFC3339Nano)
|
||||
timeBeginning = strings.Replace(timeBeginning, "Z", ".000000000Z", -1)
|
||||
eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since='%s'", timeBeginning),
|
||||
fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
|
||||
fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
out, exitCode, err := runCommandWithOutput(eventsCmd)
|
||||
if exitCode != 0 || err != nil {
|
||||
t.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
|
||||
c.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
|
||||
}
|
||||
events := strings.Split(out, "\n")
|
||||
events = events[:len(events)-1]
|
||||
if len(events) < 4 {
|
||||
t.Fatalf("Missing expected event")
|
||||
c.Fatalf("Missing expected event")
|
||||
}
|
||||
createEvent := strings.Fields(events[len(events)-4])
|
||||
startEvent := strings.Fields(events[len(events)-3])
|
||||
dieEvent := strings.Fields(events[len(events)-2])
|
||||
destroyEvent := strings.Fields(events[len(events)-1])
|
||||
if createEvent[len(createEvent)-1] != "create" {
|
||||
t.Fatalf("event should be create, not %#v", createEvent)
|
||||
c.Fatalf("event should be create, not %#v", createEvent)
|
||||
}
|
||||
if startEvent[len(startEvent)-1] != "start" {
|
||||
t.Fatalf("event should be start, not %#v", startEvent)
|
||||
c.Fatalf("event should be start, not %#v", startEvent)
|
||||
}
|
||||
if dieEvent[len(dieEvent)-1] != "die" {
|
||||
t.Fatalf("event should be die, not %#v", dieEvent)
|
||||
c.Fatalf("event should be die, not %#v", dieEvent)
|
||||
}
|
||||
if destroyEvent[len(destroyEvent)-1] != "destroy" {
|
||||
t.Fatalf("event should be destroy, not %#v", destroyEvent)
|
||||
c.Fatalf("event should be destroy, not %#v", destroyEvent)
|
||||
}
|
||||
|
||||
logDone("events - container create, start, die, destroy since Unix Epoch time")
|
||||
}
|
||||
|
||||
func TestEventsImageUntagDelete(t *testing.T) {
|
||||
func (s *DockerSuite) TestEventsImageUntagDelete(c *check.C) {
|
||||
name := "testimageevents"
|
||||
defer deleteImages(name)
|
||||
_, err := buildImage(name,
|
||||
|
@ -156,67 +150,64 @@ func TestEventsImageUntagDelete(t *testing.T) {
|
|||
MAINTAINER "docker"`,
|
||||
true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if err := deleteImages(name); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
|
||||
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
out, exitCode, err := runCommandWithOutput(eventsCmd)
|
||||
if exitCode != 0 || err != nil {
|
||||
t.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
|
||||
c.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
|
||||
}
|
||||
events := strings.Split(out, "\n")
|
||||
|
||||
events = events[:len(events)-1]
|
||||
if len(events) < 2 {
|
||||
t.Fatalf("Missing expected event")
|
||||
c.Fatalf("Missing expected event")
|
||||
}
|
||||
untagEvent := strings.Fields(events[len(events)-2])
|
||||
deleteEvent := strings.Fields(events[len(events)-1])
|
||||
if untagEvent[len(untagEvent)-1] != "untag" {
|
||||
t.Fatalf("untag should be untag, not %#v", untagEvent)
|
||||
c.Fatalf("untag should be untag, not %#v", untagEvent)
|
||||
}
|
||||
if deleteEvent[len(deleteEvent)-1] != "delete" {
|
||||
t.Fatalf("delete should be delete, not %#v", deleteEvent)
|
||||
c.Fatalf("delete should be delete, not %#v", deleteEvent)
|
||||
}
|
||||
logDone("events - image untag, delete is logged")
|
||||
}
|
||||
|
||||
func TestEventsImagePull(t *testing.T) {
|
||||
since := daemonTime(t).Unix()
|
||||
testRequires(t, Network)
|
||||
func (s *DockerSuite) TestEventsImagePull(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
testRequires(c, Network)
|
||||
|
||||
defer deleteImages("hello-world")
|
||||
|
||||
pullCmd := exec.Command(dockerBinary, "pull", "hello-world")
|
||||
if out, _, err := runCommandWithOutput(pullCmd); err != nil {
|
||||
t.Fatalf("pulling the hello-world image from has failed: %s, %v", out, err)
|
||||
c.Fatalf("pulling the hello-world image from has failed: %s, %v", out, err)
|
||||
}
|
||||
|
||||
eventsCmd := exec.Command(dockerBinary, "events",
|
||||
fmt.Sprintf("--since=%d", since),
|
||||
fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
|
||||
fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
out, _, _ := runCommandWithOutput(eventsCmd)
|
||||
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
event := strings.TrimSpace(events[len(events)-1])
|
||||
|
||||
if !strings.HasSuffix(event, "hello-world:latest: pull") {
|
||||
t.Fatalf("Missing pull event - got:%q", event)
|
||||
c.Fatalf("Missing pull event - got:%q", event)
|
||||
}
|
||||
|
||||
logDone("events - image pull is logged")
|
||||
}
|
||||
|
||||
func TestEventsImageImport(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
since := daemonTime(t).Unix()
|
||||
func (s *DockerSuite) TestEventsImageImport(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal("failed to create a container", out, err)
|
||||
c.Fatal("failed to create a container", out, err)
|
||||
}
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
|
@ -225,25 +216,24 @@ func TestEventsImageImport(t *testing.T) {
|
|||
exec.Command(dockerBinary, "import", "-"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Errorf("import failed with errors: %v, output: %q", err, out)
|
||||
c.Errorf("import failed with errors: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
eventsCmd := exec.Command(dockerBinary, "events",
|
||||
fmt.Sprintf("--since=%d", since),
|
||||
fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
|
||||
fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
out, _, _ = runCommandWithOutput(eventsCmd)
|
||||
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
event := strings.TrimSpace(events[len(events)-1])
|
||||
|
||||
if !strings.HasSuffix(event, ": import") {
|
||||
t.Fatalf("Missing import event - got:%q", event)
|
||||
c.Fatalf("Missing import event - got:%q", event)
|
||||
}
|
||||
|
||||
logDone("events - image import is logged")
|
||||
}
|
||||
|
||||
func TestEventsFilters(t *testing.T) {
|
||||
func (s *DockerSuite) TestEventsFilters(c *check.C) {
|
||||
parseEvents := func(out, match string) {
|
||||
events := strings.Split(out, "\n")
|
||||
events = events[:len(events)-1]
|
||||
|
@ -251,67 +241,65 @@ func TestEventsFilters(t *testing.T) {
|
|||
eventFields := strings.Fields(event)
|
||||
eventName := eventFields[len(eventFields)-1]
|
||||
if ok, err := regexp.MatchString(match, eventName); err != nil || !ok {
|
||||
t.Fatalf("event should match %s, got %#v, err: %v", match, eventFields, err)
|
||||
c.Fatalf("event should match %s, got %#v, err: %v", match, eventFields, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
since := daemonTime(t).Unix()
|
||||
since := daemonTime(c).Unix()
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", "busybox", "true"))
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", "busybox", "true"))
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", "event=die"))
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "--filter", "event=die"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get events: %s", err)
|
||||
c.Fatalf("Failed to get events: %s", err)
|
||||
}
|
||||
parseEvents(out, "die")
|
||||
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", "event=die", "--filter", "event=start"))
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "--filter", "event=die", "--filter", "event=start"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get events: %s", err)
|
||||
c.Fatalf("Failed to get events: %s", err)
|
||||
}
|
||||
parseEvents(out, "((die)|(start))")
|
||||
|
||||
// make sure we at least got 2 start events
|
||||
count := strings.Count(out, "start")
|
||||
if count < 2 {
|
||||
t.Fatalf("should have had 2 start events but had %d, out: %s", count, out)
|
||||
c.Fatalf("should have had 2 start events but had %d, out: %s", count, out)
|
||||
}
|
||||
|
||||
logDone("events - filters")
|
||||
}
|
||||
|
||||
func TestEventsFilterImageName(t *testing.T) {
|
||||
since := daemonTime(t).Unix()
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestEventsFilterImageName(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_1", "-d", "busybox:latest", "true"))
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
container1 := strings.TrimSpace(out)
|
||||
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_2", "-d", "busybox", "true"))
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
container2 := strings.TrimSpace(out)
|
||||
|
||||
s := "busybox"
|
||||
eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", fmt.Sprintf("image=%s", s))
|
||||
name := "busybox"
|
||||
eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "--filter", fmt.Sprintf("image=%s", name))
|
||||
out, _, err = runCommandWithOutput(eventsCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get events, error: %s(%s)", err, out)
|
||||
c.Fatalf("Failed to get events, error: %s(%s)", err, out)
|
||||
}
|
||||
events := strings.Split(out, "\n")
|
||||
events = events[:len(events)-1]
|
||||
if len(events) == 0 {
|
||||
t.Fatalf("Expected events but found none for the image busybox:latest")
|
||||
c.Fatalf("Expected events but found none for the image busybox:latest")
|
||||
}
|
||||
count1 := 0
|
||||
count2 := 0
|
||||
|
@ -324,27 +312,25 @@ func TestEventsFilterImageName(t *testing.T) {
|
|||
}
|
||||
}
|
||||
if count1 == 0 || count2 == 0 {
|
||||
t.Fatalf("Expected events from each container but got %d from %s and %d from %s", count1, container1, count2, container2)
|
||||
c.Fatalf("Expected events from each container but got %d from %s and %d from %s", count1, container1, count2, container2)
|
||||
}
|
||||
|
||||
logDone("events - filters using image")
|
||||
}
|
||||
|
||||
func TestEventsFilterContainer(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
since := fmt.Sprintf("%d", daemonTime(t).Unix())
|
||||
func (s *DockerSuite) TestEventsFilterContainer(c *check.C) {
|
||||
since := fmt.Sprintf("%d", daemonTime(c).Unix())
|
||||
nameID := make(map[string]string)
|
||||
|
||||
for _, name := range []string{"container_1", "container_2"} {
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", name, "busybox", "true"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
nameID[name] = strings.TrimSpace(out)
|
||||
waitInspect(name, "{{.State.Runing }}", "false", 5)
|
||||
}
|
||||
|
||||
until := fmt.Sprintf("%d", daemonTime(t).Unix())
|
||||
until := fmt.Sprintf("%d", daemonTime(c).Unix())
|
||||
|
||||
checkEvents := func(id string, events []string) error {
|
||||
if len(events) != 3 { // create, start, die
|
||||
|
@ -370,32 +356,31 @@ func TestEventsFilterContainer(t *testing.T) {
|
|||
eventsCmd := exec.Command(dockerBinary, "events", "--since", since, "--until", until, "--filter", "container="+name)
|
||||
out, _, err := runCommandWithOutput(eventsCmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
events := strings.Split(strings.TrimSuffix(out, "\n"), "\n")
|
||||
if err := checkEvents(ID, events); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// filter by ID's
|
||||
eventsCmd = exec.Command(dockerBinary, "events", "--since", since, "--until", until, "--filter", "container="+ID)
|
||||
out, _, err = runCommandWithOutput(eventsCmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
events = strings.Split(strings.TrimSuffix(out, "\n"), "\n")
|
||||
if err := checkEvents(ID, events); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("events - filters using container name")
|
||||
}
|
||||
|
||||
func TestEventsStreaming(t *testing.T) {
|
||||
start := daemonTime(t).Unix()
|
||||
func (s *DockerSuite) TestEventsStreaming(c *check.C) {
|
||||
start := daemonTime(c).Unix()
|
||||
|
||||
finish := make(chan struct{})
|
||||
defer close(finish)
|
||||
|
@ -409,11 +394,11 @@ func TestEventsStreaming(t *testing.T) {
|
|||
eventsCmd := exec.Command(dockerBinary, "events", "--since", strconv.FormatInt(start, 10))
|
||||
stdout, err := eventsCmd.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
err = eventsCmd.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start 'docker events': %s", err)
|
||||
c.Fatalf("failed to start 'docker events': %s", err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
@ -444,35 +429,35 @@ func TestEventsStreaming(t *testing.T) {
|
|||
|
||||
err = eventsCmd.Wait()
|
||||
if err != nil && !IsKilled(err) {
|
||||
t.Fatalf("docker events had bad exit status: %s", err)
|
||||
c.Fatalf("docker events had bad exit status: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox:latest", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
id <- cleanedContainerID
|
||||
|
||||
select {
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("failed to observe container create in timely fashion")
|
||||
c.Fatal("failed to observe container create in timely fashion")
|
||||
case <-eventCreate:
|
||||
// ignore, done
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("failed to observe container start in timely fashion")
|
||||
c.Fatal("failed to observe container start in timely fashion")
|
||||
case <-eventStart:
|
||||
// ignore, done
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("failed to observe container die in timely fashion")
|
||||
c.Fatal("failed to observe container die in timely fashion")
|
||||
case <-eventDie:
|
||||
// ignore, done
|
||||
}
|
||||
|
@ -480,15 +465,14 @@ func TestEventsStreaming(t *testing.T) {
|
|||
rmCmd := exec.Command(dockerBinary, "rm", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(rmCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("failed to observe container destroy in timely fashion")
|
||||
c.Fatal("failed to observe container destroy in timely fashion")
|
||||
case <-eventDestroy:
|
||||
// ignore, done
|
||||
}
|
||||
|
||||
logDone("events - streamed to stdout")
|
||||
}
|
||||
|
|
|
@ -8,48 +8,46 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
"unicode"
|
||||
|
||||
"github.com/go-check/check"
|
||||
"github.com/kr/pty"
|
||||
)
|
||||
|
||||
// #5979
|
||||
func TestEventsRedirectStdout(t *testing.T) {
|
||||
since := daemonTime(t).Unix()
|
||||
dockerCmd(t, "run", "busybox", "true")
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestEventsRedirectStdout(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
dockerCmd(c, "run", "busybox", "true")
|
||||
|
||||
file, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
t.Fatalf("could not create temp file: %v", err)
|
||||
c.Fatalf("could not create temp file: %v", err)
|
||||
}
|
||||
defer os.Remove(file.Name())
|
||||
|
||||
command := fmt.Sprintf("%s events --since=%d --until=%d > %s", dockerBinary, since, daemonTime(t).Unix(), file.Name())
|
||||
command := fmt.Sprintf("%s events --since=%d --until=%d > %s", dockerBinary, since, daemonTime(c).Unix(), file.Name())
|
||||
_, tty, err := pty.Open()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not open pty: %v", err)
|
||||
c.Fatalf("Could not open pty: %v", err)
|
||||
}
|
||||
cmd := exec.Command("sh", "-c", command)
|
||||
cmd.Stdin = tty
|
||||
cmd.Stdout = tty
|
||||
cmd.Stderr = tty
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("run err for command %q: %v", command, err)
|
||||
c.Fatalf("run err for command %q: %v", command, err)
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
for _, c := range scanner.Text() {
|
||||
if unicode.IsControl(c) {
|
||||
t.Fatalf("found control character %v", []byte(string(c)))
|
||||
for _, ch := range scanner.Text() {
|
||||
if unicode.IsControl(ch) {
|
||||
c.Fatalf("found control character %v", []byte(string(ch)))
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
t.Fatalf("Scan err for command %q: %v", command, err)
|
||||
c.Fatalf("Scan err for command %q: %v", command, err)
|
||||
}
|
||||
|
||||
logDone("events - redirect stdout")
|
||||
}
|
||||
|
|
|
@ -12,38 +12,36 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestExec(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExec(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "sh", "-c", "echo test > /tmp/file && top")
|
||||
if out, _, _, err := runCommandWithStdoutStderr(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
execCmd := exec.Command(dockerBinary, "exec", "testing", "cat", "/tmp/file")
|
||||
out, _, err := runCommandWithOutput(execCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
out = strings.Trim(out, "\r\n")
|
||||
|
||||
if expected := "test"; out != expected {
|
||||
t.Errorf("container exec should've printed %q but printed %q", expected, out)
|
||||
c.Errorf("container exec should've printed %q but printed %q", expected, out)
|
||||
}
|
||||
|
||||
logDone("exec - basic test")
|
||||
}
|
||||
|
||||
func TestExecInteractiveStdinClose(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecInteractiveStdinClose(c *check.C) {
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-itd", "busybox", "/bin/cat"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
contId := strings.TrimSpace(out)
|
||||
|
@ -55,16 +53,16 @@ func TestExecInteractiveStdinClose(t *testing.T) {
|
|||
cmd := exec.Command(dockerBinary, "exec", "-i", contId, "/bin/ls", "/")
|
||||
cmd.Stdin = os.Stdin
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatal(err, string(out))
|
||||
c.Fatal(err, string(out))
|
||||
}
|
||||
|
||||
if string(out) == "" {
|
||||
t.Fatalf("Output was empty, likely blocked by standard input")
|
||||
c.Fatalf("Output was empty, likely blocked by standard input")
|
||||
}
|
||||
|
||||
returnchan <- struct{}{}
|
||||
|
@ -73,163 +71,153 @@ func TestExecInteractiveStdinClose(t *testing.T) {
|
|||
select {
|
||||
case <-returnchan:
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Fatal("timed out running docker exec")
|
||||
c.Fatal("timed out running docker exec")
|
||||
}
|
||||
|
||||
logDone("exec - interactive mode closes stdin after execution")
|
||||
}
|
||||
|
||||
func TestExecInteractive(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecInteractive(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "sh", "-c", "echo test > /tmp/file && top")
|
||||
if out, _, _, err := runCommandWithStdoutStderr(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
execCmd := exec.Command(dockerBinary, "exec", "-i", "testing", "sh")
|
||||
stdin, err := execCmd.StdinPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
stdout, err := execCmd.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if err := execCmd.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if _, err := stdin.Write([]byte("cat /tmp/file\n")); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
r := bufio.NewReader(stdout)
|
||||
line, err := r.ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
line = strings.TrimSpace(line)
|
||||
if line != "test" {
|
||||
t.Fatalf("Output should be 'test', got '%q'", line)
|
||||
c.Fatalf("Output should be 'test', got '%q'", line)
|
||||
}
|
||||
if err := stdin.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
finish := make(chan struct{})
|
||||
go func() {
|
||||
if err := execCmd.Wait(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
close(finish)
|
||||
}()
|
||||
select {
|
||||
case <-finish:
|
||||
case <-time.After(1 * time.Second):
|
||||
t.Fatal("docker exec failed to exit on stdin close")
|
||||
c.Fatal("docker exec failed to exit on stdin close")
|
||||
}
|
||||
|
||||
logDone("exec - Interactive test")
|
||||
}
|
||||
|
||||
func TestExecAfterContainerRestart(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecAfterContainerRestart(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "restart", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "exec", cleanedContainerID, "echo", "hello")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
outStr := strings.TrimSpace(out)
|
||||
if outStr != "hello" {
|
||||
t.Errorf("container should've printed hello, instead printed %q", outStr)
|
||||
c.Errorf("container should've printed hello, instead printed %q", outStr)
|
||||
}
|
||||
|
||||
logDone("exec - exec running container after container restart")
|
||||
}
|
||||
|
||||
func TestExecAfterDaemonRestart(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon)
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecAfterDaemonRestart(c *check.C) {
|
||||
testRequires(c, SameHostDaemon)
|
||||
|
||||
d := NewDaemon(t)
|
||||
d := NewDaemon(c)
|
||||
if err := d.StartWithBusybox(); err != nil {
|
||||
t.Fatalf("Could not start daemon with busybox: %v", err)
|
||||
c.Fatalf("Could not start daemon with busybox: %v", err)
|
||||
}
|
||||
defer d.Stop()
|
||||
|
||||
if out, err := d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top"); err != nil {
|
||||
t.Fatalf("Could not run top: err=%v\n%s", err, out)
|
||||
c.Fatalf("Could not run top: err=%v\n%s", err, out)
|
||||
}
|
||||
|
||||
if err := d.Restart(); err != nil {
|
||||
t.Fatalf("Could not restart daemon: %v", err)
|
||||
c.Fatalf("Could not restart daemon: %v", err)
|
||||
}
|
||||
|
||||
if out, err := d.Cmd("start", "top"); err != nil {
|
||||
t.Fatalf("Could not start top after daemon restart: err=%v\n%s", err, out)
|
||||
c.Fatalf("Could not start top after daemon restart: err=%v\n%s", err, out)
|
||||
}
|
||||
|
||||
out, err := d.Cmd("exec", "top", "echo", "hello")
|
||||
if err != nil {
|
||||
t.Fatalf("Could not exec on container top: err=%v\n%s", err, out)
|
||||
c.Fatalf("Could not exec on container top: err=%v\n%s", err, out)
|
||||
}
|
||||
|
||||
outStr := strings.TrimSpace(string(out))
|
||||
if outStr != "hello" {
|
||||
t.Errorf("container should've printed hello, instead printed %q", outStr)
|
||||
c.Errorf("container should've printed hello, instead printed %q", outStr)
|
||||
}
|
||||
|
||||
logDone("exec - exec running container after daemon restart")
|
||||
}
|
||||
|
||||
// Regression test for #9155, #9044
|
||||
func TestExecEnv(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecEnv(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run",
|
||||
"-e", "LALA=value1",
|
||||
"-e", "LALA=value2",
|
||||
"-d", "--name", "testing", "busybox", "top")
|
||||
if out, _, _, err := runCommandWithStdoutStderr(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
execCmd := exec.Command(dockerBinary, "exec", "testing", "env")
|
||||
out, _, err := runCommandWithOutput(execCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if strings.Contains(out, "LALA=value1") ||
|
||||
!strings.Contains(out, "LALA=value2") ||
|
||||
!strings.Contains(out, "HOME=/root") {
|
||||
t.Errorf("exec env(%q), expect %q, %q", out, "LALA=value2", "HOME=/root")
|
||||
c.Errorf("exec env(%q), expect %q, %q", out, "LALA=value2", "HOME=/root")
|
||||
}
|
||||
|
||||
logDone("exec - exec inherits correct env")
|
||||
}
|
||||
|
||||
func TestExecExitStatus(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecExitStatus(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "top", "busybox", "top")
|
||||
if out, _, _, err := runCommandWithStdoutStderr(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
// Test normal (non-detached) case first
|
||||
|
@ -237,20 +225,18 @@ func TestExecExitStatus(t *testing.T) {
|
|||
ec, _ := runCommand(cmd)
|
||||
|
||||
if ec != 23 {
|
||||
t.Fatalf("Should have had an ExitCode of 23, not: %d", ec)
|
||||
c.Fatalf("Should have had an ExitCode of 23, not: %d", ec)
|
||||
}
|
||||
|
||||
logDone("exec - exec non-zero ExitStatus")
|
||||
}
|
||||
|
||||
func TestExecPausedContainer(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecPausedContainer(c *check.C) {
|
||||
defer unpauseAllContainers()
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
ContainerID := strings.TrimSpace(out)
|
||||
|
@ -258,82 +244,78 @@ func TestExecPausedContainer(t *testing.T) {
|
|||
pausedCmd := exec.Command(dockerBinary, "pause", "testing")
|
||||
out, _, _, err = runCommandWithStdoutStderr(pausedCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
execCmd := exec.Command(dockerBinary, "exec", "-i", "-t", ContainerID, "echo", "hello")
|
||||
out, _, err = runCommandWithOutput(execCmd)
|
||||
if err == nil {
|
||||
t.Fatal("container should fail to exec new command if it is paused")
|
||||
c.Fatal("container should fail to exec new command if it is paused")
|
||||
}
|
||||
|
||||
expected := ContainerID + " is paused, unpause the container before exec"
|
||||
if !strings.Contains(out, expected) {
|
||||
t.Fatal("container should not exec new command if it is paused")
|
||||
c.Fatal("container should not exec new command if it is paused")
|
||||
}
|
||||
|
||||
logDone("exec - exec should not exec a pause container")
|
||||
}
|
||||
|
||||
// regression test for #9476
|
||||
func TestExecTtyCloseStdin(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecTtyCloseStdin(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "-d", "-it", "--name", "exec_tty_stdin", "busybox")
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "exec", "-i", "exec_tty_stdin", "cat")
|
||||
stdinRw, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
stdinRw.Write([]byte("test"))
|
||||
stdinRw.Close()
|
||||
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "top", "exec_tty_stdin")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
outArr := strings.Split(out, "\n")
|
||||
if len(outArr) > 3 || strings.Contains(out, "nsenter-exec") {
|
||||
// This is the really bad part
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "rm", "-f", "exec_tty_stdin")); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
t.Fatalf("exec process left running\n\t %s", out)
|
||||
c.Fatalf("exec process left running\n\t %s", out)
|
||||
}
|
||||
|
||||
logDone("exec - stdin is closed properly with tty enabled")
|
||||
}
|
||||
|
||||
func TestExecTtyWithoutStdin(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecTtyWithoutStdin(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "-d", "-ti", "busybox")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start container: %v (%v)", out, err)
|
||||
c.Fatalf("failed to start container: %v (%v)", out, err)
|
||||
}
|
||||
|
||||
id := strings.TrimSpace(out)
|
||||
if err := waitRun(id); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
cmd := exec.Command(dockerBinary, "kill", id)
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
t.Fatalf("failed to kill container: %v (%v)", out, err)
|
||||
c.Fatalf("failed to kill container: %v (%v)", out, err)
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -343,86 +325,80 @@ func TestExecTtyWithoutStdin(t *testing.T) {
|
|||
|
||||
cmd := exec.Command(dockerBinary, "exec", "-ti", id, "true")
|
||||
if _, err := cmd.StdinPipe(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
expected := "cannot enable tty mode"
|
||||
if out, _, err := runCommandWithOutput(cmd); err == nil {
|
||||
t.Fatal("exec should have failed")
|
||||
c.Fatal("exec should have failed")
|
||||
} else if !strings.Contains(out, expected) {
|
||||
t.Fatalf("exec failed with error %q: expected %q", out, expected)
|
||||
c.Fatalf("exec failed with error %q: expected %q", out, expected)
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("exec is running but should have failed")
|
||||
c.Fatal("exec is running but should have failed")
|
||||
}
|
||||
|
||||
logDone("exec - forbid piped stdin to tty enabled container")
|
||||
}
|
||||
|
||||
func TestExecParseError(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecParseError(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "top", "busybox", "top")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
// Test normal (non-detached) case first
|
||||
cmd := exec.Command(dockerBinary, "exec", "top")
|
||||
if _, stderr, code, err := runCommandWithStdoutStderr(cmd); err == nil || !strings.Contains(stderr, "See '"+dockerBinary+" exec --help'") || code == 0 {
|
||||
t.Fatalf("Should have thrown error & point to help: %s", stderr)
|
||||
c.Fatalf("Should have thrown error & point to help: %s", stderr)
|
||||
}
|
||||
logDone("exec - error on parseExec should point to help")
|
||||
}
|
||||
|
||||
func TestExecStopNotHanging(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecStopNotHanging(c *check.C) {
|
||||
if out, err := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "top").CombinedOutput(); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if err := exec.Command(dockerBinary, "exec", "testing", "top").Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
wait := make(chan struct{})
|
||||
go func() {
|
||||
if out, err := exec.Command(dockerBinary, "stop", "testing").CombinedOutput(); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
close(wait)
|
||||
}()
|
||||
select {
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("Container stop timed out")
|
||||
c.Fatal("Container stop timed out")
|
||||
case <-wait:
|
||||
}
|
||||
logDone("exec - container with exec not hanging on stop")
|
||||
}
|
||||
|
||||
func TestExecCgroup(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecCgroup(c *check.C) {
|
||||
var cmd *exec.Cmd
|
||||
|
||||
cmd = exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "top")
|
||||
_, err := runCommand(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "exec", "testing", "cat", "/proc/1/cgroup")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerCgroups := sort.StringSlice(strings.Split(string(out), "\n"))
|
||||
|
||||
var wg sync.WaitGroup
|
||||
var s sync.Mutex
|
||||
var mu sync.Mutex
|
||||
execCgroups := []sort.StringSlice{}
|
||||
// exec a few times concurrently to get consistent failure
|
||||
for i := 0; i < 5; i++ {
|
||||
|
@ -431,13 +407,13 @@ func TestExecCgroup(t *testing.T) {
|
|||
cmd := exec.Command(dockerBinary, "exec", "testing", "cat", "/proc/self/cgroup")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
cg := sort.StringSlice(strings.Split(string(out), "\n"))
|
||||
|
||||
s.Lock()
|
||||
mu.Lock()
|
||||
execCgroups = append(execCgroups, cg)
|
||||
s.Unlock()
|
||||
mu.Unlock()
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
|
@ -454,86 +430,81 @@ func TestExecCgroup(t *testing.T) {
|
|||
for _, name := range containerCgroups {
|
||||
fmt.Printf(" %s\n", name)
|
||||
}
|
||||
t.Fatal("cgroups mismatched")
|
||||
c.Fatal("cgroups mismatched")
|
||||
}
|
||||
}
|
||||
|
||||
logDone("exec - exec has the container cgroups")
|
||||
}
|
||||
|
||||
func TestInspectExecID(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestInspectExecID(c *check.C) {
|
||||
|
||||
out, exitCode, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "busybox", "top"))
|
||||
if exitCode != 0 || err != nil {
|
||||
t.Fatalf("failed to run container: %s, %v", out, err)
|
||||
c.Fatalf("failed to run container: %s, %v", out, err)
|
||||
}
|
||||
id := strings.TrimSuffix(out, "\n")
|
||||
|
||||
out, err = inspectField(id, "ExecIDs")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to inspect container: %s, %v", out, err)
|
||||
c.Fatalf("failed to inspect container: %s, %v", out, err)
|
||||
}
|
||||
if out != "<no value>" {
|
||||
t.Fatalf("ExecIDs should be empty, got: %s", out)
|
||||
c.Fatalf("ExecIDs should be empty, got: %s", out)
|
||||
}
|
||||
|
||||
exitCode, err = runCommand(exec.Command(dockerBinary, "exec", "-d", id, "ls", "/"))
|
||||
if exitCode != 0 || err != nil {
|
||||
t.Fatalf("failed to exec in container: %s, %v", out, err)
|
||||
c.Fatalf("failed to exec in container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
out, err = inspectField(id, "ExecIDs")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to inspect container: %s, %v", out, err)
|
||||
c.Fatalf("failed to inspect container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
out = strings.TrimSuffix(out, "\n")
|
||||
if out == "[]" || out == "<no value>" {
|
||||
t.Fatalf("ExecIDs should not be empty, got: %s", out)
|
||||
c.Fatalf("ExecIDs should not be empty, got: %s", out)
|
||||
}
|
||||
|
||||
logDone("inspect - inspect a container with ExecIDs")
|
||||
}
|
||||
|
||||
func TestLinksPingLinkedContainersOnRename(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLinksPingLinkedContainersOnRename(c *check.C) {
|
||||
|
||||
var out string
|
||||
out, _ = dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "top")
|
||||
out, _ = dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top")
|
||||
idA := strings.TrimSpace(out)
|
||||
if idA == "" {
|
||||
t.Fatal(out, "id should not be nil")
|
||||
c.Fatal(out, "id should not be nil")
|
||||
}
|
||||
out, _ = dockerCmd(t, "run", "-d", "--link", "container1:alias1", "--name", "container2", "busybox", "top")
|
||||
out, _ = dockerCmd(c, "run", "-d", "--link", "container1:alias1", "--name", "container2", "busybox", "top")
|
||||
idB := strings.TrimSpace(out)
|
||||
if idB == "" {
|
||||
t.Fatal(out, "id should not be nil")
|
||||
c.Fatal(out, "id should not be nil")
|
||||
}
|
||||
|
||||
execCmd := exec.Command(dockerBinary, "exec", "container2", "ping", "-c", "1", "alias1", "-W", "1")
|
||||
out, _, err := runCommandWithOutput(execCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
dockerCmd(t, "rename", "container1", "container_new")
|
||||
dockerCmd(c, "rename", "container1", "container_new")
|
||||
|
||||
execCmd = exec.Command(dockerBinary, "exec", "container2", "ping", "-c", "1", "alias1", "-W", "1")
|
||||
out, _, err = runCommandWithOutput(execCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
logDone("links - ping linked container upon rename")
|
||||
}
|
||||
|
||||
func TestRunExecDir(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon)
|
||||
func (s *DockerSuite) TestRunExecDir(c *check.C) {
|
||||
testRequires(c, SameHostDaemon)
|
||||
cmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
id := strings.TrimSpace(out)
|
||||
execDir := filepath.Join(execDriverPath, id)
|
||||
|
@ -542,92 +513,90 @@ func TestRunExecDir(t *testing.T) {
|
|||
{
|
||||
fi, err := os.Stat(execDir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if !fi.IsDir() {
|
||||
t.Fatalf("%q must be a directory", execDir)
|
||||
c.Fatalf("%q must be a directory", execDir)
|
||||
}
|
||||
fi, err = os.Stat(stateFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
stopCmd := exec.Command(dockerBinary, "stop", id)
|
||||
out, _, err = runCommandWithOutput(stopCmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
{
|
||||
_, err := os.Stat(execDir)
|
||||
if err == nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatalf("Exec directory %q exists for removed container!", execDir)
|
||||
c.Fatalf("Exec directory %q exists for removed container!", execDir)
|
||||
}
|
||||
if !os.IsNotExist(err) {
|
||||
t.Fatalf("Error should be about non-existing, got %s", err)
|
||||
c.Fatalf("Error should be about non-existing, got %s", err)
|
||||
}
|
||||
}
|
||||
startCmd := exec.Command(dockerBinary, "start", id)
|
||||
out, _, err = runCommandWithOutput(startCmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
{
|
||||
fi, err := os.Stat(execDir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if !fi.IsDir() {
|
||||
t.Fatalf("%q must be a directory", execDir)
|
||||
c.Fatalf("%q must be a directory", execDir)
|
||||
}
|
||||
fi, err = os.Stat(stateFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
}
|
||||
rmCmd := exec.Command(dockerBinary, "rm", "-f", id)
|
||||
out, _, err = runCommandWithOutput(rmCmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
{
|
||||
_, err := os.Stat(execDir)
|
||||
if err == nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatalf("Exec directory %q is exists for removed container!", execDir)
|
||||
c.Fatalf("Exec directory %q is exists for removed container!", execDir)
|
||||
}
|
||||
if !os.IsNotExist(err) {
|
||||
t.Fatalf("Error should be about non-existing, got %s", err)
|
||||
c.Fatalf("Error should be about non-existing, got %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("run - check execdriver dir behavior")
|
||||
}
|
||||
|
||||
func TestRunMutableNetworkFiles(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon)
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRunMutableNetworkFiles(c *check.C) {
|
||||
testRequires(c, SameHostDaemon)
|
||||
|
||||
for _, fn := range []string{"resolv.conf", "hosts"} {
|
||||
deleteAllContainers()
|
||||
|
||||
content, err := runCommandAndReadContainerFile(fn, exec.Command(dockerBinary, "run", "-d", "--name", "c1", "busybox", "sh", "-c", fmt.Sprintf("echo success >/etc/%s && top", fn)))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if strings.TrimSpace(string(content)) != "success" {
|
||||
t.Fatal("Content was not what was modified in the container", string(content))
|
||||
c.Fatal("Content was not what was modified in the container", string(content))
|
||||
}
|
||||
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "c2", "busybox", "top"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
contID := strings.TrimSpace(out)
|
||||
|
@ -636,88 +605,83 @@ func TestRunMutableNetworkFiles(t *testing.T) {
|
|||
|
||||
f, err := os.OpenFile(netFilePath, os.O_WRONLY|os.O_SYNC|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := f.Seek(0, 0); err != nil {
|
||||
f.Close()
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if err := f.Truncate(0); err != nil {
|
||||
f.Close()
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := f.Write([]byte("success2\n")); err != nil {
|
||||
f.Close()
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
f.Close()
|
||||
|
||||
res, err := exec.Command(dockerBinary, "exec", contID, "cat", "/etc/"+fn).CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("Output: %s, error: %s", res, err)
|
||||
c.Fatalf("Output: %s, error: %s", res, err)
|
||||
}
|
||||
if string(res) != "success2\n" {
|
||||
t.Fatalf("Expected content of %s: %q, got: %q", fn, "success2\n", res)
|
||||
c.Fatalf("Expected content of %s: %q, got: %q", fn, "success2\n", res)
|
||||
}
|
||||
}
|
||||
logDone("run - mutable network files")
|
||||
}
|
||||
|
||||
func TestExecWithUser(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecWithUser(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "parent", "busybox", "top")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cmd := exec.Command(dockerBinary, "exec", "-u", "1", "parent", "id")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
if !strings.Contains(out, "uid=1(daemon) gid=1(daemon)") {
|
||||
t.Fatalf("exec with user by id expected daemon user got %s", out)
|
||||
c.Fatalf("exec with user by id expected daemon user got %s", out)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "exec", "-u", "root", "parent", "id")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
if !strings.Contains(out, "uid=0(root) gid=0(root)") {
|
||||
t.Fatalf("exec with user by root expected root user got %s", out)
|
||||
c.Fatalf("exec with user by root expected root user got %s", out)
|
||||
}
|
||||
|
||||
logDone("exec - with user")
|
||||
}
|
||||
|
||||
func TestExecWithPrivileged(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestExecWithPrivileged(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "parent", "--cap-drop=ALL", "busybox", "top")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cmd := exec.Command(dockerBinary, "exec", "parent", "sh", "-c", "mknod /tmp/sda b 8 0")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err == nil || !strings.Contains(out, "Operation not permitted") {
|
||||
t.Fatalf("exec mknod in --cap-drop=ALL container without --privileged should failed")
|
||||
c.Fatalf("exec mknod in --cap-drop=ALL container without --privileged should failed")
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "exec", "--privileged", "parent", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
if actual := strings.TrimSpace(out); actual != "ok" {
|
||||
t.Fatalf("exec mknod in --cap-drop=ALL container with --privileged failed: %v, output: %q", err, out)
|
||||
c.Fatalf("exec mknod in --cap-drop=ALL container with --privileged failed: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
logDone("exec - exec command in a container with privileged")
|
||||
}
|
||||
|
|
|
@ -4,11 +4,12 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// export an image and try to import it into a new one
|
||||
func TestExportContainerAndImportImage(t *testing.T) {
|
||||
func (s *DockerSuite) TestExportContainerAndImportImage(c *check.C) {
|
||||
containerID := "testexportcontainerandimportimage"
|
||||
|
||||
defer deleteImages("repo/testexp:v1")
|
||||
|
@ -17,39 +18,38 @@ func TestExportContainerAndImportImage(t *testing.T) {
|
|||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", containerID, "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal("failed to create a container", out, err)
|
||||
c.Fatal("failed to create a container", out, err)
|
||||
}
|
||||
|
||||
inspectCmd := exec.Command(dockerBinary, "inspect", containerID)
|
||||
out, _, err = runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("output should've been a container id: %s %s ", containerID, err)
|
||||
c.Fatalf("output should've been a container id: %s %s ", containerID, err)
|
||||
}
|
||||
|
||||
exportCmd := exec.Command(dockerBinary, "export", containerID)
|
||||
if out, _, err = runCommandWithOutput(exportCmd); err != nil {
|
||||
t.Fatalf("failed to export container: %s, %v", out, err)
|
||||
c.Fatalf("failed to export container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
importCmd := exec.Command(dockerBinary, "import", "-", "repo/testexp:v1")
|
||||
importCmd.Stdin = strings.NewReader(out)
|
||||
out, _, err = runCommandWithOutput(importCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to import image: %s, %v", out, err)
|
||||
c.Fatalf("failed to import image: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
|
||||
inspectCmd = exec.Command(dockerBinary, "inspect", cleanedImageID)
|
||||
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
|
||||
t.Fatalf("output should've been an image id: %s, %v", out, err)
|
||||
c.Fatalf("output should've been an image id: %s, %v", out, err)
|
||||
}
|
||||
|
||||
logDone("export - export/import a container/image")
|
||||
}
|
||||
|
||||
// Used to test output flag in the export command
|
||||
func TestExportContainerWithOutputAndImportImage(t *testing.T) {
|
||||
func (s *DockerSuite) TestExportContainerWithOutputAndImportImage(c *check.C) {
|
||||
containerID := "testexportcontainerwithoutputandimportimage"
|
||||
|
||||
defer deleteImages("repo/testexp:v1")
|
||||
|
@ -58,40 +58,39 @@ func TestExportContainerWithOutputAndImportImage(t *testing.T) {
|
|||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", containerID, "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal("failed to create a container", out, err)
|
||||
c.Fatal("failed to create a container", out, err)
|
||||
}
|
||||
|
||||
inspectCmd := exec.Command(dockerBinary, "inspect", containerID)
|
||||
out, _, err = runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("output should've been a container id: %s %s ", containerID, err)
|
||||
c.Fatalf("output should've been a container id: %s %s ", containerID, err)
|
||||
}
|
||||
|
||||
defer os.Remove("testexp.tar")
|
||||
|
||||
exportCmd := exec.Command(dockerBinary, "export", "--output=testexp.tar", containerID)
|
||||
if out, _, err = runCommandWithOutput(exportCmd); err != nil {
|
||||
t.Fatalf("failed to export container: %s, %v", out, err)
|
||||
c.Fatalf("failed to export container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
out, _, err = runCommandWithOutput(exec.Command("cat", "testexp.tar"))
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
importCmd := exec.Command(dockerBinary, "import", "-", "repo/testexp:v1")
|
||||
importCmd.Stdin = strings.NewReader(out)
|
||||
out, _, err = runCommandWithOutput(importCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to import image: %s, %v", out, err)
|
||||
c.Fatalf("failed to import image: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
|
||||
inspectCmd = exec.Command(dockerBinary, "inspect", cleanedImageID)
|
||||
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
|
||||
t.Fatalf("output should've been an image id: %s, %v", out, err)
|
||||
c.Fatalf("output should've been an image id: %s, %v", out, err)
|
||||
}
|
||||
|
||||
logDone("export - export/import a container/image with output flag")
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@ import (
|
|||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"unicode"
|
||||
|
||||
"github.com/docker/docker/pkg/homedir"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestHelpTextVerify(t *testing.T) {
|
||||
func (s *DockerSuite) TestHelpTextVerify(c *check.C) {
|
||||
// Make sure main help text fits within 80 chars and that
|
||||
// on non-windows system we use ~ when possible (to shorten things).
|
||||
// Test for HOME set to its default value and set to "/" on linux
|
||||
|
@ -51,26 +51,26 @@ func TestHelpTextVerify(t *testing.T) {
|
|||
helpCmd.Env = newEnvs
|
||||
out, ec, err := runCommandWithOutput(helpCmd)
|
||||
if err != nil || ec != 0 {
|
||||
t.Fatalf("docker help should have worked\nout:%s\nec:%d", out, ec)
|
||||
c.Fatalf("docker help should have worked\nout:%s\nec:%d", out, ec)
|
||||
}
|
||||
lines := strings.Split(out, "\n")
|
||||
for _, line := range lines {
|
||||
if len(line) > 80 {
|
||||
t.Fatalf("Line is too long(%d chars):\n%s", len(line), line)
|
||||
c.Fatalf("Line is too long(%d chars):\n%s", len(line), line)
|
||||
}
|
||||
|
||||
// All lines should not end with a space
|
||||
if strings.HasSuffix(line, " ") {
|
||||
t.Fatalf("Line should not end with a space: %s", line)
|
||||
c.Fatalf("Line should not end with a space: %s", line)
|
||||
}
|
||||
|
||||
if scanForHome && strings.Contains(line, `=`+home) {
|
||||
t.Fatalf("Line should use '%q' instead of %q:\n%s", homedir.GetShortcutString(), home, line)
|
||||
c.Fatalf("Line should use '%q' instead of %q:\n%s", homedir.GetShortcutString(), home, line)
|
||||
}
|
||||
if runtime.GOOS != "windows" {
|
||||
i := strings.Index(line, homedir.GetShortcutString())
|
||||
if i >= 0 && i != len(line)-1 && line[i+1] != '/' {
|
||||
t.Fatalf("Main help should not have used home shortcut:\n%s", line)
|
||||
c.Fatalf("Main help should not have used home shortcut:\n%s", line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,11 +82,11 @@ func TestHelpTextVerify(t *testing.T) {
|
|||
helpCmd.Env = newEnvs
|
||||
out, ec, err = runCommandWithOutput(helpCmd)
|
||||
if err != nil || ec != 0 {
|
||||
t.Fatalf("docker help should have worked\nout:%s\nec:%d", out, ec)
|
||||
c.Fatalf("docker help should have worked\nout:%s\nec:%d", out, ec)
|
||||
}
|
||||
i := strings.Index(out, "Commands:")
|
||||
if i < 0 {
|
||||
t.Fatalf("Missing 'Commands:' in:\n%s", out)
|
||||
c.Fatalf("Missing 'Commands:' in:\n%s", out)
|
||||
}
|
||||
|
||||
// Grab all chars starting at "Commands:"
|
||||
|
@ -106,39 +106,39 @@ func TestHelpTextVerify(t *testing.T) {
|
|||
helpCmd.Env = newEnvs
|
||||
out, ec, err := runCommandWithOutput(helpCmd)
|
||||
if err != nil || ec != 0 {
|
||||
t.Fatalf("Error on %q help: %s\nexit code:%d", cmd, out, ec)
|
||||
c.Fatalf("Error on %q help: %s\nexit code:%d", cmd, out, ec)
|
||||
}
|
||||
lines := strings.Split(out, "\n")
|
||||
for _, line := range lines {
|
||||
if len(line) > 80 {
|
||||
t.Fatalf("Help for %q is too long(%d chars):\n%s", cmd,
|
||||
c.Fatalf("Help for %q is too long(%d chars):\n%s", cmd,
|
||||
len(line), line)
|
||||
}
|
||||
|
||||
if scanForHome && strings.Contains(line, `"`+home) {
|
||||
t.Fatalf("Help for %q should use ~ instead of %q on:\n%s",
|
||||
c.Fatalf("Help for %q should use ~ instead of %q on:\n%s",
|
||||
cmd, home, line)
|
||||
}
|
||||
i := strings.Index(line, "~")
|
||||
if i >= 0 && i != len(line)-1 && line[i+1] != '/' {
|
||||
t.Fatalf("Help for %q should not have used ~:\n%s", cmd, line)
|
||||
c.Fatalf("Help for %q should not have used ~:\n%s", cmd, line)
|
||||
}
|
||||
|
||||
// If a line starts with 4 spaces then assume someone
|
||||
// added a multi-line description for an option and we need
|
||||
// to flag it
|
||||
if strings.HasPrefix(line, " ") {
|
||||
t.Fatalf("Help for %q should not have a multi-line option: %s", cmd, line)
|
||||
c.Fatalf("Help for %q should not have a multi-line option: %s", cmd, line)
|
||||
}
|
||||
|
||||
// Options should NOT end with a period
|
||||
if strings.HasPrefix(line, " -") && strings.HasSuffix(line, ".") {
|
||||
t.Fatalf("Help for %q should not end with a period: %s", cmd, line)
|
||||
c.Fatalf("Help for %q should not end with a period: %s", cmd, line)
|
||||
}
|
||||
|
||||
// Options should NOT end with a space
|
||||
if strings.HasSuffix(line, " ") {
|
||||
t.Fatalf("Help for %q should not end with a space: %s", cmd, line)
|
||||
c.Fatalf("Help for %q should not end with a space: %s", cmd, line)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -146,10 +146,9 @@ func TestHelpTextVerify(t *testing.T) {
|
|||
|
||||
expected := 39
|
||||
if len(cmds) != expected {
|
||||
t.Fatalf("Wrong # of cmds(%d), it should be: %d\nThe list:\n%q",
|
||||
c.Fatalf("Wrong # of cmds(%d), it should be: %d\nThe list:\n%q",
|
||||
len(cmds), expected, cmds)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("help - verify text")
|
||||
}
|
||||
|
|
|
@ -4,12 +4,13 @@ import (
|
|||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// This is a heisen-test. Because the created timestamp of images and the behavior of
|
||||
// sort is not predictable it doesn't always fail.
|
||||
func TestBuildHistory(t *testing.T) {
|
||||
func (s *DockerSuite) TestBuildHistory(c *check.C) {
|
||||
name := "testbuildhistory"
|
||||
defer deleteImages(name)
|
||||
_, err := buildImage(name, `FROM busybox
|
||||
|
@ -42,12 +43,12 @@ RUN echo "Z"`,
|
|||
true)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
out, exitCode, err := runCommandWithOutput(exec.Command(dockerBinary, "history", "testbuildhistory"))
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Fatalf("failed to get image history: %s, %v", out, err)
|
||||
c.Fatalf("failed to get image history: %s, %v", out, err)
|
||||
}
|
||||
|
||||
actualValues := strings.Split(out, "\n")[1:27]
|
||||
|
@ -58,32 +59,29 @@ RUN echo "Z"`,
|
|||
actualValue := actualValues[i]
|
||||
|
||||
if !strings.Contains(actualValue, echoValue) {
|
||||
t.Fatalf("Expected layer \"%s\", but was: %s", expectedValues[i], actualValue)
|
||||
c.Fatalf("Expected layer \"%s\", but was: %s", expectedValues[i], actualValue)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("history - build history")
|
||||
}
|
||||
|
||||
func TestHistoryExistentImage(t *testing.T) {
|
||||
func (s *DockerSuite) TestHistoryExistentImage(c *check.C) {
|
||||
historyCmd := exec.Command(dockerBinary, "history", "busybox")
|
||||
_, exitCode, err := runCommandWithOutput(historyCmd)
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Fatal("failed to get image history")
|
||||
c.Fatal("failed to get image history")
|
||||
}
|
||||
logDone("history - history on existent image must pass")
|
||||
}
|
||||
|
||||
func TestHistoryNonExistentImage(t *testing.T) {
|
||||
func (s *DockerSuite) TestHistoryNonExistentImage(c *check.C) {
|
||||
historyCmd := exec.Command(dockerBinary, "history", "testHistoryNonExistentImage")
|
||||
_, exitCode, err := runCommandWithOutput(historyCmd)
|
||||
if err == nil || exitCode == 0 {
|
||||
t.Fatal("history on a non-existent image didn't result in a non-zero exit status")
|
||||
c.Fatal("history on a non-existent image didn't result in a non-zero exit status")
|
||||
}
|
||||
logDone("history - history on non-existent image must pass")
|
||||
}
|
||||
|
||||
func TestHistoryImageWithComment(t *testing.T) {
|
||||
func (s *DockerSuite) TestHistoryImageWithComment(c *check.C) {
|
||||
name := "testhistoryimagewithcomment"
|
||||
defer deleteContainer(name)
|
||||
defer deleteImages(name)
|
||||
|
@ -93,26 +91,26 @@ func TestHistoryImageWithComment(t *testing.T) {
|
|||
runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run container: %s, %v", out, err)
|
||||
c.Fatalf("failed to run container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
waitCmd := exec.Command(dockerBinary, "wait", name)
|
||||
if out, _, err := runCommandWithOutput(waitCmd); err != nil {
|
||||
t.Fatalf("error thrown while waiting for container: %s, %v", out, err)
|
||||
c.Fatalf("error thrown while waiting for container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
comment := "This_is_a_comment"
|
||||
|
||||
commitCmd := exec.Command(dockerBinary, "commit", "-m="+comment, name, name)
|
||||
if out, _, err := runCommandWithOutput(commitCmd); err != nil {
|
||||
t.Fatalf("failed to commit container to image: %s, %v", out, err)
|
||||
c.Fatalf("failed to commit container to image: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// test docker history <image id> to check comment messages
|
||||
historyCmd := exec.Command(dockerBinary, "history", name)
|
||||
out, exitCode, err := runCommandWithOutput(historyCmd)
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Fatalf("failed to get image history: %s, %v", out, err)
|
||||
c.Fatalf("failed to get image history: %s, %v", out, err)
|
||||
}
|
||||
|
||||
outputTabs := strings.Fields(strings.Split(out, "\n")[1])
|
||||
|
@ -120,8 +118,7 @@ func TestHistoryImageWithComment(t *testing.T) {
|
|||
actualValue := outputTabs[len(outputTabs)-1]
|
||||
|
||||
if !strings.Contains(actualValue, comment) {
|
||||
t.Fatalf("Expected comments %q, but found %q", comment, actualValue)
|
||||
c.Fatalf("Expected comments %q, but found %q", comment, actualValue)
|
||||
}
|
||||
|
||||
logDone("history - history on image with comment")
|
||||
}
|
||||
|
|
|
@ -6,27 +6,26 @@ import (
|
|||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestImagesEnsureImageIsListed(t *testing.T) {
|
||||
func (s *DockerSuite) TestImagesEnsureImageIsListed(c *check.C) {
|
||||
imagesCmd := exec.Command(dockerBinary, "images")
|
||||
out, _, err := runCommandWithOutput(imagesCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("listing images failed with errors: %s, %v", out, err)
|
||||
c.Fatalf("listing images failed with errors: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if !strings.Contains(out, "busybox") {
|
||||
t.Fatal("images should've listed busybox")
|
||||
c.Fatal("images should've listed busybox")
|
||||
}
|
||||
|
||||
logDone("images - busybox should be listed")
|
||||
}
|
||||
|
||||
func TestImagesOrderedByCreationDate(t *testing.T) {
|
||||
func (s *DockerSuite) TestImagesOrderedByCreationDate(c *check.C) {
|
||||
defer deleteImages("order:test_a")
|
||||
defer deleteImages("order:test_c")
|
||||
defer deleteImages("order:test_b")
|
||||
|
@ -34,56 +33,53 @@ func TestImagesOrderedByCreationDate(t *testing.T) {
|
|||
`FROM scratch
|
||||
MAINTAINER dockerio1`, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
id2, err := buildImage("order:test_c",
|
||||
`FROM scratch
|
||||
MAINTAINER dockerio2`, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
id3, err := buildImage("order:test_b",
|
||||
`FROM scratch
|
||||
MAINTAINER dockerio3`, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "images", "-q", "--no-trunc"))
|
||||
if err != nil {
|
||||
t.Fatalf("listing images failed with errors: %s, %v", out, err)
|
||||
c.Fatalf("listing images failed with errors: %s, %v", out, err)
|
||||
}
|
||||
imgs := strings.Split(out, "\n")
|
||||
if imgs[0] != id3 {
|
||||
t.Fatalf("First image must be %s, got %s", id3, imgs[0])
|
||||
c.Fatalf("First image must be %s, got %s", id3, imgs[0])
|
||||
}
|
||||
if imgs[1] != id2 {
|
||||
t.Fatalf("Second image must be %s, got %s", id2, imgs[1])
|
||||
c.Fatalf("Second image must be %s, got %s", id2, imgs[1])
|
||||
}
|
||||
if imgs[2] != id1 {
|
||||
t.Fatalf("Third image must be %s, got %s", id1, imgs[2])
|
||||
c.Fatalf("Third image must be %s, got %s", id1, imgs[2])
|
||||
}
|
||||
|
||||
logDone("images - ordering by creation date")
|
||||
}
|
||||
|
||||
func TestImagesErrorWithInvalidFilterNameTest(t *testing.T) {
|
||||
func (s *DockerSuite) TestImagesErrorWithInvalidFilterNameTest(c *check.C) {
|
||||
imagesCmd := exec.Command(dockerBinary, "images", "-f", "FOO=123")
|
||||
out, _, err := runCommandWithOutput(imagesCmd)
|
||||
if !strings.Contains(out, "Invalid filter") {
|
||||
t.Fatalf("error should occur when listing images with invalid filter name FOO, %s, %v", out, err)
|
||||
c.Fatalf("error should occur when listing images with invalid filter name FOO, %s, %v", out, err)
|
||||
}
|
||||
|
||||
logDone("images - invalid filter name check working")
|
||||
}
|
||||
|
||||
func TestImagesFilterLabel(t *testing.T) {
|
||||
func (s *DockerSuite) TestImagesFilterLabel(c *check.C) {
|
||||
imageName1 := "images_filter_test1"
|
||||
imageName2 := "images_filter_test2"
|
||||
imageName3 := "images_filter_test3"
|
||||
defer deleteAllContainers()
|
||||
defer deleteImages(imageName1)
|
||||
defer deleteImages(imageName2)
|
||||
defer deleteImages(imageName3)
|
||||
|
@ -91,51 +87,49 @@ func TestImagesFilterLabel(t *testing.T) {
|
|||
`FROM scratch
|
||||
LABEL match me`, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
image2ID, err := buildImage(imageName2,
|
||||
`FROM scratch
|
||||
LABEL match="me too"`, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
image3ID, err := buildImage(imageName3,
|
||||
`FROM scratch
|
||||
LABEL nomatch me`, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cmd := exec.Command(dockerBinary, "images", "--no-trunc", "-q", "-f", "label=match")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
out = strings.TrimSpace(out)
|
||||
|
||||
if (!strings.Contains(out, image1ID) && !strings.Contains(out, image2ID)) || strings.Contains(out, image3ID) {
|
||||
t.Fatalf("Expected ids %s,%s got %s", image1ID, image2ID, out)
|
||||
c.Fatalf("Expected ids %s,%s got %s", image1ID, image2ID, out)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "images", "--no-trunc", "-q", "-f", "label=match=me too")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
out = strings.TrimSpace(out)
|
||||
|
||||
if out != image2ID {
|
||||
t.Fatalf("Expected %s got %s", image2ID, out)
|
||||
c.Fatalf("Expected %s got %s", image2ID, out)
|
||||
}
|
||||
|
||||
logDone("images - filter label")
|
||||
}
|
||||
|
||||
func TestImagesFilterWhiteSpaceTrimmingAndLowerCasingWorking(t *testing.T) {
|
||||
func (s *DockerSuite) TestImagesFilterSpaceTrimCase(c *check.C) {
|
||||
imageName := "images_filter_test"
|
||||
defer deleteAllContainers()
|
||||
defer deleteImages(imageName)
|
||||
buildImage(imageName,
|
||||
`FROM scratch
|
||||
|
@ -156,7 +150,7 @@ func TestImagesFilterWhiteSpaceTrimmingAndLowerCasingWorking(t *testing.T) {
|
|||
cmd := exec.Command(dockerBinary, "images", "-q", "-f", filter)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
listing := strings.Split(out, "\n")
|
||||
sort.Strings(listing)
|
||||
|
@ -172,50 +166,47 @@ func TestImagesFilterWhiteSpaceTrimmingAndLowerCasingWorking(t *testing.T) {
|
|||
}
|
||||
fmt.Print("")
|
||||
}
|
||||
t.Fatalf("All output must be the same")
|
||||
c.Fatalf("All output must be the same")
|
||||
}
|
||||
}
|
||||
|
||||
logDone("images - white space trimming and lower casing")
|
||||
}
|
||||
|
||||
func TestImagesEnsureDanglingImageOnlyListedOnce(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestImagesEnsureDanglingImageOnlyListedOnce(c *check.C) {
|
||||
|
||||
// create container 1
|
||||
c := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
cmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error running busybox: %s, %v", out, err)
|
||||
c.Fatalf("error running busybox: %s, %v", out, err)
|
||||
}
|
||||
containerId1 := strings.TrimSpace(out)
|
||||
|
||||
// tag as foobox
|
||||
c = exec.Command(dockerBinary, "commit", containerId1, "foobox")
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "commit", containerId1, "foobox")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error tagging foobox: %s", err)
|
||||
c.Fatalf("error tagging foobox: %s", err)
|
||||
}
|
||||
imageId := stringid.TruncateID(strings.TrimSpace(out))
|
||||
defer deleteImages(imageId)
|
||||
|
||||
// overwrite the tag, making the previous image dangling
|
||||
c = exec.Command(dockerBinary, "tag", "-f", "busybox", "foobox")
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "tag", "-f", "busybox", "foobox")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("error tagging foobox: %s", err)
|
||||
c.Fatalf("error tagging foobox: %s", err)
|
||||
}
|
||||
defer deleteImages("foobox")
|
||||
|
||||
c = exec.Command(dockerBinary, "images", "-q", "-f", "dangling=true")
|
||||
out, _, err = runCommandWithOutput(c)
|
||||
cmd = exec.Command(dockerBinary, "images", "-q", "-f", "dangling=true")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("listing images failed with errors: %s, %v", out, err)
|
||||
c.Fatalf("listing images failed with errors: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if e, a := 1, strings.Count(out, imageId); e != a {
|
||||
t.Fatalf("expected 1 dangling image, got %d: %s", a, out)
|
||||
c.Fatalf("expected 1 dangling image, got %d: %s", a, out)
|
||||
}
|
||||
|
||||
logDone("images - dangling image only listed once")
|
||||
}
|
||||
|
|
|
@ -3,14 +3,15 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestImportDisplay(t *testing.T) {
|
||||
func (s *DockerSuite) TestImportDisplay(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal("failed to create a container", out, err)
|
||||
c.Fatal("failed to create a container", out, err)
|
||||
}
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
defer deleteContainer(cleanedContainerID)
|
||||
|
@ -20,11 +21,11 @@ func TestImportDisplay(t *testing.T) {
|
|||
exec.Command(dockerBinary, "import", "-"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Errorf("import failed with errors: %v, output: %q", err, out)
|
||||
c.Errorf("import failed with errors: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
if n := strings.Count(out, "\n"); n != 1 {
|
||||
t.Fatalf("display is messed up: %d '\\n' instead of 1:\n%s", n, out)
|
||||
c.Fatalf("display is messed up: %d '\\n' instead of 1:\n%s", n, out)
|
||||
}
|
||||
image := strings.TrimSpace(out)
|
||||
defer deleteImages(image)
|
||||
|
@ -32,12 +33,11 @@ func TestImportDisplay(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "run", "--rm", image, "true")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal("failed to create a container", out, err)
|
||||
c.Fatal("failed to create a container", out, err)
|
||||
}
|
||||
|
||||
if out != "" {
|
||||
t.Fatalf("command output should've been nothing, was %q", out)
|
||||
c.Fatalf("command output should've been nothing, was %q", out)
|
||||
}
|
||||
|
||||
logDone("import - display is fine, imported image runs")
|
||||
}
|
||||
|
|
|
@ -3,15 +3,16 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// ensure docker info succeeds
|
||||
func TestInfoEnsureSucceeds(t *testing.T) {
|
||||
func (s *DockerSuite) TestInfoEnsureSucceeds(c *check.C) {
|
||||
versionCmd := exec.Command(dockerBinary, "info")
|
||||
out, exitCode, err := runCommandWithOutput(versionCmd)
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Fatalf("failed to execute docker info: %s, %v", out, err)
|
||||
c.Fatalf("failed to execute docker info: %s, %v", out, err)
|
||||
}
|
||||
|
||||
// always shown fields
|
||||
|
@ -29,9 +30,8 @@ func TestInfoEnsureSucceeds(t *testing.T) {
|
|||
|
||||
for _, linePrefix := range stringsToCheck {
|
||||
if !strings.Contains(out, linePrefix) {
|
||||
t.Errorf("couldn't find string %v in output", linePrefix)
|
||||
c.Errorf("couldn't find string %v in output", linePrefix)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("info - verify that it works")
|
||||
}
|
||||
|
|
|
@ -3,21 +3,21 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestInspectImage(t *testing.T) {
|
||||
func (s *DockerSuite) TestInspectImage(c *check.C) {
|
||||
imageTest := "emptyfs"
|
||||
imageTestID := "511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158"
|
||||
imagesCmd := exec.Command(dockerBinary, "inspect", "--format='{{.Id}}'", imageTest)
|
||||
out, exitCode, err := runCommandWithOutput(imagesCmd)
|
||||
if exitCode != 0 || err != nil {
|
||||
t.Fatalf("failed to inspect image: %s, %v", out, err)
|
||||
c.Fatalf("failed to inspect image: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if id := strings.TrimSuffix(out, "\n"); id != imageTestID {
|
||||
t.Fatalf("Expected id: %s for image: %s but received id: %s", imageTestID, imageTest, id)
|
||||
c.Fatalf("Expected id: %s for image: %s but received id: %s", imageTestID, imageTest, id)
|
||||
}
|
||||
|
||||
logDone("inspect - inspect an image")
|
||||
}
|
||||
|
|
|
@ -3,73 +3,72 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestKillContainer(t *testing.T) {
|
||||
func (s *DockerSuite) TestKillContainer(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
|
||||
t.Fatalf("out should've been a container id: %s, %v", out, err)
|
||||
c.Fatalf("out should've been a container id: %s, %v", out, err)
|
||||
}
|
||||
|
||||
killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(killCmd); err != nil {
|
||||
t.Fatalf("failed to kill container: %s, %v", out, err)
|
||||
c.Fatalf("failed to kill container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
listRunningContainersCmd := exec.Command(dockerBinary, "ps", "-q")
|
||||
out, _, err = runCommandWithOutput(listRunningContainersCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to list running containers: %s, %v", out, err)
|
||||
c.Fatalf("failed to list running containers: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if strings.Contains(out, cleanedContainerID) {
|
||||
t.Fatal("killed container is still running")
|
||||
c.Fatal("killed container is still running")
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
|
||||
logDone("kill - kill container running top")
|
||||
}
|
||||
|
||||
func TestKillDifferentUserContainer(t *testing.T) {
|
||||
func (s *DockerSuite) TestKillDifferentUserContainer(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-u", "daemon", "-d", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
|
||||
t.Fatalf("out should've been a container id: %s, %v", out, err)
|
||||
c.Fatalf("out should've been a container id: %s, %v", out, err)
|
||||
}
|
||||
|
||||
killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(killCmd); err != nil {
|
||||
t.Fatalf("failed to kill container: %s, %v", out, err)
|
||||
c.Fatalf("failed to kill container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
listRunningContainersCmd := exec.Command(dockerBinary, "ps", "-q")
|
||||
out, _, err = runCommandWithOutput(listRunningContainersCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to list running containers: %s, %v", out, err)
|
||||
c.Fatalf("failed to list running containers: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if strings.Contains(out, cleanedContainerID) {
|
||||
t.Fatal("killed container is still running")
|
||||
c.Fatal("killed container is still running")
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
|
||||
logDone("kill - kill container running top from a different user")
|
||||
}
|
||||
|
|
|
@ -8,89 +8,81 @@ import (
|
|||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/iptables"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestLinksEtcHostsRegularFile(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLinksEtcHostsRegularFile(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "--net=host", "busybox", "ls", "-la", "/etc/hosts")
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(out, "-") {
|
||||
t.Errorf("/etc/hosts should be a regular file")
|
||||
c.Errorf("/etc/hosts should be a regular file")
|
||||
}
|
||||
logDone("link - /etc/hosts is a regular file")
|
||||
}
|
||||
|
||||
func TestLinksEtcHostsContentMatch(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon)
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLinksEtcHostsContentMatch(c *check.C) {
|
||||
testRequires(c, SameHostDaemon)
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "--net=host", "busybox", "cat", "/etc/hosts")
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
hosts, err := ioutil.ReadFile("/etc/hosts")
|
||||
if os.IsNotExist(err) {
|
||||
t.Skip("/etc/hosts does not exist, skip this test")
|
||||
c.Skip("/etc/hosts does not exist, skip this test")
|
||||
}
|
||||
|
||||
if out != string(hosts) {
|
||||
t.Errorf("container")
|
||||
c.Errorf("container")
|
||||
}
|
||||
|
||||
logDone("link - /etc/hosts matches hosts copy")
|
||||
}
|
||||
|
||||
func TestLinksPingUnlinkedContainers(t *testing.T) {
|
||||
func (s *DockerSuite) TestLinksPingUnlinkedContainers(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "--rm", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1")
|
||||
exitCode, err := runCommand(runCmd)
|
||||
|
||||
if exitCode == 0 {
|
||||
t.Fatal("run ping did not fail")
|
||||
c.Fatal("run ping did not fail")
|
||||
} else if exitCode != 1 {
|
||||
t.Fatalf("run ping failed with errors: %v", err)
|
||||
c.Fatalf("run ping failed with errors: %v", err)
|
||||
}
|
||||
|
||||
logDone("links - ping unlinked container")
|
||||
}
|
||||
|
||||
// Test for appropriate error when calling --link with an invalid target container
|
||||
func TestLinksInvalidContainerTarget(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLinksInvalidContainerTarget(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "--link", "bogus:alias", "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("an invalid container target should produce an error")
|
||||
c.Fatal("an invalid container target should produce an error")
|
||||
}
|
||||
if !strings.Contains(out, "Could not get container") {
|
||||
t.Fatalf("error output expected 'Could not get container', but got %q instead; err: %v", out, err)
|
||||
c.Fatalf("error output expected 'Could not get container', but got %q instead; err: %v", out, err)
|
||||
}
|
||||
|
||||
logDone("links - linking to non-existent container should not work")
|
||||
}
|
||||
|
||||
func TestLinksPingLinkedContainers(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLinksPingLinkedContainers(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "container1", "--hostname", "fred", "busybox", "top")
|
||||
if _, err := runCommand(runCmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
runCmd = exec.Command(dockerBinary, "run", "-d", "--name", "container2", "--hostname", "wilma", "busybox", "top")
|
||||
if _, err := runCommand(runCmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
runArgs := []string{"run", "--rm", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "sh", "-c"}
|
||||
|
@ -98,74 +90,68 @@ func TestLinksPingLinkedContainers(t *testing.T) {
|
|||
|
||||
// test ping by alias, ping by name, and ping by hostname
|
||||
// 1. Ping by alias
|
||||
dockerCmd(t, append(runArgs, fmt.Sprintf(pingCmd, "alias1", "alias2"))...)
|
||||
dockerCmd(c, append(runArgs, fmt.Sprintf(pingCmd, "alias1", "alias2"))...)
|
||||
// 2. Ping by container name
|
||||
dockerCmd(t, append(runArgs, fmt.Sprintf(pingCmd, "container1", "container2"))...)
|
||||
dockerCmd(c, append(runArgs, fmt.Sprintf(pingCmd, "container1", "container2"))...)
|
||||
// 3. Ping by hostname
|
||||
dockerCmd(t, append(runArgs, fmt.Sprintf(pingCmd, "fred", "wilma"))...)
|
||||
dockerCmd(c, append(runArgs, fmt.Sprintf(pingCmd, "fred", "wilma"))...)
|
||||
|
||||
logDone("links - ping linked container")
|
||||
}
|
||||
|
||||
func TestLinksPingLinkedContainersAfterRename(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLinksPingLinkedContainersAfterRename(c *check.C) {
|
||||
|
||||
out, _ := dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "top")
|
||||
out, _ := dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top")
|
||||
idA := strings.TrimSpace(out)
|
||||
out, _ = dockerCmd(t, "run", "-d", "--name", "container2", "busybox", "top")
|
||||
out, _ = dockerCmd(c, "run", "-d", "--name", "container2", "busybox", "top")
|
||||
idB := strings.TrimSpace(out)
|
||||
dockerCmd(t, "rename", "container1", "container_new")
|
||||
dockerCmd(t, "run", "--rm", "--link", "container_new:alias1", "--link", "container2:alias2", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1")
|
||||
dockerCmd(t, "kill", idA)
|
||||
dockerCmd(t, "kill", idB)
|
||||
dockerCmd(c, "rename", "container1", "container_new")
|
||||
dockerCmd(c, "run", "--rm", "--link", "container_new:alias1", "--link", "container2:alias2", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1")
|
||||
dockerCmd(c, "kill", idA)
|
||||
dockerCmd(c, "kill", idB)
|
||||
|
||||
logDone("links - ping linked container after rename")
|
||||
}
|
||||
|
||||
func TestLinksIpTablesRulesWhenLinkAndUnlink(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon)
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLinksIpTablesRulesWhenLinkAndUnlink(c *check.C) {
|
||||
testRequires(c, SameHostDaemon)
|
||||
|
||||
dockerCmd(t, "run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "top")
|
||||
dockerCmd(t, "run", "-d", "--name", "parent", "--link", "child:http", "busybox", "top")
|
||||
dockerCmd(c, "run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "top")
|
||||
dockerCmd(c, "run", "-d", "--name", "parent", "--link", "child:http", "busybox", "top")
|
||||
|
||||
childIP := findContainerIP(t, "child")
|
||||
parentIP := findContainerIP(t, "parent")
|
||||
childIP := findContainerIP(c, "child")
|
||||
parentIP := findContainerIP(c, "parent")
|
||||
|
||||
sourceRule := []string{"-i", "docker0", "-o", "docker0", "-p", "tcp", "-s", childIP, "--sport", "80", "-d", parentIP, "-j", "ACCEPT"}
|
||||
destinationRule := []string{"-i", "docker0", "-o", "docker0", "-p", "tcp", "-s", parentIP, "--dport", "80", "-d", childIP, "-j", "ACCEPT"}
|
||||
if !iptables.Exists("filter", "DOCKER", sourceRule...) || !iptables.Exists("filter", "DOCKER", destinationRule...) {
|
||||
t.Fatal("Iptables rules not found")
|
||||
c.Fatal("Iptables rules not found")
|
||||
}
|
||||
|
||||
dockerCmd(t, "rm", "--link", "parent/http")
|
||||
dockerCmd(c, "rm", "--link", "parent/http")
|
||||
if iptables.Exists("filter", "DOCKER", sourceRule...) || iptables.Exists("filter", "DOCKER", destinationRule...) {
|
||||
t.Fatal("Iptables rules should be removed when unlink")
|
||||
c.Fatal("Iptables rules should be removed when unlink")
|
||||
}
|
||||
|
||||
dockerCmd(t, "kill", "child")
|
||||
dockerCmd(t, "kill", "parent")
|
||||
dockerCmd(c, "kill", "child")
|
||||
dockerCmd(c, "kill", "parent")
|
||||
|
||||
logDone("link - verify iptables when link and unlink")
|
||||
}
|
||||
|
||||
func TestLinksInspectLinksStarted(t *testing.T) {
|
||||
func (s *DockerSuite) TestLinksInspectLinksStarted(c *check.C) {
|
||||
var (
|
||||
expected = map[string]struct{}{"/container1:/testinspectlink/alias1": {}, "/container2:/testinspectlink/alias2": {}}
|
||||
result []string
|
||||
)
|
||||
defer deleteAllContainers()
|
||||
dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "top")
|
||||
dockerCmd(t, "run", "-d", "--name", "container2", "busybox", "top")
|
||||
dockerCmd(t, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "top")
|
||||
dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top")
|
||||
dockerCmd(c, "run", "-d", "--name", "container2", "busybox", "top")
|
||||
dockerCmd(c, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "top")
|
||||
links, err := inspectFieldJSON("testinspectlink", "HostConfig.Links")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
err = unmarshalJSON([]byte(links), &result)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
output := convertSliceOfStringsToMap(result)
|
||||
|
@ -173,28 +159,26 @@ func TestLinksInspectLinksStarted(t *testing.T) {
|
|||
equal := reflect.DeepEqual(output, expected)
|
||||
|
||||
if !equal {
|
||||
t.Fatalf("Links %s, expected %s", result, expected)
|
||||
c.Fatalf("Links %s, expected %s", result, expected)
|
||||
}
|
||||
logDone("link - links in started container inspect")
|
||||
}
|
||||
|
||||
func TestLinksInspectLinksStopped(t *testing.T) {
|
||||
func (s *DockerSuite) TestLinksInspectLinksStopped(c *check.C) {
|
||||
var (
|
||||
expected = map[string]struct{}{"/container1:/testinspectlink/alias1": {}, "/container2:/testinspectlink/alias2": {}}
|
||||
result []string
|
||||
)
|
||||
defer deleteAllContainers()
|
||||
dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "top")
|
||||
dockerCmd(t, "run", "-d", "--name", "container2", "busybox", "top")
|
||||
dockerCmd(t, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "true")
|
||||
dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top")
|
||||
dockerCmd(c, "run", "-d", "--name", "container2", "busybox", "top")
|
||||
dockerCmd(c, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "true")
|
||||
links, err := inspectFieldJSON("testinspectlink", "HostConfig.Links")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
err = unmarshalJSON([]byte(links), &result)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
output := convertSliceOfStringsToMap(result)
|
||||
|
@ -202,47 +186,42 @@ func TestLinksInspectLinksStopped(t *testing.T) {
|
|||
equal := reflect.DeepEqual(output, expected)
|
||||
|
||||
if !equal {
|
||||
t.Fatalf("Links %s, but expected %s", result, expected)
|
||||
c.Fatalf("Links %s, but expected %s", result, expected)
|
||||
}
|
||||
|
||||
logDone("link - links in stopped container inspect")
|
||||
}
|
||||
|
||||
func TestLinksNotStartedParentNotFail(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLinksNotStartedParentNotFail(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "create", "--name=first", "busybox", "top")
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
runCmd = exec.Command(dockerBinary, "create", "--name=second", "--link=first:first", "busybox", "top")
|
||||
out, _, _, err = runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
runCmd = exec.Command(dockerBinary, "start", "first")
|
||||
out, _, _, err = runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
logDone("link - container start successfully updating stopped parent links")
|
||||
}
|
||||
|
||||
func TestLinksHostsFilesInject(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon, ExecSupport)
|
||||
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLinksHostsFilesInject(c *check.C) {
|
||||
testRequires(c, SameHostDaemon, ExecSupport)
|
||||
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-itd", "--name", "one", "busybox", "top"))
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
idOne := strings.TrimSpace(out)
|
||||
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "-itd", "--name", "two", "--link", "one:onetwo", "busybox", "top"))
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
idTwo := strings.TrimSpace(out)
|
||||
|
@ -251,89 +230,83 @@ func TestLinksHostsFilesInject(t *testing.T) {
|
|||
|
||||
contentOne, err := readContainerFileWithExec(idOne, "/etc/hosts")
|
||||
if err != nil {
|
||||
t.Fatal(err, string(contentOne))
|
||||
c.Fatal(err, string(contentOne))
|
||||
}
|
||||
|
||||
contentTwo, err := readContainerFileWithExec(idTwo, "/etc/hosts")
|
||||
if err != nil {
|
||||
t.Fatal(err, string(contentTwo))
|
||||
c.Fatal(err, string(contentTwo))
|
||||
}
|
||||
|
||||
if !strings.Contains(string(contentTwo), "onetwo") {
|
||||
t.Fatal("Host is not present in updated hosts file", string(contentTwo))
|
||||
c.Fatal("Host is not present in updated hosts file", string(contentTwo))
|
||||
}
|
||||
|
||||
logDone("link - ensure containers hosts files are updated with the link alias.")
|
||||
}
|
||||
|
||||
func TestLinksNetworkHostContainer(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLinksNetworkHostContainer(c *check.C) {
|
||||
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--net", "host", "--name", "host_container", "busybox", "top"))
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "should_fail", "--link", "host_container:tester", "busybox", "true"))
|
||||
if err == nil || !strings.Contains(out, "--net=host can't be used with links. This would result in undefined behavior.") {
|
||||
t.Fatalf("Running container linking to a container with --net host should have failed: %s", out)
|
||||
c.Fatalf("Running container linking to a container with --net host should have failed: %s", out)
|
||||
}
|
||||
|
||||
logDone("link - error thrown when linking to container with --net host")
|
||||
}
|
||||
|
||||
func TestLinksUpdateOnRestart(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon, ExecSupport)
|
||||
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestLinksUpdateOnRestart(c *check.C) {
|
||||
testRequires(c, SameHostDaemon, ExecSupport)
|
||||
|
||||
if out, err := exec.Command(dockerBinary, "run", "-d", "--name", "one", "busybox", "top").CombinedOutput(); err != nil {
|
||||
t.Fatal(err, string(out))
|
||||
c.Fatal(err, string(out))
|
||||
}
|
||||
out, err := exec.Command(dockerBinary, "run", "-d", "--name", "two", "--link", "one:onetwo", "--link", "one:one", "busybox", "top").CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatal(err, string(out))
|
||||
c.Fatal(err, string(out))
|
||||
}
|
||||
id := strings.TrimSpace(string(out))
|
||||
|
||||
realIP, err := inspectField("one", "NetworkSettings.IPAddress")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
content, err := readContainerFileWithExec(id, "/etc/hosts")
|
||||
if err != nil {
|
||||
t.Fatal(err, string(content))
|
||||
c.Fatal(err, string(content))
|
||||
}
|
||||
getIP := func(hosts []byte, hostname string) string {
|
||||
re := regexp.MustCompile(fmt.Sprintf(`(\S*)\t%s`, regexp.QuoteMeta(hostname)))
|
||||
matches := re.FindSubmatch(hosts)
|
||||
if matches == nil {
|
||||
t.Fatalf("Hostname %s have no matches in hosts", hostname)
|
||||
c.Fatalf("Hostname %s have no matches in hosts", hostname)
|
||||
}
|
||||
return string(matches[1])
|
||||
}
|
||||
if ip := getIP(content, "one"); ip != realIP {
|
||||
t.Fatalf("For 'one' alias expected IP: %s, got: %s", realIP, ip)
|
||||
c.Fatalf("For 'one' alias expected IP: %s, got: %s", realIP, ip)
|
||||
}
|
||||
if ip := getIP(content, "onetwo"); ip != realIP {
|
||||
t.Fatalf("For 'onetwo' alias expected IP: %s, got: %s", realIP, ip)
|
||||
c.Fatalf("For 'onetwo' alias expected IP: %s, got: %s", realIP, ip)
|
||||
}
|
||||
if out, err := exec.Command(dockerBinary, "restart", "one").CombinedOutput(); err != nil {
|
||||
t.Fatal(err, string(out))
|
||||
c.Fatal(err, string(out))
|
||||
}
|
||||
realIP, err = inspectField("one", "NetworkSettings.IPAddress")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
content, err = readContainerFileWithExec(id, "/etc/hosts")
|
||||
if err != nil {
|
||||
t.Fatal(err, string(content))
|
||||
c.Fatal(err, string(content))
|
||||
}
|
||||
if ip := getIP(content, "one"); ip != realIP {
|
||||
t.Fatalf("For 'one' alias expected IP: %s, got: %s", realIP, ip)
|
||||
c.Fatalf("For 'one' alias expected IP: %s, got: %s", realIP, ip)
|
||||
}
|
||||
if ip := getIP(content, "onetwo"); ip != realIP {
|
||||
t.Fatalf("For 'onetwo' alias expected IP: %s, got: %s", realIP, ip)
|
||||
c.Fatalf("For 'onetwo' alias expected IP: %s, got: %s", realIP, ip)
|
||||
}
|
||||
logDone("link - ensure containers hosts files are updated on restart")
|
||||
}
|
||||
|
|
|
@ -3,10 +3,11 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestLoginWithoutTTY(t *testing.T) {
|
||||
func (s *DockerSuite) TestLoginWithoutTTY(c *check.C) {
|
||||
cmd := exec.Command(dockerBinary, "login")
|
||||
|
||||
// Send to stdin so the process does not get the TTY
|
||||
|
@ -14,8 +15,7 @@ func TestLoginWithoutTTY(t *testing.T) {
|
|||
|
||||
// run the command and block until it's done
|
||||
if err := cmd.Run(); err == nil {
|
||||
t.Fatal("Expected non nil err when loginning in & TTY not available")
|
||||
c.Fatal("Expected non nil err when loginning in & TTY not available")
|
||||
}
|
||||
|
||||
logDone("login - login without TTY")
|
||||
}
|
||||
|
|
|
@ -5,19 +5,19 @@ import (
|
|||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/timeutils"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// This used to work, it test a log of PageSize-1 (gh#4851)
|
||||
func TestLogsContainerSmallerThanPage(t *testing.T) {
|
||||
func (s *DockerSuite) TestLogsContainerSmallerThanPage(c *check.C) {
|
||||
testLen := 32767
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo -n =; done; echo", testLen))
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
c.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -26,25 +26,24 @@ func TestLogsContainerSmallerThanPage(t *testing.T) {
|
|||
logsCmd := exec.Command(dockerBinary, "logs", cleanedContainerID)
|
||||
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to log container: %s, %v", out, err)
|
||||
c.Fatalf("failed to log container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if len(out) != testLen+1 {
|
||||
t.Fatalf("Expected log length of %d, received %d\n", testLen+1, len(out))
|
||||
c.Fatalf("Expected log length of %d, received %d\n", testLen+1, len(out))
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
|
||||
logDone("logs - logs container running echo smaller than page size")
|
||||
}
|
||||
|
||||
// Regression test: When going over the PageSize, it used to panic (gh#4851)
|
||||
func TestLogsContainerBiggerThanPage(t *testing.T) {
|
||||
func (s *DockerSuite) TestLogsContainerBiggerThanPage(c *check.C) {
|
||||
testLen := 32768
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo -n =; done; echo", testLen))
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
c.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -53,25 +52,24 @@ func TestLogsContainerBiggerThanPage(t *testing.T) {
|
|||
logsCmd := exec.Command(dockerBinary, "logs", cleanedContainerID)
|
||||
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to log container: %s, %v", out, err)
|
||||
c.Fatalf("failed to log container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if len(out) != testLen+1 {
|
||||
t.Fatalf("Expected log length of %d, received %d\n", testLen+1, len(out))
|
||||
c.Fatalf("Expected log length of %d, received %d\n", testLen+1, len(out))
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
|
||||
logDone("logs - logs container running echo bigger than page size")
|
||||
}
|
||||
|
||||
// Regression test: When going much over the PageSize, it used to block (gh#4851)
|
||||
func TestLogsContainerMuchBiggerThanPage(t *testing.T) {
|
||||
func (s *DockerSuite) TestLogsContainerMuchBiggerThanPage(c *check.C) {
|
||||
testLen := 33000
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo -n =; done; echo", testLen))
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
c.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -80,25 +78,24 @@ func TestLogsContainerMuchBiggerThanPage(t *testing.T) {
|
|||
logsCmd := exec.Command(dockerBinary, "logs", cleanedContainerID)
|
||||
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to log container: %s, %v", out, err)
|
||||
c.Fatalf("failed to log container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if len(out) != testLen+1 {
|
||||
t.Fatalf("Expected log length of %d, received %d\n", testLen+1, len(out))
|
||||
c.Fatalf("Expected log length of %d, received %d\n", testLen+1, len(out))
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
|
||||
logDone("logs - logs container running echo much bigger than page size")
|
||||
}
|
||||
|
||||
func TestLogsTimestamps(t *testing.T) {
|
||||
func (s *DockerSuite) TestLogsTimestamps(c *check.C) {
|
||||
testLen := 100
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo =; done;", testLen))
|
||||
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
c.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -107,13 +104,13 @@ func TestLogsTimestamps(t *testing.T) {
|
|||
logsCmd := exec.Command(dockerBinary, "logs", "-t", cleanedContainerID)
|
||||
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to log container: %s, %v", out, err)
|
||||
c.Fatalf("failed to log container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
lines := strings.Split(out, "\n")
|
||||
|
||||
if len(lines) != testLen+1 {
|
||||
t.Fatalf("Expected log %d lines, received %d\n", testLen+1, len(lines))
|
||||
c.Fatalf("Expected log %d lines, received %d\n", testLen+1, len(lines))
|
||||
}
|
||||
|
||||
ts := regexp.MustCompile(`^.* `)
|
||||
|
@ -122,26 +119,25 @@ func TestLogsTimestamps(t *testing.T) {
|
|||
if l != "" {
|
||||
_, err := time.Parse(timeutils.RFC3339NanoFixed+" ", ts.FindString(l))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse timestamp from %v: %v", l, err)
|
||||
c.Fatalf("Failed to parse timestamp from %v: %v", l, err)
|
||||
}
|
||||
if l[29] != 'Z' { // ensure we have padded 0's
|
||||
t.Fatalf("Timestamp isn't padded properly: %s", l)
|
||||
c.Fatalf("Timestamp isn't padded properly: %s", l)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
|
||||
logDone("logs - logs with timestamps")
|
||||
}
|
||||
|
||||
func TestLogsSeparateStderr(t *testing.T) {
|
||||
func (s *DockerSuite) TestLogsSeparateStderr(c *check.C) {
|
||||
msg := "stderr_log"
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("echo %s 1>&2", msg))
|
||||
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
c.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -150,30 +146,29 @@ func TestLogsSeparateStderr(t *testing.T) {
|
|||
logsCmd := exec.Command(dockerBinary, "logs", cleanedContainerID)
|
||||
stdout, stderr, _, err := runCommandWithStdoutStderr(logsCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to log container: %s, %v", out, err)
|
||||
c.Fatalf("failed to log container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if stdout != "" {
|
||||
t.Fatalf("Expected empty stdout stream, got %v", stdout)
|
||||
c.Fatalf("Expected empty stdout stream, got %v", stdout)
|
||||
}
|
||||
|
||||
stderr = strings.TrimSpace(stderr)
|
||||
if stderr != msg {
|
||||
t.Fatalf("Expected %v in stderr stream, got %v", msg, stderr)
|
||||
c.Fatalf("Expected %v in stderr stream, got %v", msg, stderr)
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
|
||||
logDone("logs - separate stderr (without pseudo-tty)")
|
||||
}
|
||||
|
||||
func TestLogsStderrInStdout(t *testing.T) {
|
||||
func (s *DockerSuite) TestLogsStderrInStdout(c *check.C) {
|
||||
msg := "stderr_log"
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "-t", "busybox", "sh", "-c", fmt.Sprintf("echo %s 1>&2", msg))
|
||||
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
c.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -182,30 +177,29 @@ func TestLogsStderrInStdout(t *testing.T) {
|
|||
logsCmd := exec.Command(dockerBinary, "logs", cleanedContainerID)
|
||||
stdout, stderr, _, err := runCommandWithStdoutStderr(logsCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to log container: %s, %v", out, err)
|
||||
c.Fatalf("failed to log container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if stderr != "" {
|
||||
t.Fatalf("Expected empty stderr stream, got %v", stdout)
|
||||
c.Fatalf("Expected empty stderr stream, got %v", stdout)
|
||||
}
|
||||
|
||||
stdout = strings.TrimSpace(stdout)
|
||||
if stdout != msg {
|
||||
t.Fatalf("Expected %v in stdout stream, got %v", msg, stdout)
|
||||
c.Fatalf("Expected %v in stdout stream, got %v", msg, stdout)
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
|
||||
logDone("logs - stderr in stdout (with pseudo-tty)")
|
||||
}
|
||||
|
||||
func TestLogsTail(t *testing.T) {
|
||||
func (s *DockerSuite) TestLogsTail(c *check.C) {
|
||||
testLen := 100
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo =; done;", testLen))
|
||||
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
c.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -214,49 +208,48 @@ func TestLogsTail(t *testing.T) {
|
|||
logsCmd := exec.Command(dockerBinary, "logs", "--tail", "5", cleanedContainerID)
|
||||
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to log container: %s, %v", out, err)
|
||||
c.Fatalf("failed to log container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
lines := strings.Split(out, "\n")
|
||||
|
||||
if len(lines) != 6 {
|
||||
t.Fatalf("Expected log %d lines, received %d\n", 6, len(lines))
|
||||
c.Fatalf("Expected log %d lines, received %d\n", 6, len(lines))
|
||||
}
|
||||
|
||||
logsCmd = exec.Command(dockerBinary, "logs", "--tail", "all", cleanedContainerID)
|
||||
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to log container: %s, %v", out, err)
|
||||
c.Fatalf("failed to log container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
lines = strings.Split(out, "\n")
|
||||
|
||||
if len(lines) != testLen+1 {
|
||||
t.Fatalf("Expected log %d lines, received %d\n", testLen+1, len(lines))
|
||||
c.Fatalf("Expected log %d lines, received %d\n", testLen+1, len(lines))
|
||||
}
|
||||
|
||||
logsCmd = exec.Command(dockerBinary, "logs", "--tail", "random", cleanedContainerID)
|
||||
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to log container: %s, %v", out, err)
|
||||
c.Fatalf("failed to log container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
lines = strings.Split(out, "\n")
|
||||
|
||||
if len(lines) != testLen+1 {
|
||||
t.Fatalf("Expected log %d lines, received %d\n", testLen+1, len(lines))
|
||||
c.Fatalf("Expected log %d lines, received %d\n", testLen+1, len(lines))
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
logDone("logs - logs tail")
|
||||
}
|
||||
|
||||
func TestLogsFollowStopped(t *testing.T) {
|
||||
func (s *DockerSuite) TestLogsFollowStopped(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "echo", "hello")
|
||||
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
c.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -264,34 +257,33 @@ func TestLogsFollowStopped(t *testing.T) {
|
|||
|
||||
logsCmd := exec.Command(dockerBinary, "logs", "-f", cleanedContainerID)
|
||||
if err := logsCmd.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
c := make(chan struct{})
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
if err := logsCmd.Wait(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
close(c)
|
||||
close(ch)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-c:
|
||||
case <-ch:
|
||||
case <-time.After(1 * time.Second):
|
||||
t.Fatal("Following logs is hanged")
|
||||
c.Fatal("Following logs is hanged")
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
logDone("logs - logs follow stopped container")
|
||||
}
|
||||
|
||||
// Regression test for #8832
|
||||
func TestLogsFollowSlowStdoutConsumer(t *testing.T) {
|
||||
func (s *DockerSuite) TestLogsFollowSlowStdoutConsumer(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "/bin/sh", "-c", `usleep 200000;yes X | head -c 200000`)
|
||||
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
c.Fatalf("run failed with errors: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -308,30 +300,29 @@ func TestLogsFollowSlowStdoutConsumer(t *testing.T) {
|
|||
|
||||
stdout, err := logCmd.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if err := logCmd.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// First read slowly
|
||||
bytes1, err := consumeWithSpeed(stdout, 10, 50*time.Millisecond, stopSlowRead)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// After the container has finished we can continue reading fast
|
||||
bytes2, err := consumeWithSpeed(stdout, 32*1024, 0, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
actual := bytes1 + bytes2
|
||||
expected := 200000
|
||||
if actual != expected {
|
||||
t.Fatalf("Invalid bytes read: %d, expected %d", actual, expected)
|
||||
c.Fatalf("Invalid bytes read: %d, expected %d", actual, expected)
|
||||
}
|
||||
|
||||
logDone("logs - follow slow consumer")
|
||||
}
|
||||
|
|
|
@ -5,32 +5,32 @@ import (
|
|||
"net"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestNetworkNat(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon, NativeExecDriver)
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestNetworkNat(c *check.C) {
|
||||
testRequires(c, SameHostDaemon, NativeExecDriver)
|
||||
|
||||
iface, err := net.InterfaceByName("eth0")
|
||||
if err != nil {
|
||||
t.Skipf("Test not running with `make test`. Interface eth0 not found: %s", err)
|
||||
c.Skip(fmt.Sprintf("Test not running with `make test`. Interface eth0 not found: %v", err))
|
||||
}
|
||||
|
||||
ifaceAddrs, err := iface.Addrs()
|
||||
if err != nil || len(ifaceAddrs) == 0 {
|
||||
t.Fatalf("Error retrieving addresses for eth0: %v (%d addresses)", err, len(ifaceAddrs))
|
||||
c.Fatalf("Error retrieving addresses for eth0: %v (%d addresses)", err, len(ifaceAddrs))
|
||||
}
|
||||
|
||||
ifaceIP, _, err := net.ParseCIDR(ifaceAddrs[0].String())
|
||||
if err != nil {
|
||||
t.Fatalf("Error retrieving the up for eth0: %s", err)
|
||||
c.Fatalf("Error retrieving the up for eth0: %s", err)
|
||||
}
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-dt", "-p", "8080:8080", "busybox", "nc", "-lp", "8080")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -38,25 +38,24 @@ func TestNetworkNat(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "run", "busybox", "sh", "-c", fmt.Sprintf("echo hello world | nc -w 30 %s 8080", ifaceIP))
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "logs", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to retrieve logs for container: %s, %v", out, err)
|
||||
c.Fatalf("failed to retrieve logs for container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
out = strings.Trim(out, "\r\n")
|
||||
|
||||
if expected := "hello world"; out != expected {
|
||||
t.Fatalf("Unexpected output. Expected: %q, received: %q for iface %s", expected, out, ifaceIP)
|
||||
c.Fatalf("Unexpected output. Expected: %q, received: %q for iface %s", expected, out, ifaceIP)
|
||||
}
|
||||
|
||||
killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(killCmd); err != nil {
|
||||
t.Fatalf("failed to kill container: %s, %v", out, err)
|
||||
c.Fatalf("failed to kill container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
logDone("network - make sure nat works through the host")
|
||||
}
|
||||
|
|
|
@ -4,78 +4,76 @@ import (
|
|||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestPause(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestPause(c *check.C) {
|
||||
defer unpauseAllContainers()
|
||||
|
||||
name := "testeventpause"
|
||||
out, _ := dockerCmd(t, "images", "-q")
|
||||
out, _ := dockerCmd(c, "images", "-q")
|
||||
image := strings.Split(out, "\n")[0]
|
||||
dockerCmd(t, "run", "-d", "--name", name, image, "top")
|
||||
dockerCmd(c, "run", "-d", "--name", name, image, "top")
|
||||
|
||||
dockerCmd(t, "pause", name)
|
||||
dockerCmd(c, "pause", name)
|
||||
pausedContainers, err := getSliceOfPausedContainers()
|
||||
if err != nil {
|
||||
t.Fatalf("error thrown while checking if containers were paused: %v", err)
|
||||
c.Fatalf("error thrown while checking if containers were paused: %v", err)
|
||||
}
|
||||
if len(pausedContainers) != 1 {
|
||||
t.Fatalf("there should be one paused container and not %d", len(pausedContainers))
|
||||
c.Fatalf("there should be one paused container and not %d", len(pausedContainers))
|
||||
}
|
||||
|
||||
dockerCmd(t, "unpause", name)
|
||||
dockerCmd(c, "unpause", name)
|
||||
|
||||
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
|
||||
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
out, _, _ = runCommandWithOutput(eventsCmd)
|
||||
events := strings.Split(out, "\n")
|
||||
if len(events) <= 1 {
|
||||
t.Fatalf("Missing expected event")
|
||||
c.Fatalf("Missing expected event")
|
||||
}
|
||||
|
||||
pauseEvent := strings.Fields(events[len(events)-3])
|
||||
unpauseEvent := strings.Fields(events[len(events)-2])
|
||||
|
||||
if pauseEvent[len(pauseEvent)-1] != "pause" {
|
||||
t.Fatalf("event should be pause, not %#v", pauseEvent)
|
||||
c.Fatalf("event should be pause, not %#v", pauseEvent)
|
||||
}
|
||||
if unpauseEvent[len(unpauseEvent)-1] != "unpause" {
|
||||
t.Fatalf("event should be unpause, not %#v", unpauseEvent)
|
||||
c.Fatalf("event should be unpause, not %#v", unpauseEvent)
|
||||
}
|
||||
|
||||
logDone("pause - pause/unpause is logged")
|
||||
}
|
||||
|
||||
func TestPauseMultipleContainers(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestPauseMultipleContainers(c *check.C) {
|
||||
defer unpauseAllContainers()
|
||||
|
||||
containers := []string{
|
||||
"testpausewithmorecontainers1",
|
||||
"testpausewithmorecontainers2",
|
||||
}
|
||||
out, _ := dockerCmd(t, "images", "-q")
|
||||
out, _ := dockerCmd(c, "images", "-q")
|
||||
image := strings.Split(out, "\n")[0]
|
||||
for _, name := range containers {
|
||||
dockerCmd(t, "run", "-d", "--name", name, image, "top")
|
||||
dockerCmd(c, "run", "-d", "--name", name, image, "top")
|
||||
}
|
||||
dockerCmd(t, append([]string{"pause"}, containers...)...)
|
||||
dockerCmd(c, append([]string{"pause"}, containers...)...)
|
||||
pausedContainers, err := getSliceOfPausedContainers()
|
||||
if err != nil {
|
||||
t.Fatalf("error thrown while checking if containers were paused: %v", err)
|
||||
c.Fatalf("error thrown while checking if containers were paused: %v", err)
|
||||
}
|
||||
if len(pausedContainers) != len(containers) {
|
||||
t.Fatalf("there should be %d paused container and not %d", len(containers), len(pausedContainers))
|
||||
c.Fatalf("there should be %d paused container and not %d", len(containers), len(pausedContainers))
|
||||
}
|
||||
|
||||
dockerCmd(t, append([]string{"unpause"}, containers...)...)
|
||||
dockerCmd(c, append([]string{"unpause"}, containers...)...)
|
||||
|
||||
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
|
||||
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
out, _, _ = runCommandWithOutput(eventsCmd)
|
||||
events := strings.Split(out, "\n")
|
||||
if len(events) <= len(containers)*3-2 {
|
||||
t.Fatalf("Missing expected event")
|
||||
c.Fatalf("Missing expected event")
|
||||
}
|
||||
|
||||
pauseEvents := make([][]string, len(containers))
|
||||
|
@ -87,14 +85,13 @@ func TestPauseMultipleContainers(t *testing.T) {
|
|||
|
||||
for _, pauseEvent := range pauseEvents {
|
||||
if pauseEvent[len(pauseEvent)-1] != "pause" {
|
||||
t.Fatalf("event should be pause, not %#v", pauseEvent)
|
||||
c.Fatalf("event should be pause, not %#v", pauseEvent)
|
||||
}
|
||||
}
|
||||
for _, unpauseEvent := range unpauseEvents {
|
||||
if unpauseEvent[len(unpauseEvent)-1] != "unpause" {
|
||||
t.Fatalf("event should be unpause, not %#v", unpauseEvent)
|
||||
c.Fatalf("event should be unpause, not %#v", unpauseEvent)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("pause - multi pause/unpause is logged")
|
||||
}
|
||||
|
|
|
@ -5,42 +5,42 @@ import (
|
|||
"os/exec"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestPortList(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestPortList(c *check.C) {
|
||||
|
||||
// one port
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "-p", "9876:80", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
firstID := strings.TrimSpace(out)
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "port", firstID, "80")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertPortList(t, out, []string{"0.0.0.0:9876"}) {
|
||||
t.Error("Port list is not correct")
|
||||
if !assertPortList(c, out, []string{"0.0.0.0:9876"}) {
|
||||
c.Error("Port list is not correct")
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "port", firstID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertPortList(t, out, []string{"80/tcp -> 0.0.0.0:9876"}) {
|
||||
t.Error("Port list is not correct")
|
||||
if !assertPortList(c, out, []string{"80/tcp -> 0.0.0.0:9876"}) {
|
||||
c.Error("Port list is not correct")
|
||||
}
|
||||
runCmd = exec.Command(dockerBinary, "rm", "-f", firstID)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
// three port
|
||||
|
@ -51,36 +51,36 @@ func TestPortList(t *testing.T) {
|
|||
"busybox", "top")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
ID := strings.TrimSpace(out)
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "port", ID, "80")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertPortList(t, out, []string{"0.0.0.0:9876"}) {
|
||||
t.Error("Port list is not correct")
|
||||
if !assertPortList(c, out, []string{"0.0.0.0:9876"}) {
|
||||
c.Error("Port list is not correct")
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "port", ID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertPortList(t, out, []string{
|
||||
if !assertPortList(c, out, []string{
|
||||
"80/tcp -> 0.0.0.0:9876",
|
||||
"81/tcp -> 0.0.0.0:9877",
|
||||
"82/tcp -> 0.0.0.0:9878"}) {
|
||||
t.Error("Port list is not correct")
|
||||
c.Error("Port list is not correct")
|
||||
}
|
||||
runCmd = exec.Command(dockerBinary, "rm", "-f", ID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
// more and one port mapped to the same container port
|
||||
|
@ -92,46 +92,45 @@ func TestPortList(t *testing.T) {
|
|||
"busybox", "top")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
ID = strings.TrimSpace(out)
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "port", ID, "80")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertPortList(t, out, []string{"0.0.0.0:9876", "0.0.0.0:9999"}) {
|
||||
t.Error("Port list is not correct")
|
||||
if !assertPortList(c, out, []string{"0.0.0.0:9876", "0.0.0.0:9999"}) {
|
||||
c.Error("Port list is not correct")
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "port", ID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertPortList(t, out, []string{
|
||||
if !assertPortList(c, out, []string{
|
||||
"80/tcp -> 0.0.0.0:9876",
|
||||
"80/tcp -> 0.0.0.0:9999",
|
||||
"81/tcp -> 0.0.0.0:9877",
|
||||
"82/tcp -> 0.0.0.0:9878"}) {
|
||||
t.Error("Port list is not correct\n", out)
|
||||
c.Error("Port list is not correct\n", out)
|
||||
}
|
||||
runCmd = exec.Command(dockerBinary, "rm", "-f", ID)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
logDone("port - test port list")
|
||||
}
|
||||
|
||||
func assertPortList(t *testing.T, out string, expected []string) bool {
|
||||
func assertPortList(c *check.C, out string, expected []string) bool {
|
||||
//lines := strings.Split(out, "\n")
|
||||
lines := strings.Split(strings.Trim(out, "\n "), "\n")
|
||||
if len(lines) != len(expected) {
|
||||
t.Errorf("different size lists %s, %d, %d", out, len(lines), len(expected))
|
||||
c.Errorf("different size lists %s, %d, %d", out, len(lines), len(expected))
|
||||
return false
|
||||
}
|
||||
sort.Strings(lines)
|
||||
|
@ -139,7 +138,7 @@ func assertPortList(t *testing.T, out string, expected []string) bool {
|
|||
|
||||
for i := 0; i < len(expected); i++ {
|
||||
if lines[i] != expected[i] {
|
||||
t.Error("|" + lines[i] + "!=" + expected[i] + "|")
|
||||
c.Error("|" + lines[i] + "!=" + expected[i] + "|")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -147,84 +146,78 @@ func assertPortList(t *testing.T, out string, expected []string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func TestPortHostBinding(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
|
||||
func (s *DockerSuite) TestPortHostBinding(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "-p", "9876:80", "busybox",
|
||||
"nc", "-l", "-p", "80")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
firstID := strings.TrimSpace(out)
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "port", firstID, "80")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertPortList(t, out, []string{"0.0.0.0:9876"}) {
|
||||
t.Error("Port list is not correct")
|
||||
if !assertPortList(c, out, []string{"0.0.0.0:9876"}) {
|
||||
c.Error("Port list is not correct")
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "run", "--net=host", "busybox",
|
||||
"nc", "localhost", "9876")
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "rm", "-f", firstID)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "run", "--net=host", "busybox",
|
||||
"nc", "localhost", "9876")
|
||||
if out, _, err = runCommandWithOutput(runCmd); err == nil {
|
||||
t.Error("Port is still bound after the Container is removed")
|
||||
c.Error("Port is still bound after the Container is removed")
|
||||
}
|
||||
logDone("port - test host binding done")
|
||||
}
|
||||
|
||||
func TestPortExposeHostBinding(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
|
||||
func (s *DockerSuite) TestPortExposeHostBinding(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "-P", "--expose", "80", "busybox",
|
||||
"nc", "-l", "-p", "80")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
firstID := strings.TrimSpace(out)
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "port", firstID, "80")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
_, exposedPort, err := net.SplitHostPort(out)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "run", "--net=host", "busybox",
|
||||
"nc", "localhost", strings.TrimSpace(exposedPort))
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "rm", "-f", firstID)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "run", "--net=host", "busybox",
|
||||
"nc", "localhost", strings.TrimSpace(exposedPort))
|
||||
if out, _, err = runCommandWithOutput(runCmd); err == nil {
|
||||
t.Error("Port is still bound after the Container is removed")
|
||||
c.Error("Port is still bound after the Container is removed")
|
||||
}
|
||||
logDone("port - test port expose done")
|
||||
}
|
||||
|
|
|
@ -4,30 +4,30 @@ import (
|
|||
"net"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestCliProxyDisableProxyUnixSock(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon) // test is valid when DOCKER_HOST=unix://..
|
||||
func (s *DockerSuite) TestCliProxyDisableProxyUnixSock(c *check.C) {
|
||||
testRequires(c, SameHostDaemon) // test is valid when DOCKER_HOST=unix://..
|
||||
|
||||
cmd := exec.Command(dockerBinary, "info")
|
||||
cmd.Env = appendBaseEnv([]string{"HTTP_PROXY=http://127.0.0.1:9999"})
|
||||
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
logDone("cli proxy - HTTP_PROXY is not used when connecting to unix sock")
|
||||
}
|
||||
|
||||
// Can't use localhost here since go has a special case to not use proxy if connecting to localhost
|
||||
// See https://golang.org/pkg/net/http/#ProxyFromEnvironment
|
||||
func TestCliProxyProxyTCPSock(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon)
|
||||
func (s *DockerSuite) TestCliProxyProxyTCPSock(c *check.C) {
|
||||
testRequires(c, SameHostDaemon)
|
||||
// get the IP to use to connect since we can't use localhost
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
var ip string
|
||||
for _, addr := range addrs {
|
||||
|
@ -40,25 +40,24 @@ func TestCliProxyProxyTCPSock(t *testing.T) {
|
|||
}
|
||||
|
||||
if ip == "" {
|
||||
t.Fatal("could not find ip to connect to")
|
||||
c.Fatal("could not find ip to connect to")
|
||||
}
|
||||
|
||||
d := NewDaemon(t)
|
||||
d := NewDaemon(c)
|
||||
if err := d.Start("-H", "tcp://"+ip+":2375"); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cmd := exec.Command(dockerBinary, "info")
|
||||
cmd.Env = []string{"DOCKER_HOST=tcp://" + ip + ":2375", "HTTP_PROXY=127.0.0.1:9999"}
|
||||
if out, _, err := runCommandWithOutput(cmd); err == nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
// Test with no_proxy
|
||||
cmd.Env = append(cmd.Env, "NO_PROXY="+ip)
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "info")); err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
logDone("cli proxy - HTTP_PROXY is used for TCP sock")
|
||||
}
|
||||
|
|
|
@ -6,24 +6,24 @@ import (
|
|||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestPsListContainers(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestPsListContainers(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
firstID := strings.TrimSpace(out)
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "top")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
secondID := strings.TrimSpace(out)
|
||||
|
||||
|
@ -31,53 +31,53 @@ func TestPsListContainers(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
thirdID := strings.TrimSpace(out)
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "top")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
fourthID := strings.TrimSpace(out)
|
||||
|
||||
// make sure the second is running
|
||||
if err := waitRun(secondID); err != nil {
|
||||
t.Fatalf("waiting for container failed: %v", err)
|
||||
c.Fatalf("waiting for container failed: %v", err)
|
||||
}
|
||||
|
||||
// make sure third one is not running
|
||||
runCmd = exec.Command(dockerBinary, "wait", thirdID)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
// make sure the forth is running
|
||||
if err := waitRun(fourthID); err != nil {
|
||||
t.Fatalf("waiting for container failed: %v", err)
|
||||
c.Fatalf("waiting for container failed: %v", err)
|
||||
}
|
||||
|
||||
// all
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-a")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertContainerList(out, []string{fourthID, thirdID, secondID, firstID}) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
// running
|
||||
runCmd = exec.Command(dockerBinary, "ps")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertContainerList(out, []string{fourthID, secondID, firstID}) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
// from here all flag '-a' is ignored
|
||||
|
@ -86,156 +86,155 @@ func TestPsListContainers(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "ps", "-n=2", "-a")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
expected := []string{fourthID, thirdID}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-n=2")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
// since
|
||||
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "-a")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
expected = []string{fourthID, thirdID, secondID}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
// before
|
||||
runCmd = exec.Command(dockerBinary, "ps", "--before", thirdID, "-a")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
expected = []string{secondID, firstID}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "ps", "--before", thirdID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
// since & before
|
||||
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "--before", fourthID, "-a")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
expected = []string{thirdID, secondID}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "--before", fourthID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
// since & limit
|
||||
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "-n=2", "-a")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
expected = []string{fourthID, thirdID}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "-n=2")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
// before & limit
|
||||
runCmd = exec.Command(dockerBinary, "ps", "--before", fourthID, "-n=1", "-a")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
expected = []string{thirdID}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "ps", "--before", fourthID, "-n=1")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
// since & before & limit
|
||||
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "--before", fourthID, "-n=1", "-a")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
expected = []string{thirdID}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "--before", fourthID, "-n=1")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if !assertContainerList(out, expected) {
|
||||
t.Errorf("Container list is not in the correct order: %s", out)
|
||||
c.Errorf("Container list is not in the correct order: %s", out)
|
||||
}
|
||||
|
||||
logDone("ps - test ps options")
|
||||
}
|
||||
|
||||
func assertContainerList(out string, expected []string) bool {
|
||||
|
@ -255,8 +254,7 @@ func assertContainerList(out string, expected []string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func TestPsListContainersSize(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestPsListContainersSize(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "-d", "busybox", "echo", "hello")
|
||||
runCommandWithOutput(cmd)
|
||||
|
@ -267,18 +265,18 @@ func TestPsListContainersSize(t *testing.T) {
|
|||
baseFoundsize := baseLines[1][baseSizeIndex:]
|
||||
baseBytes, err := strconv.Atoi(strings.Split(baseFoundsize, " ")[0])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
name := "test_size"
|
||||
runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "sh", "-c", "echo 1 > test")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
id, err := getIDByName(name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-s", "-n=1")
|
||||
|
@ -290,54 +288,52 @@ func TestPsListContainersSize(t *testing.T) {
|
|||
select {
|
||||
case <-wait:
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatalf("Calling \"docker ps -s\" timed out!")
|
||||
c.Fatalf("Calling \"docker ps -s\" timed out!")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
lines := strings.Split(strings.Trim(out, "\n "), "\n")
|
||||
if len(lines) != 2 {
|
||||
t.Fatalf("Expected 2 lines for 'ps -s -n=1' output, got %d", len(lines))
|
||||
c.Fatalf("Expected 2 lines for 'ps -s -n=1' output, got %d", len(lines))
|
||||
}
|
||||
sizeIndex := strings.Index(lines[0], "SIZE")
|
||||
idIndex := strings.Index(lines[0], "CONTAINER ID")
|
||||
foundID := lines[1][idIndex : idIndex+12]
|
||||
if foundID != id[:12] {
|
||||
t.Fatalf("Expected id %s, got %s", id[:12], foundID)
|
||||
c.Fatalf("Expected id %s, got %s", id[:12], foundID)
|
||||
}
|
||||
expectedSize := fmt.Sprintf("%d B", (2 + baseBytes))
|
||||
foundSize := lines[1][sizeIndex:]
|
||||
if foundSize != expectedSize {
|
||||
t.Fatalf("Expected size %q, got %q", expectedSize, foundSize)
|
||||
c.Fatalf("Expected size %q, got %q", expectedSize, foundSize)
|
||||
}
|
||||
|
||||
logDone("ps - test ps size")
|
||||
}
|
||||
|
||||
func TestPsListContainersFilterStatus(t *testing.T) {
|
||||
func (s *DockerSuite) TestPsListContainersFilterStatus(c *check.C) {
|
||||
// FIXME: this should test paused, but it makes things hang and its wonky
|
||||
// this is because paused containers can't be controlled by signals
|
||||
defer deleteAllContainers()
|
||||
|
||||
// start exited container
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
firstID := strings.TrimSpace(out)
|
||||
|
||||
// make sure the exited cintainer is not running
|
||||
runCmd = exec.Command(dockerBinary, "wait", firstID)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
// start running container
|
||||
runCmd = exec.Command(dockerBinary, "run", "-itd", "busybox")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
secondID := strings.TrimSpace(out)
|
||||
|
||||
|
@ -345,313 +341,302 @@ func TestPsListContainersFilterStatus(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "ps", "-q", "--filter=status=exited")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerOut := strings.TrimSpace(out)
|
||||
if containerOut != firstID[:12] {
|
||||
t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
|
||||
c.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=status=running")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerOut = strings.TrimSpace(out)
|
||||
if containerOut != secondID[:12] {
|
||||
t.Fatalf("Expected id %s, got %s for running filter, output: %q", secondID[:12], containerOut, out)
|
||||
c.Fatalf("Expected id %s, got %s for running filter, output: %q", secondID[:12], containerOut, out)
|
||||
}
|
||||
|
||||
logDone("ps - test ps filter status")
|
||||
}
|
||||
|
||||
func TestPsListContainersFilterID(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestPsListContainersFilterID(c *check.C) {
|
||||
|
||||
// start container
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
firstID := strings.TrimSpace(out)
|
||||
|
||||
// start another container
|
||||
runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "top")
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
// filter containers by id
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=id="+firstID)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerOut := strings.TrimSpace(out)
|
||||
if containerOut != firstID[:12] {
|
||||
t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
|
||||
c.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
|
||||
}
|
||||
|
||||
logDone("ps - test ps filter id")
|
||||
}
|
||||
|
||||
func TestPsListContainersFilterName(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestPsListContainersFilterName(c *check.C) {
|
||||
|
||||
// start container
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name=a_name_to_match", "busybox")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
firstID := strings.TrimSpace(out)
|
||||
|
||||
// start another container
|
||||
runCmd = exec.Command(dockerBinary, "run", "-d", "--name=b_name_to_match", "busybox", "top")
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
// filter containers by name
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=name=a_name_to_match")
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerOut := strings.TrimSpace(out)
|
||||
if containerOut != firstID[:12] {
|
||||
t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
|
||||
c.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
|
||||
}
|
||||
|
||||
logDone("ps - test ps filter name")
|
||||
}
|
||||
|
||||
func TestPsListContainersFilterLabel(t *testing.T) {
|
||||
func (s *DockerSuite) TestPsListContainersFilterLabel(c *check.C) {
|
||||
// start container
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "-l", "match=me", "-l", "second=tag", "busybox")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
firstID := strings.TrimSpace(out)
|
||||
|
||||
// start another container
|
||||
runCmd = exec.Command(dockerBinary, "run", "-d", "-l", "match=me too", "busybox")
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
secondID := strings.TrimSpace(out)
|
||||
|
||||
// start third container
|
||||
runCmd = exec.Command(dockerBinary, "run", "-d", "-l", "nomatch=me", "busybox")
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
thirdID := strings.TrimSpace(out)
|
||||
|
||||
// filter containers by exact match
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me")
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerOut := strings.TrimSpace(out)
|
||||
if containerOut != firstID {
|
||||
t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out)
|
||||
c.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out)
|
||||
}
|
||||
|
||||
// filter containers by two labels
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me", "--filter=label=second=tag")
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerOut = strings.TrimSpace(out)
|
||||
if containerOut != firstID {
|
||||
t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out)
|
||||
c.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out)
|
||||
}
|
||||
|
||||
// filter containers by two labels, but expect not found because of AND behavior
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me", "--filter=label=second=tag-no")
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerOut = strings.TrimSpace(out)
|
||||
if containerOut != "" {
|
||||
t.Fatalf("Expected nothing, got %s for exited filter, output: %q", containerOut, out)
|
||||
c.Fatalf("Expected nothing, got %s for exited filter, output: %q", containerOut, out)
|
||||
}
|
||||
|
||||
// filter containers by exact key
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--no-trunc", "--filter=label=match")
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerOut = strings.TrimSpace(out)
|
||||
if (!strings.Contains(containerOut, firstID) || !strings.Contains(containerOut, secondID)) || strings.Contains(containerOut, thirdID) {
|
||||
t.Fatalf("Expected ids %s,%s, got %s for exited filter, output: %q", firstID, secondID, containerOut, out)
|
||||
c.Fatalf("Expected ids %s,%s, got %s for exited filter, output: %q", firstID, secondID, containerOut, out)
|
||||
}
|
||||
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("ps - test ps filter label")
|
||||
}
|
||||
|
||||
func TestPsListContainersFilterExited(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestPsListContainersFilterExited(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "top", "busybox", "top")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "run", "--name", "zero1", "busybox", "true")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
firstZero, err := getIDByName("zero1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "run", "--name", "zero2", "busybox", "true")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
secondZero, err := getIDByName("zero2")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "run", "--name", "nonzero1", "busybox", "false")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err == nil {
|
||||
t.Fatal("Should fail.", out, err)
|
||||
c.Fatal("Should fail.", out, err)
|
||||
}
|
||||
firstNonZero, err := getIDByName("nonzero1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "run", "--name", "nonzero2", "busybox", "false")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err == nil {
|
||||
t.Fatal("Should fail.", out, err)
|
||||
c.Fatal("Should fail.", out, err)
|
||||
}
|
||||
secondNonZero, err := getIDByName("nonzero2")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// filter containers by exited=0
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--no-trunc", "--filter=exited=0")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
ids := strings.Split(strings.TrimSpace(out), "\n")
|
||||
if len(ids) != 2 {
|
||||
t.Fatalf("Should be 2 zero exited containers got %d: %s", len(ids), out)
|
||||
c.Fatalf("Should be 2 zero exited containers got %d: %s", len(ids), out)
|
||||
}
|
||||
if ids[0] != secondZero {
|
||||
t.Fatalf("First in list should be %q, got %q", secondZero, ids[0])
|
||||
c.Fatalf("First in list should be %q, got %q", secondZero, ids[0])
|
||||
}
|
||||
if ids[1] != firstZero {
|
||||
t.Fatalf("Second in list should be %q, got %q", firstZero, ids[1])
|
||||
c.Fatalf("Second in list should be %q, got %q", firstZero, ids[1])
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--no-trunc", "--filter=exited=1")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
ids = strings.Split(strings.TrimSpace(out), "\n")
|
||||
if len(ids) != 2 {
|
||||
t.Fatalf("Should be 2 zero exited containerst got %d", len(ids))
|
||||
c.Fatalf("Should be 2 zero exited containerst got %d", len(ids))
|
||||
}
|
||||
if ids[0] != secondNonZero {
|
||||
t.Fatalf("First in list should be %q, got %q", secondNonZero, ids[0])
|
||||
c.Fatalf("First in list should be %q, got %q", secondNonZero, ids[0])
|
||||
}
|
||||
if ids[1] != firstNonZero {
|
||||
t.Fatalf("Second in list should be %q, got %q", firstNonZero, ids[1])
|
||||
c.Fatalf("Second in list should be %q, got %q", firstNonZero, ids[1])
|
||||
}
|
||||
|
||||
logDone("ps - test ps filter exited")
|
||||
}
|
||||
|
||||
func TestPsRightTagName(t *testing.T) {
|
||||
func (s *DockerSuite) TestPsRightTagName(c *check.C) {
|
||||
tag := "asybox:shmatest"
|
||||
defer deleteAllContainers()
|
||||
defer deleteImages(tag)
|
||||
if out, err := exec.Command(dockerBinary, "tag", "busybox", tag).CombinedOutput(); err != nil {
|
||||
t.Fatalf("Failed to tag image: %s, out: %q", err, out)
|
||||
c.Fatalf("Failed to tag image: %s, out: %q", err, out)
|
||||
}
|
||||
|
||||
var id1 string
|
||||
if out, err := exec.Command(dockerBinary, "run", "-d", "busybox", "top").CombinedOutput(); err != nil {
|
||||
t.Fatalf("Failed to run container: %s, out: %q", err, out)
|
||||
c.Fatalf("Failed to run container: %s, out: %q", err, out)
|
||||
} else {
|
||||
id1 = strings.TrimSpace(string(out))
|
||||
}
|
||||
|
||||
var id2 string
|
||||
if out, err := exec.Command(dockerBinary, "run", "-d", tag, "top").CombinedOutput(); err != nil {
|
||||
t.Fatalf("Failed to run container: %s, out: %q", err, out)
|
||||
c.Fatalf("Failed to run container: %s, out: %q", err, out)
|
||||
} else {
|
||||
id2 = strings.TrimSpace(string(out))
|
||||
}
|
||||
|
||||
var imageID string
|
||||
if out, err := exec.Command(dockerBinary, "inspect", "-f", "{{.Id}}", "busybox").CombinedOutput(); err != nil {
|
||||
t.Fatalf("failed to get the image ID of busybox: %s, %v", out, err)
|
||||
c.Fatalf("failed to get the image ID of busybox: %s, %v", out, err)
|
||||
} else {
|
||||
imageID = strings.TrimSpace(string(out))
|
||||
}
|
||||
|
||||
var id3 string
|
||||
if out, err := exec.Command(dockerBinary, "run", "-d", imageID, "top").CombinedOutput(); err != nil {
|
||||
t.Fatalf("Failed to run container: %s, out: %q", err, out)
|
||||
c.Fatalf("Failed to run container: %s, out: %q", err, out)
|
||||
} else {
|
||||
id3 = strings.TrimSpace(string(out))
|
||||
}
|
||||
|
||||
out, err := exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to run 'ps': %s, out: %q", err, out)
|
||||
c.Fatalf("Failed to run 'ps': %s, out: %q", err, out)
|
||||
}
|
||||
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
|
||||
// skip header
|
||||
lines = lines[1:]
|
||||
if len(lines) != 3 {
|
||||
t.Fatalf("There should be 3 running container, got %d", len(lines))
|
||||
c.Fatalf("There should be 3 running container, got %d", len(lines))
|
||||
}
|
||||
for _, line := range lines {
|
||||
f := strings.Fields(line)
|
||||
switch f[0] {
|
||||
case id1:
|
||||
if f[1] != "busybox" {
|
||||
t.Fatalf("Expected %s tag for id %s, got %s", "busybox", id1, f[1])
|
||||
c.Fatalf("Expected %s tag for id %s, got %s", "busybox", id1, f[1])
|
||||
}
|
||||
case id2:
|
||||
if f[1] != tag {
|
||||
t.Fatalf("Expected %s tag for id %s, got %s", tag, id2, f[1])
|
||||
c.Fatalf("Expected %s tag for id %s, got %s", tag, id2, f[1])
|
||||
}
|
||||
case id3:
|
||||
if f[1] != imageID {
|
||||
t.Fatalf("Expected %s imageID for id %s, got %s", tag, id3, f[1])
|
||||
c.Fatalf("Expected %s imageID for id %s, got %s", tag, id3, f[1])
|
||||
}
|
||||
default:
|
||||
t.Fatalf("Unexpected id %s, expected %s and %s and %s", f[0], id1, id2, id3)
|
||||
c.Fatalf("Unexpected id %s, expected %s and %s and %s", f[0], id1, id2, id3)
|
||||
}
|
||||
}
|
||||
logDone("ps - right tags for containers")
|
||||
}
|
||||
|
||||
func TestPsLinkedWithNoTrunc(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestPsLinkedWithNoTrunc(c *check.C) {
|
||||
if out, err := exec.Command(dockerBinary, "run", "--name=first", "-d", "busybox", "top").CombinedOutput(); err != nil {
|
||||
t.Fatalf("Output: %s, err: %s", out, err)
|
||||
c.Fatalf("Output: %s, err: %s", out, err)
|
||||
}
|
||||
if out, err := exec.Command(dockerBinary, "run", "--name=second", "--link=first:first", "-d", "busybox", "top").CombinedOutput(); err != nil {
|
||||
t.Fatalf("Output: %s, err: %s", out, err)
|
||||
c.Fatalf("Output: %s, err: %s", out, err)
|
||||
}
|
||||
out, err := exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("Output: %s, err: %s", out, err)
|
||||
c.Fatalf("Output: %s, err: %s", out, err)
|
||||
}
|
||||
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
|
||||
// strip header
|
||||
|
@ -663,28 +648,26 @@ func TestPsLinkedWithNoTrunc(t *testing.T) {
|
|||
names = append(names, fields[len(fields)-1])
|
||||
}
|
||||
if !reflect.DeepEqual(expected, names) {
|
||||
t.Fatalf("Expected array: %v, got: %v", expected, names)
|
||||
c.Fatalf("Expected array: %v, got: %v", expected, names)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPsGroupPortRange(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestPsGroupPortRange(c *check.C) {
|
||||
|
||||
portRange := "3800-3900"
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "porttest", "-p", portRange+":"+portRange, "busybox", "top"))
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "ps"))
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
// check that the port range is in the output
|
||||
if !strings.Contains(string(out), portRange) {
|
||||
t.Fatalf("docker ps output should have had the port range %q: %s", portRange, string(out))
|
||||
c.Fatalf("docker ps output should have had the port range %q: %s", portRange, string(out))
|
||||
}
|
||||
|
||||
logDone("ps - port range")
|
||||
}
|
||||
|
|
|
@ -4,12 +4,13 @@ import (
|
|||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// See issue docker/docker#8141
|
||||
func TestPullImageWithAliases(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestPullImageWithAliases(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
defer deleteImages(repoName)
|
||||
|
@ -22,40 +23,39 @@ func TestPullImageWithAliases(t *testing.T) {
|
|||
// Tag and push the same image multiple times.
|
||||
for _, repo := range repos {
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "tag", "busybox", repo)); err != nil {
|
||||
t.Fatalf("Failed to tag image %v: error %v, output %q", repos, err, out)
|
||||
c.Fatalf("Failed to tag image %v: error %v, output %q", repos, err, out)
|
||||
}
|
||||
defer deleteImages(repo)
|
||||
if out, err := exec.Command(dockerBinary, "push", repo).CombinedOutput(); err != nil {
|
||||
t.Fatalf("Failed to push image %v: error %v, output %q", repo, err, string(out))
|
||||
c.Fatalf("Failed to push image %v: error %v, output %q", repo, err, string(out))
|
||||
}
|
||||
}
|
||||
|
||||
// Clear local images store.
|
||||
args := append([]string{"rmi"}, repos...)
|
||||
if out, err := exec.Command(dockerBinary, args...).CombinedOutput(); err != nil {
|
||||
t.Fatalf("Failed to clean images: error %v, output %q", err, string(out))
|
||||
c.Fatalf("Failed to clean images: error %v, output %q", err, string(out))
|
||||
}
|
||||
|
||||
// Pull a single tag and verify it doesn't bring down all aliases.
|
||||
pullCmd := exec.Command(dockerBinary, "pull", repos[0])
|
||||
if out, _, err := runCommandWithOutput(pullCmd); err != nil {
|
||||
t.Fatalf("Failed to pull %v: error %v, output %q", repoName, err, out)
|
||||
c.Fatalf("Failed to pull %v: error %v, output %q", repoName, err, out)
|
||||
}
|
||||
if err := exec.Command(dockerBinary, "inspect", repos[0]).Run(); err != nil {
|
||||
t.Fatalf("Image %v was not pulled down", repos[0])
|
||||
c.Fatalf("Image %v was not pulled down", repos[0])
|
||||
}
|
||||
for _, repo := range repos[1:] {
|
||||
if err := exec.Command(dockerBinary, "inspect", repo).Run(); err == nil {
|
||||
t.Fatalf("Image %v shouldn't have been pulled down", repo)
|
||||
c.Fatalf("Image %v shouldn't have been pulled down", repo)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("pull - image with aliases")
|
||||
}
|
||||
|
||||
// pulling library/hello-world should show verified message
|
||||
func TestPullVerified(t *testing.T) {
|
||||
t.Skip("Skipping hub dependent test")
|
||||
func (s *DockerSuite) TestPullVerified(c *check.C) {
|
||||
c.Skip("Skipping hub dependent test")
|
||||
|
||||
// Image must be pulled from central repository to get verified message
|
||||
// unless keychain is manually updated to contain the daemon's sign key.
|
||||
|
@ -68,49 +68,46 @@ func TestPullVerified(t *testing.T) {
|
|||
pullCmd := exec.Command(dockerBinary, "pull", verifiedName)
|
||||
if out, exitCode, err := runCommandWithOutput(pullCmd); err != nil || !strings.Contains(out, expected) {
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Skipf("pulling the '%s' image from the registry has failed: %s", verifiedName, err)
|
||||
c.Skip(fmt.Sprintf("pulling the '%s' image from the registry has failed: %v", verifiedName, err))
|
||||
}
|
||||
t.Fatalf("pulling a verified image failed. expected: %s\ngot: %s, %v", expected, out, err)
|
||||
c.Fatalf("pulling a verified image failed. expected: %s\ngot: %s, %v", expected, out, err)
|
||||
}
|
||||
|
||||
// pull it again
|
||||
pullCmd = exec.Command(dockerBinary, "pull", verifiedName)
|
||||
if out, exitCode, err := runCommandWithOutput(pullCmd); err != nil || strings.Contains(out, expected) {
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Skipf("pulling the '%s' image from the registry has failed: %s", verifiedName, err)
|
||||
c.Skip(fmt.Sprintf("pulling the '%s' image from the registry has failed: %v", verifiedName, err))
|
||||
}
|
||||
t.Fatalf("pulling a verified image failed. unexpected verify message\ngot: %s, %v", out, err)
|
||||
c.Fatalf("pulling a verified image failed. unexpected verify message\ngot: %s, %v", out, err)
|
||||
}
|
||||
|
||||
logDone("pull - pull verified")
|
||||
}
|
||||
|
||||
// pulling an image from the central registry should work
|
||||
func TestPullImageFromCentralRegistry(t *testing.T) {
|
||||
testRequires(t, Network)
|
||||
func (s *DockerSuite) TestPullImageFromCentralRegistry(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
|
||||
defer deleteImages("hello-world")
|
||||
|
||||
pullCmd := exec.Command(dockerBinary, "pull", "hello-world")
|
||||
if out, _, err := runCommandWithOutput(pullCmd); err != nil {
|
||||
t.Fatalf("pulling the hello-world image from the registry has failed: %s, %v", out, err)
|
||||
c.Fatalf("pulling the hello-world image from the registry has failed: %s, %v", out, err)
|
||||
}
|
||||
logDone("pull - pull hello-world")
|
||||
}
|
||||
|
||||
// pulling a non-existing image from the central registry should return a non-zero exit code
|
||||
func TestPullNonExistingImage(t *testing.T) {
|
||||
func (s *DockerSuite) TestPullNonExistingImage(c *check.C) {
|
||||
pullCmd := exec.Command(dockerBinary, "pull", "fooblahblah1234")
|
||||
if out, _, err := runCommandWithOutput(pullCmd); err == nil {
|
||||
t.Fatalf("expected non-zero exit status when pulling non-existing image: %s", out)
|
||||
c.Fatalf("expected non-zero exit status when pulling non-existing image: %s", out)
|
||||
}
|
||||
logDone("pull - pull fooblahblah1234 (non-existing image)")
|
||||
}
|
||||
|
||||
// pulling an image from the central registry using official names should work
|
||||
// ensure all pulls result in the same image
|
||||
func TestPullImageOfficialNames(t *testing.T) {
|
||||
testRequires(t, Network)
|
||||
func (s *DockerSuite) TestPullImageOfficialNames(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
|
||||
names := []string{
|
||||
"docker.io/hello-world",
|
||||
|
@ -123,7 +120,7 @@ func TestPullImageOfficialNames(t *testing.T) {
|
|||
pullCmd := exec.Command(dockerBinary, "pull", name)
|
||||
out, exitCode, err := runCommandWithOutput(pullCmd)
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Errorf("pulling the '%s' image from the registry has failed: %s", name, err)
|
||||
c.Errorf("pulling the '%s' image from the registry has failed: %s", name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -131,10 +128,9 @@ func TestPullImageOfficialNames(t *testing.T) {
|
|||
imagesCmd := exec.Command(dockerBinary, "images")
|
||||
out, _, err = runCommandWithOutput(imagesCmd)
|
||||
if err != nil {
|
||||
t.Errorf("listing images failed with errors: %v", err)
|
||||
c.Errorf("listing images failed with errors: %v", err)
|
||||
} else if strings.Contains(out, name) {
|
||||
t.Errorf("images should not have listed '%s'", name)
|
||||
c.Errorf("images should not have listed '%s'", name)
|
||||
}
|
||||
}
|
||||
logDone("pull - pull official names")
|
||||
}
|
||||
|
|
|
@ -6,72 +6,68 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// pulling an image from the central registry should work
|
||||
func TestPushBusyboxImage(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestPushBusyboxImage(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
// tag the image to upload it to the private registry
|
||||
tagCmd := exec.Command(dockerBinary, "tag", "busybox", repoName)
|
||||
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
|
||||
t.Fatalf("image tagging failed: %s, %v", out, err)
|
||||
c.Fatalf("image tagging failed: %s, %v", out, err)
|
||||
}
|
||||
defer deleteImages(repoName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
if out, _, err := runCommandWithOutput(pushCmd); err != nil {
|
||||
t.Fatalf("pushing the image to the private registry has failed: %s, %v", out, err)
|
||||
c.Fatalf("pushing the image to the private registry has failed: %s, %v", out, err)
|
||||
}
|
||||
logDone("push - busybox to private registry")
|
||||
}
|
||||
|
||||
// pushing an image without a prefix should throw an error
|
||||
func TestPushUnprefixedRepo(t *testing.T) {
|
||||
func (s *DockerSuite) TestPushUnprefixedRepo(c *check.C) {
|
||||
pushCmd := exec.Command(dockerBinary, "push", "busybox")
|
||||
if out, _, err := runCommandWithOutput(pushCmd); err == nil {
|
||||
t.Fatalf("pushing an unprefixed repo didn't result in a non-zero exit status: %s", out)
|
||||
c.Fatalf("pushing an unprefixed repo didn't result in a non-zero exit status: %s", out)
|
||||
}
|
||||
logDone("push - unprefixed busybox repo must not pass")
|
||||
}
|
||||
|
||||
func TestPushUntagged(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestPushUntagged(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
|
||||
expected := "Repository does not exist"
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
if out, _, err := runCommandWithOutput(pushCmd); err == nil {
|
||||
t.Fatalf("pushing the image to the private registry should have failed: outuput %q", out)
|
||||
c.Fatalf("pushing the image to the private registry should have failed: outuput %q", out)
|
||||
} else if !strings.Contains(out, expected) {
|
||||
t.Fatalf("pushing the image failed with an unexpected message: expected %q, got %q", expected, out)
|
||||
c.Fatalf("pushing the image failed with an unexpected message: expected %q, got %q", expected, out)
|
||||
}
|
||||
logDone("push - untagged image")
|
||||
}
|
||||
|
||||
func TestPushBadTag(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestPushBadTag(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox:latest", privateRegistryURL)
|
||||
|
||||
expected := "does not exist"
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
if out, _, err := runCommandWithOutput(pushCmd); err == nil {
|
||||
t.Fatalf("pushing the image to the private registry should have failed: outuput %q", out)
|
||||
c.Fatalf("pushing the image to the private registry should have failed: outuput %q", out)
|
||||
} else if !strings.Contains(out, expected) {
|
||||
t.Fatalf("pushing the image failed with an unexpected message: expected %q, got %q", expected, out)
|
||||
c.Fatalf("pushing the image failed with an unexpected message: expected %q, got %q", expected, out)
|
||||
}
|
||||
logDone("push - image with bad tag")
|
||||
}
|
||||
|
||||
func TestPushMultipleTags(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestPushMultipleTags(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
repoTag1 := fmt.Sprintf("%v/dockercli/busybox:t1", privateRegistryURL)
|
||||
|
@ -79,80 +75,79 @@ func TestPushMultipleTags(t *testing.T) {
|
|||
// tag the image to upload it tot he private registry
|
||||
tagCmd1 := exec.Command(dockerBinary, "tag", "busybox", repoTag1)
|
||||
if out, _, err := runCommandWithOutput(tagCmd1); err != nil {
|
||||
t.Fatalf("image tagging failed: %s, %v", out, err)
|
||||
c.Fatalf("image tagging failed: %s, %v", out, err)
|
||||
}
|
||||
defer deleteImages(repoTag1)
|
||||
tagCmd2 := exec.Command(dockerBinary, "tag", "busybox", repoTag2)
|
||||
if out, _, err := runCommandWithOutput(tagCmd2); err != nil {
|
||||
t.Fatalf("image tagging failed: %s, %v", out, err)
|
||||
c.Fatalf("image tagging failed: %s, %v", out, err)
|
||||
}
|
||||
defer deleteImages(repoTag2)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
if out, _, err := runCommandWithOutput(pushCmd); err != nil {
|
||||
t.Fatalf("pushing the image to the private registry has failed: %s, %v", out, err)
|
||||
c.Fatalf("pushing the image to the private registry has failed: %s, %v", out, err)
|
||||
}
|
||||
logDone("push - multiple tags to private registry")
|
||||
}
|
||||
|
||||
func TestPushInterrupt(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestPushInterrupt(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
// tag the image to upload it tot he private registry
|
||||
tagCmd := exec.Command(dockerBinary, "tag", "busybox", repoName)
|
||||
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
|
||||
t.Fatalf("image tagging failed: %s, %v", out, err)
|
||||
c.Fatalf("image tagging failed: %s, %v", out, err)
|
||||
}
|
||||
defer deleteImages(repoName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
if err := pushCmd.Start(); err != nil {
|
||||
t.Fatalf("Failed to start pushing to private registry: %v", err)
|
||||
c.Fatalf("Failed to start pushing to private registry: %v", err)
|
||||
}
|
||||
|
||||
// Interrupt push (yes, we have no idea at what point it will get killed).
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
if err := pushCmd.Process.Kill(); err != nil {
|
||||
t.Fatalf("Failed to kill push process: %v", err)
|
||||
c.Fatalf("Failed to kill push process: %v", err)
|
||||
}
|
||||
// Try agin
|
||||
pushCmd = exec.Command(dockerBinary, "push", repoName)
|
||||
if err := pushCmd.Start(); err != nil {
|
||||
t.Fatalf("Failed to start pushing to private registry: %v", err)
|
||||
if out, err := pushCmd.CombinedOutput(); err == nil {
|
||||
str := string(out)
|
||||
if !strings.Contains(str, "already in progress") {
|
||||
c.Fatalf("Push should be continued on daemon side, but seems ok: %v, %s", err, out)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("push - interrupted")
|
||||
}
|
||||
|
||||
func TestPushEmptyLayer(t *testing.T) {
|
||||
defer setupRegistry(t)()
|
||||
func (s *DockerSuite) TestPushEmptyLayer(c *check.C) {
|
||||
defer setupRegistry(c)()
|
||||
repoName := fmt.Sprintf("%v/dockercli/emptylayer", privateRegistryURL)
|
||||
emptyTarball, err := ioutil.TempFile("", "empty_tarball")
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create test file: %v", err)
|
||||
c.Fatalf("Unable to create test file: %v", err)
|
||||
}
|
||||
tw := tar.NewWriter(emptyTarball)
|
||||
err = tw.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating empty tarball: %v", err)
|
||||
c.Fatalf("Error creating empty tarball: %v", err)
|
||||
}
|
||||
freader, err := os.Open(emptyTarball.Name())
|
||||
if err != nil {
|
||||
t.Fatalf("Could not open test tarball: %v", err)
|
||||
c.Fatalf("Could not open test tarball: %v", err)
|
||||
}
|
||||
|
||||
importCmd := exec.Command(dockerBinary, "import", "-", repoName)
|
||||
importCmd.Stdin = freader
|
||||
out, _, err := runCommandWithOutput(importCmd)
|
||||
if err != nil {
|
||||
t.Errorf("import failed with errors: %v, output: %q", err, out)
|
||||
c.Errorf("import failed with errors: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
// Now verify we can push it
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
if out, _, err := runCommandWithOutput(pushCmd); err != nil {
|
||||
t.Fatalf("pushing the image to the private registry has failed: %s, %v", out, err)
|
||||
c.Fatalf("pushing the image to the private registry has failed: %s, %v", out, err)
|
||||
}
|
||||
logDone("push - empty layer config to private registry")
|
||||
}
|
||||
|
|
|
@ -3,16 +3,16 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestRenameStoppedContainer(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRenameStoppedContainer(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "--name", "first_name", "-d", "busybox", "sh")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -20,7 +20,7 @@ func TestRenameStoppedContainer(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "wait", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
|
||||
name, err := inspectField(cleanedContainerID, "Name")
|
||||
|
@ -28,94 +28,87 @@ func TestRenameStoppedContainer(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "rename", "first_name", "new_name")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
|
||||
name, err = inspectField(cleanedContainerID, "Name")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if name != "/new_name" {
|
||||
t.Fatal("Failed to rename container ", name)
|
||||
c.Fatal("Failed to rename container ", name)
|
||||
}
|
||||
|
||||
logDone("rename - stopped container")
|
||||
}
|
||||
|
||||
func TestRenameRunningContainer(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRenameRunningContainer(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "--name", "first_name", "-d", "busybox", "sh")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
runCmd = exec.Command(dockerBinary, "rename", "first_name", "new_name")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
|
||||
name, err := inspectField(cleanedContainerID, "Name")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if name != "/new_name" {
|
||||
t.Fatal("Failed to rename container ")
|
||||
c.Fatal("Failed to rename container ")
|
||||
}
|
||||
|
||||
logDone("rename - running container")
|
||||
}
|
||||
|
||||
func TestRenameCheckNames(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRenameCheckNames(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "--name", "first_name", "-d", "busybox", "sh")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "rename", "first_name", "new_name")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
|
||||
name, err := inspectField("new_name", "Name")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if name != "/new_name" {
|
||||
t.Fatal("Failed to rename container ")
|
||||
c.Fatal("Failed to rename container ")
|
||||
}
|
||||
|
||||
name, err = inspectField("first_name", "Name")
|
||||
if err == nil && !strings.Contains(err.Error(), "No such image or container: first_name") {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
logDone("rename - old name released")
|
||||
}
|
||||
|
||||
func TestRenameInvalidName(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRenameInvalidName(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "--name", "myname", "-d", "busybox", "top")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatalf(out, err)
|
||||
c.Fatalf(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "rename", "myname", "new:invalid")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err == nil || !strings.Contains(out, "Invalid container name") {
|
||||
t.Fatalf("Renaming container to invalid name should have failed: %s\n%v", out, err)
|
||||
c.Fatalf("Renaming container to invalid name should have failed: %s\n%v", out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "ps", "-a")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil || !strings.Contains(out, "myname") {
|
||||
t.Fatalf("Output of docker ps should have included 'myname': %s\n%v", out, err)
|
||||
c.Fatalf("Output of docker ps should have included 'myname': %s\n%v", out, err)
|
||||
}
|
||||
|
||||
logDone("rename - invalid container name")
|
||||
}
|
||||
|
|
|
@ -3,61 +3,59 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestRestartStoppedContainer(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRestartStoppedContainer(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "echo", "foobar")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "wait", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "logs", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if out != "foobar\n" {
|
||||
t.Errorf("container should've printed 'foobar'")
|
||||
c.Errorf("container should've printed 'foobar'")
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "restart", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "logs", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if out != "foobar\nfoobar\n" {
|
||||
t.Errorf("container should've printed 'foobar' twice")
|
||||
c.Errorf("container should've printed 'foobar' twice")
|
||||
}
|
||||
|
||||
logDone("restart - echo foobar for stopped container")
|
||||
}
|
||||
|
||||
func TestRestartRunningContainer(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRestartRunningContainer(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "echo foobar && sleep 30 && echo 'should not print this'")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -67,41 +65,39 @@ func TestRestartRunningContainer(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "logs", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if out != "foobar\n" {
|
||||
t.Errorf("container should've printed 'foobar'")
|
||||
c.Errorf("container should've printed 'foobar'")
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "restart", "-t", "1", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "logs", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
if out != "foobar\nfoobar\n" {
|
||||
t.Errorf("container should've printed 'foobar' twice")
|
||||
c.Errorf("container should've printed 'foobar' twice")
|
||||
}
|
||||
|
||||
logDone("restart - echo foobar for running container")
|
||||
}
|
||||
|
||||
// Test that restarting a container with a volume does not create a new volume on restart. Regression test for #819.
|
||||
func TestRestartWithVolumes(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRestartWithVolumes(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "-v", "/test", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -109,148 +105,139 @@ func TestRestartWithVolumes(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "inspect", "--format", "{{ len .Volumes }}", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if out = strings.Trim(out, " \n\r"); out != "1" {
|
||||
t.Errorf("expect 1 volume received %s", out)
|
||||
c.Errorf("expect 1 volume received %s", out)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "inspect", "--format", "{{ .Volumes }}", cleanedContainerID)
|
||||
volumes, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(volumes, err)
|
||||
c.Fatal(volumes, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "restart", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "inspect", "--format", "{{ len .Volumes }}", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
if out = strings.Trim(out, " \n\r"); out != "1" {
|
||||
t.Errorf("expect 1 volume after restart received %s", out)
|
||||
c.Errorf("expect 1 volume after restart received %s", out)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "inspect", "--format", "{{ .Volumes }}", cleanedContainerID)
|
||||
volumesAfterRestart, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(volumesAfterRestart, err)
|
||||
c.Fatal(volumesAfterRestart, err)
|
||||
}
|
||||
|
||||
if volumes != volumesAfterRestart {
|
||||
volumes = strings.Trim(volumes, " \n\r")
|
||||
volumesAfterRestart = strings.Trim(volumesAfterRestart, " \n\r")
|
||||
t.Errorf("expected volume path: %s Actual path: %s", volumes, volumesAfterRestart)
|
||||
c.Errorf("expected volume path: %s Actual path: %s", volumes, volumesAfterRestart)
|
||||
}
|
||||
|
||||
logDone("restart - does not create a new volume on restart")
|
||||
}
|
||||
|
||||
func TestRestartPolicyNO(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRestartPolicyNO(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "-d", "--restart=no", "busybox", "false")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
id := strings.TrimSpace(string(out))
|
||||
name, err := inspectField(id, "HostConfig.RestartPolicy.Name")
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
if name != "no" {
|
||||
t.Fatalf("Container restart policy name is %s, expected %s", name, "no")
|
||||
c.Fatalf("Container restart policy name is %s, expected %s", name, "no")
|
||||
}
|
||||
|
||||
logDone("restart - recording restart policy name for --restart=no")
|
||||
}
|
||||
|
||||
func TestRestartPolicyAlways(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRestartPolicyAlways(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "-d", "--restart=always", "busybox", "false")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
id := strings.TrimSpace(string(out))
|
||||
name, err := inspectField(id, "HostConfig.RestartPolicy.Name")
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
if name != "always" {
|
||||
t.Fatalf("Container restart policy name is %s, expected %s", name, "always")
|
||||
c.Fatalf("Container restart policy name is %s, expected %s", name, "always")
|
||||
}
|
||||
|
||||
MaximumRetryCount, err := inspectField(id, "HostConfig.RestartPolicy.MaximumRetryCount")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// MaximumRetryCount=0 if the restart policy is always
|
||||
if MaximumRetryCount != "0" {
|
||||
t.Fatalf("Container Maximum Retry Count is %s, expected %s", MaximumRetryCount, "0")
|
||||
c.Fatalf("Container Maximum Retry Count is %s, expected %s", MaximumRetryCount, "0")
|
||||
}
|
||||
|
||||
logDone("restart - recording restart policy name for --restart=always")
|
||||
}
|
||||
|
||||
func TestRestartPolicyOnFailure(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRestartPolicyOnFailure(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "-d", "--restart=on-failure:1", "busybox", "false")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
id := strings.TrimSpace(string(out))
|
||||
name, err := inspectField(id, "HostConfig.RestartPolicy.Name")
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
if name != "on-failure" {
|
||||
t.Fatalf("Container restart policy name is %s, expected %s", name, "on-failure")
|
||||
c.Fatalf("Container restart policy name is %s, expected %s", name, "on-failure")
|
||||
}
|
||||
|
||||
logDone("restart - recording restart policy name for --restart=on-failure")
|
||||
}
|
||||
|
||||
// a good container with --restart=on-failure:3
|
||||
// MaximumRetryCount!=0; RestartCount=0
|
||||
func TestContainerRestartwithGoodContainer(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestContainerRestartwithGoodContainer(c *check.C) {
|
||||
out, err := exec.Command(dockerBinary, "run", "-d", "--restart=on-failure:3", "busybox", "true").CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatal(string(out), err)
|
||||
c.Fatal(string(out), err)
|
||||
}
|
||||
id := strings.TrimSpace(string(out))
|
||||
if err := waitInspect(id, "{{ .State.Restarting }} {{ .State.Running }}", "false false", 5); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
count, err := inspectField(id, "RestartCount")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if count != "0" {
|
||||
t.Fatalf("Container was restarted %s times, expected %d", count, 0)
|
||||
c.Fatalf("Container was restarted %s times, expected %d", count, 0)
|
||||
}
|
||||
MaximumRetryCount, err := inspectField(id, "HostConfig.RestartPolicy.MaximumRetryCount")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if MaximumRetryCount != "3" {
|
||||
t.Fatalf("Container Maximum Retry Count is %s, expected %s", MaximumRetryCount, "3")
|
||||
c.Fatalf("Container Maximum Retry Count is %s, expected %s", MaximumRetryCount, "3")
|
||||
}
|
||||
|
||||
logDone("restart - for a good container with restart policy, MaximumRetryCount is not 0 and RestartCount is 0")
|
||||
}
|
||||
|
|
|
@ -5,93 +5,83 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestRmContainerWithRemovedVolume(t *testing.T) {
|
||||
testRequires(t, SameHostDaemon)
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRmContainerWithRemovedVolume(c *check.C) {
|
||||
testRequires(c, SameHostDaemon)
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "--name", "losemyvolumes", "-v", "/tmp/testing:/test", "busybox", "true")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if err := os.Remove("/tmp/testing"); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "rm", "-v", "losemyvolumes")
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
logDone("rm - removed volume")
|
||||
}
|
||||
|
||||
func TestRmContainerWithVolume(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRmContainerWithVolume(c *check.C) {
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "--name", "foo", "-v", "/srv", "busybox", "true")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "rm", "-v", "foo")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
logDone("rm - volume")
|
||||
}
|
||||
|
||||
func TestRmRunningContainer(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRmRunningContainer(c *check.C) {
|
||||
|
||||
createRunningContainer(t, "foo")
|
||||
createRunningContainer(c, "foo")
|
||||
|
||||
// Test cannot remove running container
|
||||
cmd := exec.Command(dockerBinary, "rm", "foo")
|
||||
if _, err := runCommand(cmd); err == nil {
|
||||
t.Fatalf("Expected error, can't rm a running container")
|
||||
c.Fatalf("Expected error, can't rm a running container")
|
||||
}
|
||||
|
||||
logDone("rm - running container")
|
||||
}
|
||||
|
||||
func TestRmRunningContainerCheckError409(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRmRunningContainerCheckError409(c *check.C) {
|
||||
|
||||
createRunningContainer(t, "foo")
|
||||
createRunningContainer(c, "foo")
|
||||
|
||||
endpoint := "/containers/foo"
|
||||
status, _, err := sockRequest("DELETE", endpoint, nil)
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error, can't rm a running container")
|
||||
c.Fatalf("Expected error, can't rm a running container")
|
||||
} else if status != http.StatusConflict {
|
||||
t.Fatalf("Expected error to contain '409 Conflict' but found %s", err)
|
||||
c.Fatalf("Expected error to contain '409 Conflict' but found %s", err)
|
||||
}
|
||||
|
||||
logDone("rm - running container with Error 409")
|
||||
}
|
||||
|
||||
func TestRmForceRemoveRunningContainer(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRmForceRemoveRunningContainer(c *check.C) {
|
||||
|
||||
createRunningContainer(t, "foo")
|
||||
createRunningContainer(c, "foo")
|
||||
|
||||
// Stop then remove with -s
|
||||
cmd := exec.Command(dockerBinary, "rm", "-f", "foo")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
logDone("rm - running container with --force=true")
|
||||
}
|
||||
|
||||
func TestRmContainerOrphaning(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRmContainerOrphaning(c *check.C) {
|
||||
|
||||
dockerfile1 := `FROM busybox:latest
|
||||
ENTRYPOINT ["/bin/true"]`
|
||||
|
@ -104,45 +94,43 @@ func TestRmContainerOrphaning(t *testing.T) {
|
|||
img1, err := buildImage(img, dockerfile1, true)
|
||||
defer deleteImages(img1)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not build image %s: %v", img, err)
|
||||
c.Fatalf("Could not build image %s: %v", img, err)
|
||||
}
|
||||
// run container on first image
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", img)); err != nil {
|
||||
t.Fatalf("Could not run image %s: %v: %s", img, err, out)
|
||||
c.Fatalf("Could not run image %s: %v: %s", img, err, out)
|
||||
}
|
||||
// rebuild dockerfile with a small addition at the end
|
||||
if _, err := buildImage(img, dockerfile2, true); err != nil {
|
||||
t.Fatalf("Could not rebuild image %s: %v", img, err)
|
||||
c.Fatalf("Could not rebuild image %s: %v", img, err)
|
||||
}
|
||||
// try to remove the image, should error out.
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "rmi", img)); err == nil {
|
||||
t.Fatalf("Expected to error out removing the image, but succeeded: %s", out)
|
||||
c.Fatalf("Expected to error out removing the image, but succeeded: %s", out)
|
||||
}
|
||||
// check if we deleted the first image
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "images", "-q", "--no-trunc"))
|
||||
if err != nil {
|
||||
t.Fatalf("%v: %s", err, out)
|
||||
c.Fatalf("%v: %s", err, out)
|
||||
}
|
||||
if !strings.Contains(out, img1) {
|
||||
t.Fatalf("Orphaned container (could not find %q in docker images): %s", img1, out)
|
||||
c.Fatalf("Orphaned container (could not find %q in docker images): %s", img1, out)
|
||||
}
|
||||
|
||||
logDone("rm - container orphaning")
|
||||
}
|
||||
|
||||
func TestRmInvalidContainer(t *testing.T) {
|
||||
func (s *DockerSuite) TestRmInvalidContainer(c *check.C) {
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "rm", "unknown")); err == nil {
|
||||
t.Fatal("Expected error on rm unknown container, got none")
|
||||
c.Fatal("Expected error on rm unknown container, got none")
|
||||
} else if !strings.Contains(out, "failed to remove one or more containers") {
|
||||
t.Fatalf("Expected output to contain 'failed to remove one or more containers', got %q", out)
|
||||
c.Fatalf("Expected output to contain 'failed to remove one or more containers', got %q", out)
|
||||
}
|
||||
|
||||
logDone("rm - delete unknown container")
|
||||
}
|
||||
|
||||
func createRunningContainer(t *testing.T, name string) {
|
||||
func createRunningContainer(c *check.C, name string) {
|
||||
cmd := exec.Command(dockerBinary, "run", "-dt", "--name", name, "busybox", "top")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,17 +3,18 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestRmiWithContainerFails(t *testing.T) {
|
||||
func (s *DockerSuite) TestRmiWithContainerFails(c *check.C) {
|
||||
errSubstr := "is using it"
|
||||
|
||||
// create a container
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create a container: %s, %v", out, err)
|
||||
c.Fatalf("failed to create a container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -22,123 +23,117 @@ func TestRmiWithContainerFails(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "rmi", "busybox")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err == nil {
|
||||
t.Fatalf("Container %q is using image, should not be able to rmi: %q", cleanedContainerID, out)
|
||||
c.Fatalf("Container %q is using image, should not be able to rmi: %q", cleanedContainerID, out)
|
||||
}
|
||||
if !strings.Contains(out, errSubstr) {
|
||||
t.Fatalf("Container %q is using image, error message should contain %q: %v", cleanedContainerID, errSubstr, out)
|
||||
c.Fatalf("Container %q is using image, error message should contain %q: %v", cleanedContainerID, errSubstr, out)
|
||||
}
|
||||
|
||||
// make sure it didn't delete the busybox name
|
||||
images, _ := dockerCmd(t, "images")
|
||||
images, _ := dockerCmd(c, "images")
|
||||
if !strings.Contains(images, "busybox") {
|
||||
t.Fatalf("The name 'busybox' should not have been removed from images: %q", images)
|
||||
c.Fatalf("The name 'busybox' should not have been removed from images: %q", images)
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
|
||||
logDone("rmi - container using image while rmi, should not remove image name")
|
||||
}
|
||||
|
||||
func TestRmiTag(t *testing.T) {
|
||||
imagesBefore, _ := dockerCmd(t, "images", "-a")
|
||||
dockerCmd(t, "tag", "busybox", "utest:tag1")
|
||||
dockerCmd(t, "tag", "busybox", "utest/docker:tag2")
|
||||
dockerCmd(t, "tag", "busybox", "utest:5000/docker:tag3")
|
||||
func (s *DockerSuite) TestRmiTag(c *check.C) {
|
||||
imagesBefore, _ := dockerCmd(c, "images", "-a")
|
||||
dockerCmd(c, "tag", "busybox", "utest:tag1")
|
||||
dockerCmd(c, "tag", "busybox", "utest/docker:tag2")
|
||||
dockerCmd(c, "tag", "busybox", "utest:5000/docker:tag3")
|
||||
{
|
||||
imagesAfter, _ := dockerCmd(t, "images", "-a")
|
||||
imagesAfter, _ := dockerCmd(c, "images", "-a")
|
||||
if strings.Count(imagesAfter, "\n") != strings.Count(imagesBefore, "\n")+3 {
|
||||
t.Fatalf("before: %q\n\nafter: %q\n", imagesBefore, imagesAfter)
|
||||
c.Fatalf("before: %q\n\nafter: %q\n", imagesBefore, imagesAfter)
|
||||
}
|
||||
}
|
||||
dockerCmd(t, "rmi", "utest/docker:tag2")
|
||||
dockerCmd(c, "rmi", "utest/docker:tag2")
|
||||
{
|
||||
imagesAfter, _ := dockerCmd(t, "images", "-a")
|
||||
imagesAfter, _ := dockerCmd(c, "images", "-a")
|
||||
if strings.Count(imagesAfter, "\n") != strings.Count(imagesBefore, "\n")+2 {
|
||||
t.Fatalf("before: %q\n\nafter: %q\n", imagesBefore, imagesAfter)
|
||||
c.Fatalf("before: %q\n\nafter: %q\n", imagesBefore, imagesAfter)
|
||||
}
|
||||
|
||||
}
|
||||
dockerCmd(t, "rmi", "utest:5000/docker:tag3")
|
||||
dockerCmd(c, "rmi", "utest:5000/docker:tag3")
|
||||
{
|
||||
imagesAfter, _ := dockerCmd(t, "images", "-a")
|
||||
imagesAfter, _ := dockerCmd(c, "images", "-a")
|
||||
if strings.Count(imagesAfter, "\n") != strings.Count(imagesBefore, "\n")+1 {
|
||||
t.Fatalf("before: %q\n\nafter: %q\n", imagesBefore, imagesAfter)
|
||||
c.Fatalf("before: %q\n\nafter: %q\n", imagesBefore, imagesAfter)
|
||||
}
|
||||
|
||||
}
|
||||
dockerCmd(t, "rmi", "utest:tag1")
|
||||
dockerCmd(c, "rmi", "utest:tag1")
|
||||
{
|
||||
imagesAfter, _ := dockerCmd(t, "images", "-a")
|
||||
imagesAfter, _ := dockerCmd(c, "images", "-a")
|
||||
if strings.Count(imagesAfter, "\n") != strings.Count(imagesBefore, "\n")+0 {
|
||||
t.Fatalf("before: %q\n\nafter: %q\n", imagesBefore, imagesAfter)
|
||||
c.Fatalf("before: %q\n\nafter: %q\n", imagesBefore, imagesAfter)
|
||||
}
|
||||
|
||||
}
|
||||
logDone("rmi - tag,rmi - tagging the same images multiple times then removing tags")
|
||||
}
|
||||
|
||||
func TestRmiImgIDForce(t *testing.T) {
|
||||
func (s *DockerSuite) TestRmiImgIDForce(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir '/busybox-test'")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create a container:%s, %v", out, err)
|
||||
c.Fatalf("failed to create a container:%s, %v", out, err)
|
||||
}
|
||||
containerID := strings.TrimSpace(out)
|
||||
runCmd = exec.Command(dockerBinary, "commit", containerID, "busybox-test")
|
||||
out, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit a new busybox-test:%s, %v", out, err)
|
||||
c.Fatalf("failed to commit a new busybox-test:%s, %v", out, err)
|
||||
}
|
||||
|
||||
imagesBefore, _ := dockerCmd(t, "images", "-a")
|
||||
dockerCmd(t, "tag", "busybox-test", "utest:tag1")
|
||||
dockerCmd(t, "tag", "busybox-test", "utest:tag2")
|
||||
dockerCmd(t, "tag", "busybox-test", "utest/docker:tag3")
|
||||
dockerCmd(t, "tag", "busybox-test", "utest:5000/docker:tag4")
|
||||
imagesBefore, _ := dockerCmd(c, "images", "-a")
|
||||
dockerCmd(c, "tag", "busybox-test", "utest:tag1")
|
||||
dockerCmd(c, "tag", "busybox-test", "utest:tag2")
|
||||
dockerCmd(c, "tag", "busybox-test", "utest/docker:tag3")
|
||||
dockerCmd(c, "tag", "busybox-test", "utest:5000/docker:tag4")
|
||||
{
|
||||
imagesAfter, _ := dockerCmd(t, "images", "-a")
|
||||
imagesAfter, _ := dockerCmd(c, "images", "-a")
|
||||
if strings.Count(imagesAfter, "\n") != strings.Count(imagesBefore, "\n")+4 {
|
||||
t.Fatalf("tag busybox to create 4 more images with same imageID; docker images shows: %q\n", imagesAfter)
|
||||
c.Fatalf("tag busybox to create 4 more images with same imageID; docker images shows: %q\n", imagesAfter)
|
||||
}
|
||||
}
|
||||
out, _ = dockerCmd(t, "inspect", "-f", "{{.Id}}", "busybox-test")
|
||||
out, _ = dockerCmd(c, "inspect", "-f", "{{.Id}}", "busybox-test")
|
||||
imgID := strings.TrimSpace(out)
|
||||
dockerCmd(t, "rmi", "-f", imgID)
|
||||
dockerCmd(c, "rmi", "-f", imgID)
|
||||
{
|
||||
imagesAfter, _ := dockerCmd(t, "images", "-a")
|
||||
imagesAfter, _ := dockerCmd(c, "images", "-a")
|
||||
if strings.Contains(imagesAfter, imgID[:12]) {
|
||||
t.Fatalf("rmi -f %s failed, image still exists: %q\n\n", imgID, imagesAfter)
|
||||
c.Fatalf("rmi -f %s failed, image still exists: %q\n\n", imgID, imagesAfter)
|
||||
}
|
||||
|
||||
}
|
||||
logDone("rmi - imgID,rmi -f imgID delete all tagged repos of specific imgID")
|
||||
}
|
||||
|
||||
func TestRmiTagWithExistingContainers(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRmiTagWithExistingContainers(c *check.C) {
|
||||
|
||||
container := "test-delete-tag"
|
||||
newtag := "busybox:newtag"
|
||||
bb := "busybox:latest"
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "tag", bb, newtag)); err != nil {
|
||||
t.Fatalf("Could not tag busybox: %v: %s", err, out)
|
||||
c.Fatalf("Could not tag busybox: %v: %s", err, out)
|
||||
}
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", container, bb, "/bin/true")); err != nil {
|
||||
t.Fatalf("Could not run busybox: %v: %s", err, out)
|
||||
c.Fatalf("Could not run busybox: %v: %s", err, out)
|
||||
}
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "rmi", newtag))
|
||||
if err != nil {
|
||||
t.Fatalf("Could not remove tag %s: %v: %s", newtag, err, out)
|
||||
c.Fatalf("Could not remove tag %s: %v: %s", newtag, err, out)
|
||||
}
|
||||
if d := strings.Count(out, "Untagged: "); d != 1 {
|
||||
t.Fatalf("Expected 1 untagged entry got %d: %q", d, out)
|
||||
c.Fatalf("Expected 1 untagged entry got %d: %q", d, out)
|
||||
}
|
||||
|
||||
logDone("rmi - delete tag with existing containers")
|
||||
}
|
||||
|
||||
func TestRmiForceWithExistingContainers(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRmiForceWithExistingContainers(c *check.C) {
|
||||
|
||||
image := "busybox-clone"
|
||||
|
||||
|
@ -147,64 +142,60 @@ func TestRmiForceWithExistingContainers(t *testing.T) {
|
|||
MAINTAINER foo`)
|
||||
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
t.Fatalf("Could not build %s: %s, %v", image, out, err)
|
||||
c.Fatalf("Could not build %s: %s, %v", image, out, err)
|
||||
}
|
||||
|
||||
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "test-force-rmi", image, "/bin/true")); err != nil {
|
||||
t.Fatalf("Could not run container: %s, %v", out, err)
|
||||
c.Fatalf("Could not run container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "rmi", "-f", image))
|
||||
if err != nil {
|
||||
t.Fatalf("Could not remove image %s: %s, %v", image, out, err)
|
||||
c.Fatalf("Could not remove image %s: %s, %v", image, out, err)
|
||||
}
|
||||
|
||||
logDone("rmi - force delete with existing containers")
|
||||
}
|
||||
|
||||
func TestRmiWithMultipleRepositories(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRmiWithMultipleRepositories(c *check.C) {
|
||||
newRepo := "127.0.0.1:5000/busybox"
|
||||
oldRepo := "busybox"
|
||||
newTag := "busybox:test"
|
||||
cmd := exec.Command(dockerBinary, "tag", oldRepo, newRepo)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not tag busybox: %v: %s", err, out)
|
||||
c.Fatalf("Could not tag busybox: %v: %s", err, out)
|
||||
}
|
||||
cmd = exec.Command(dockerBinary, "run", "--name", "test", oldRepo, "touch", "/home/abcd")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run container: %v, output: %s", err, out)
|
||||
c.Fatalf("failed to run container: %v, output: %s", err, out)
|
||||
}
|
||||
cmd = exec.Command(dockerBinary, "commit", "test", newTag)
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit container: %v, output: %s", err, out)
|
||||
c.Fatalf("failed to commit container: %v, output: %s", err, out)
|
||||
}
|
||||
cmd = exec.Command(dockerBinary, "rmi", newTag)
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to remove image: %v, output: %s", err, out)
|
||||
c.Fatalf("failed to remove image: %v, output: %s", err, out)
|
||||
}
|
||||
if !strings.Contains(out, "Untagged: "+newTag) {
|
||||
t.Fatalf("Could not remove image %s: %s, %v", newTag, out, err)
|
||||
c.Fatalf("Could not remove image %s: %s, %v", newTag, out, err)
|
||||
}
|
||||
|
||||
logDone("rmi - delete a image which its dependency tagged to multiple repositories success")
|
||||
}
|
||||
|
||||
func TestRmiBlank(t *testing.T) {
|
||||
func (s *DockerSuite) TestRmiBlank(c *check.C) {
|
||||
// try to delete a blank image name
|
||||
runCmd := exec.Command(dockerBinary, "rmi", "")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Should have failed to delete '' image")
|
||||
c.Fatal("Should have failed to delete '' image")
|
||||
}
|
||||
|
||||
if strings.Contains(out, "No such image") {
|
||||
t.Fatalf("Wrong error message generated: %s", out)
|
||||
c.Fatalf("Wrong error message generated: %s", out)
|
||||
}
|
||||
logDone("rmi - blank image name")
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,22 +11,19 @@ import (
|
|||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
"github.com/go-check/check"
|
||||
"github.com/kr/pty"
|
||||
)
|
||||
|
||||
// #6509
|
||||
func TestRunRedirectStdout(t *testing.T) {
|
||||
|
||||
defer deleteAllContainers()
|
||||
|
||||
func (s *DockerSuite) TestRunRedirectStdout(c *check.C) {
|
||||
checkRedirect := func(command string) {
|
||||
_, tty, err := pty.Open()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not open pty: %v", err)
|
||||
c.Fatalf("Could not open pty: %v", err)
|
||||
}
|
||||
cmd := exec.Command("sh", "-c", command)
|
||||
cmd.Stdin = tty
|
||||
|
@ -34,35 +31,31 @@ func TestRunRedirectStdout(t *testing.T) {
|
|||
cmd.Stderr = tty
|
||||
ch := make(chan struct{})
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatalf("start err: %v", err)
|
||||
c.Fatalf("start err: %v", err)
|
||||
}
|
||||
go func() {
|
||||
if err := cmd.Wait(); err != nil {
|
||||
t.Fatalf("wait err=%v", err)
|
||||
c.Fatalf("wait err=%v", err)
|
||||
}
|
||||
close(ch)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Fatal("command timeout")
|
||||
c.Fatal("command timeout")
|
||||
case <-ch:
|
||||
}
|
||||
}
|
||||
|
||||
checkRedirect(dockerBinary + " run -i busybox cat /etc/passwd | grep -q root")
|
||||
checkRedirect(dockerBinary + " run busybox cat /etc/passwd | grep -q root")
|
||||
|
||||
logDone("run - redirect stdout")
|
||||
}
|
||||
|
||||
// Test recursive bind mount works by default
|
||||
func TestRunWithVolumesIsRecursive(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
|
||||
func (s *DockerSuite) TestRunWithVolumesIsRecursive(c *check.C) {
|
||||
tmpDir, err := ioutil.TempDir("", "docker_recursive_mount_test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
@ -70,68 +63,62 @@ func TestRunWithVolumesIsRecursive(t *testing.T) {
|
|||
// Create a temporary tmpfs mount.
|
||||
tmpfsDir := filepath.Join(tmpDir, "tmpfs")
|
||||
if err := os.MkdirAll(tmpfsDir, 0777); err != nil {
|
||||
t.Fatalf("failed to mkdir at %s - %s", tmpfsDir, err)
|
||||
c.Fatalf("failed to mkdir at %s - %s", tmpfsDir, err)
|
||||
}
|
||||
if err := mount.Mount("tmpfs", tmpfsDir, "tmpfs", ""); err != nil {
|
||||
t.Fatalf("failed to create a tmpfs mount at %s - %s", tmpfsDir, err)
|
||||
c.Fatalf("failed to create a tmpfs mount at %s - %s", tmpfsDir, err)
|
||||
}
|
||||
|
||||
f, err := ioutil.TempFile(tmpfsDir, "touch-me")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "--name", "test-data", "--volume", fmt.Sprintf("%s:/tmp:ro", tmpDir), "busybox:latest", "ls", "/tmp/tmpfs")
|
||||
out, stderr, exitCode, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil && exitCode != 0 {
|
||||
t.Fatal(out, stderr, err)
|
||||
c.Fatal(out, stderr, err)
|
||||
}
|
||||
if !strings.Contains(out, filepath.Base(f.Name())) {
|
||||
t.Fatal("Recursive bind mount test failed. Expected file not found")
|
||||
c.Fatal("Recursive bind mount test failed. Expected file not found")
|
||||
}
|
||||
|
||||
logDone("run - volumes are bind mounted recursively")
|
||||
}
|
||||
|
||||
func TestRunWithUlimits(t *testing.T) {
|
||||
testRequires(t, NativeExecDriver)
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRunWithUlimits(c *check.C) {
|
||||
testRequires(c, NativeExecDriver)
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name=testulimits", "--ulimit", "nofile=42", "busybox", "/bin/sh", "-c", "ulimit -n"))
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
ul := strings.TrimSpace(out)
|
||||
if ul != "42" {
|
||||
t.Fatalf("expected `ulimit -n` to be 42, got %s", ul)
|
||||
c.Fatalf("expected `ulimit -n` to be 42, got %s", ul)
|
||||
}
|
||||
|
||||
logDone("run - ulimits are set")
|
||||
}
|
||||
|
||||
func TestRunContainerWithCgroupParent(t *testing.T) {
|
||||
testRequires(t, NativeExecDriver)
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRunContainerWithCgroupParent(c *check.C) {
|
||||
testRequires(c, NativeExecDriver)
|
||||
|
||||
cgroupParent := "test"
|
||||
data, err := ioutil.ReadFile("/proc/self/cgroup")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read '/proc/self/cgroup - %v", err)
|
||||
c.Fatalf("failed to read '/proc/self/cgroup - %v", err)
|
||||
}
|
||||
selfCgroupPaths := parseCgroupPaths(string(data))
|
||||
selfCpuCgroup, found := selfCgroupPaths["memory"]
|
||||
if !found {
|
||||
t.Fatalf("unable to find self cpu cgroup path. CgroupsPath: %v", selfCgroupPaths)
|
||||
c.Fatalf("unable to find self cpu cgroup path. CgroupsPath: %v", selfCgroupPaths)
|
||||
}
|
||||
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--cgroup-parent", cgroupParent, "--rm", "busybox", "cat", "/proc/self/cgroup"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
|
||||
c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
|
||||
}
|
||||
cgroupPaths := parseCgroupPaths(string(out))
|
||||
if len(cgroupPaths) == 0 {
|
||||
t.Fatalf("unexpected output - %q", string(out))
|
||||
c.Fatalf("unexpected output - %q", string(out))
|
||||
}
|
||||
found = false
|
||||
expectedCgroupPrefix := path.Join(selfCpuCgroup, cgroupParent)
|
||||
|
@ -142,24 +129,22 @@ func TestRunContainerWithCgroupParent(t *testing.T) {
|
|||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("unexpected cgroup paths. Expected at least one cgroup path to have prefix %q. Cgroup Paths: %v", expectedCgroupPrefix, cgroupPaths)
|
||||
c.Fatalf("unexpected cgroup paths. Expected at least one cgroup path to have prefix %q. Cgroup Paths: %v", expectedCgroupPrefix, cgroupPaths)
|
||||
}
|
||||
logDone("run - cgroup parent")
|
||||
}
|
||||
|
||||
func TestRunContainerWithCgroupParentAbsPath(t *testing.T) {
|
||||
testRequires(t, NativeExecDriver)
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRunContainerWithCgroupParentAbsPath(c *check.C) {
|
||||
testRequires(c, NativeExecDriver)
|
||||
|
||||
cgroupParent := "/cgroup-parent/test"
|
||||
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--cgroup-parent", cgroupParent, "--rm", "busybox", "cat", "/proc/self/cgroup"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
|
||||
c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
|
||||
}
|
||||
cgroupPaths := parseCgroupPaths(string(out))
|
||||
if len(cgroupPaths) == 0 {
|
||||
t.Fatalf("unexpected output - %q", string(out))
|
||||
c.Fatalf("unexpected output - %q", string(out))
|
||||
}
|
||||
found := false
|
||||
for _, path := range cgroupPaths {
|
||||
|
@ -169,81 +154,75 @@ func TestRunContainerWithCgroupParentAbsPath(t *testing.T) {
|
|||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("unexpected cgroup paths. Expected at least one cgroup path to have prefix %q. Cgroup Paths: %v", cgroupParent, cgroupPaths)
|
||||
c.Fatalf("unexpected cgroup paths. Expected at least one cgroup path to have prefix %q. Cgroup Paths: %v", cgroupParent, cgroupPaths)
|
||||
}
|
||||
|
||||
logDone("run - cgroup parent with absolute cgroup path")
|
||||
}
|
||||
|
||||
func TestRunDeviceDirectory(t *testing.T) {
|
||||
testRequires(t, NativeExecDriver)
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRunDeviceDirectory(c *check.C) {
|
||||
testRequires(c, NativeExecDriver)
|
||||
cmd := exec.Command(dockerBinary, "run", "--device", "/dev/snd:/dev/snd", "busybox", "sh", "-c", "ls /dev/snd/")
|
||||
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
if actual := strings.Trim(out, "\r\n"); !strings.Contains(out, "timer") {
|
||||
t.Fatalf("expected output /dev/snd/timer, received %s", actual)
|
||||
c.Fatalf("expected output /dev/snd/timer, received %s", actual)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "run", "--device", "/dev/snd:/dev/othersnd", "busybox", "sh", "-c", "ls /dev/othersnd/")
|
||||
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
if actual := strings.Trim(out, "\r\n"); !strings.Contains(out, "seq") {
|
||||
t.Fatalf("expected output /dev/othersnd/seq, received %s", actual)
|
||||
c.Fatalf("expected output /dev/othersnd/seq, received %s", actual)
|
||||
}
|
||||
|
||||
logDone("run - test --device directory mounts all internal devices")
|
||||
}
|
||||
|
||||
// TestRunDetach checks attaching and detaching with the escape sequence.
|
||||
func TestRunAttachDetach(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestRunAttachDetach(c *check.C) {
|
||||
name := "attach-detach"
|
||||
cmd := exec.Command(dockerBinary, "run", "--name", name, "-it", "busybox", "cat")
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
cpty, tty, err := pty.Open()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer cpty.Close()
|
||||
cmd.Stdin = tty
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if err := waitRun(name); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := cpty.Write([]byte("hello\n")); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
out, err := bufio.NewReader(stdout).ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if strings.TrimSpace(out) != "hello" {
|
||||
t.Fatalf("exepected 'hello', got %q", out)
|
||||
c.Fatalf("exepected 'hello', got %q", out)
|
||||
}
|
||||
|
||||
// escape sequence
|
||||
if _, err := cpty.Write([]byte{16}); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
if _, err := cpty.Write([]byte{17}); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
ch := make(chan struct{})
|
||||
|
@ -254,21 +233,19 @@ func TestRunAttachDetach(t *testing.T) {
|
|||
|
||||
running, err := inspectField(name, "State.Running")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
if running != "true" {
|
||||
t.Fatal("exepected container to still be running")
|
||||
c.Fatal("exepected container to still be running")
|
||||
}
|
||||
|
||||
go func() {
|
||||
dockerCmd(t, "kill", name)
|
||||
exec.Command(dockerBinary, "kill", name).Run()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ch:
|
||||
case <-time.After(10 * time.Millisecond):
|
||||
t.Fatal("timed out waiting for container to exit")
|
||||
c.Fatal("timed out waiting for container to exit")
|
||||
}
|
||||
|
||||
logDone("run - attach detach")
|
||||
}
|
||||
|
|
|
@ -9,15 +9,16 @@ import (
|
|||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// save a repo using gz compression and try to load it using stdout
|
||||
func TestSaveXzAndLoadRepoStdout(t *testing.T) {
|
||||
func (s *DockerSuite) TestSaveXzAndLoadRepoStdout(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create a container: %v %v", out, err)
|
||||
c.Fatalf("failed to create a container: %v %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -27,19 +28,19 @@ func TestSaveXzAndLoadRepoStdout(t *testing.T) {
|
|||
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("output should've been a container id: %v %v", cleanedContainerID, err)
|
||||
c.Fatalf("output should've been a container id: %v %v", cleanedContainerID, err)
|
||||
}
|
||||
|
||||
commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, repoName)
|
||||
out, _, err = runCommandWithOutput(commitCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit container: %v %v", out, err)
|
||||
c.Fatalf("failed to commit container: %v %v", out, err)
|
||||
}
|
||||
|
||||
inspectCmd = exec.Command(dockerBinary, "inspect", repoName)
|
||||
before, _, err := runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("the repo should exist before saving it: %v %v", before, err)
|
||||
c.Fatalf("the repo should exist before saving it: %v %v", before, err)
|
||||
}
|
||||
|
||||
repoTarball, _, err := runCommandPipelineWithOutput(
|
||||
|
@ -47,7 +48,7 @@ func TestSaveXzAndLoadRepoStdout(t *testing.T) {
|
|||
exec.Command("xz", "-c"),
|
||||
exec.Command("gzip", "-c"))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to save repo: %v %v", out, err)
|
||||
c.Fatalf("failed to save repo: %v %v", out, err)
|
||||
}
|
||||
deleteImages(repoName)
|
||||
|
||||
|
@ -55,26 +56,25 @@ func TestSaveXzAndLoadRepoStdout(t *testing.T) {
|
|||
loadCmd.Stdin = strings.NewReader(repoTarball)
|
||||
out, _, err = runCommandWithOutput(loadCmd)
|
||||
if err == nil {
|
||||
t.Fatalf("expected error, but succeeded with no error and output: %v", out)
|
||||
c.Fatalf("expected error, but succeeded with no error and output: %v", out)
|
||||
}
|
||||
|
||||
inspectCmd = exec.Command(dockerBinary, "inspect", repoName)
|
||||
after, _, err := runCommandWithOutput(inspectCmd)
|
||||
if err == nil {
|
||||
t.Fatalf("the repo should not exist: %v", after)
|
||||
c.Fatalf("the repo should not exist: %v", after)
|
||||
}
|
||||
|
||||
deleteImages(repoName)
|
||||
|
||||
logDone("load - save a repo with xz compression & load it using stdout")
|
||||
}
|
||||
|
||||
// save a repo using xz+gz compression and try to load it using stdout
|
||||
func TestSaveXzGzAndLoadRepoStdout(t *testing.T) {
|
||||
func (s *DockerSuite) TestSaveXzGzAndLoadRepoStdout(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create a container: %v %v", out, err)
|
||||
c.Fatalf("failed to create a container: %v %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -84,19 +84,19 @@ func TestSaveXzGzAndLoadRepoStdout(t *testing.T) {
|
|||
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
|
||||
out, _, err = runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("output should've been a container id: %v %v", cleanedContainerID, err)
|
||||
c.Fatalf("output should've been a container id: %v %v", cleanedContainerID, err)
|
||||
}
|
||||
|
||||
commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, repoName)
|
||||
out, _, err = runCommandWithOutput(commitCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit container: %v %v", out, err)
|
||||
c.Fatalf("failed to commit container: %v %v", out, err)
|
||||
}
|
||||
|
||||
inspectCmd = exec.Command(dockerBinary, "inspect", repoName)
|
||||
before, _, err := runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("the repo should exist before saving it: %v %v", before, err)
|
||||
c.Fatalf("the repo should exist before saving it: %v %v", before, err)
|
||||
}
|
||||
|
||||
out, _, err = runCommandPipelineWithOutput(
|
||||
|
@ -104,7 +104,7 @@ func TestSaveXzGzAndLoadRepoStdout(t *testing.T) {
|
|||
exec.Command("xz", "-c"),
|
||||
exec.Command("gzip", "-c"))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to save repo: %v %v", out, err)
|
||||
c.Fatalf("failed to save repo: %v %v", out, err)
|
||||
}
|
||||
|
||||
deleteImages(repoName)
|
||||
|
@ -113,34 +113,33 @@ func TestSaveXzGzAndLoadRepoStdout(t *testing.T) {
|
|||
loadCmd.Stdin = strings.NewReader(out)
|
||||
out, _, err = runCommandWithOutput(loadCmd)
|
||||
if err == nil {
|
||||
t.Fatalf("expected error, but succeeded with no error and output: %v", out)
|
||||
c.Fatalf("expected error, but succeeded with no error and output: %v", out)
|
||||
}
|
||||
|
||||
inspectCmd = exec.Command(dockerBinary, "inspect", repoName)
|
||||
after, _, err := runCommandWithOutput(inspectCmd)
|
||||
if err == nil {
|
||||
t.Fatalf("the repo should not exist: %v", after)
|
||||
c.Fatalf("the repo should not exist: %v", after)
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
deleteImages(repoName)
|
||||
|
||||
logDone("load - save a repo with xz+gz compression & load it using stdout")
|
||||
}
|
||||
|
||||
func TestSaveSingleTag(t *testing.T) {
|
||||
func (s *DockerSuite) TestSaveSingleTag(c *check.C) {
|
||||
repoName := "foobar-save-single-tag-test"
|
||||
|
||||
tagCmd := exec.Command(dockerBinary, "tag", "busybox:latest", fmt.Sprintf("%v:latest", repoName))
|
||||
defer deleteImages(repoName)
|
||||
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
|
||||
t.Fatalf("failed to tag repo: %s, %v", out, err)
|
||||
c.Fatalf("failed to tag repo: %s, %v", out, err)
|
||||
}
|
||||
|
||||
idCmd := exec.Command(dockerBinary, "images", "-q", "--no-trunc", repoName)
|
||||
out, _, err := runCommandWithOutput(idCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get repo ID: %s, %v", out, err)
|
||||
c.Fatalf("failed to get repo ID: %s, %v", out, err)
|
||||
}
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
|
||||
|
@ -149,25 +148,24 @@ func TestSaveSingleTag(t *testing.T) {
|
|||
exec.Command("tar", "t"),
|
||||
exec.Command("grep", "-E", fmt.Sprintf("(^repositories$|%v)", cleanedImageID)))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to save repo with image ID and 'repositories' file: %s, %v", out, err)
|
||||
c.Fatalf("failed to save repo with image ID and 'repositories' file: %s, %v", out, err)
|
||||
}
|
||||
|
||||
logDone("save - save a specific image:tag")
|
||||
}
|
||||
|
||||
func TestSaveImageId(t *testing.T) {
|
||||
func (s *DockerSuite) TestSaveImageId(c *check.C) {
|
||||
repoName := "foobar-save-image-id-test"
|
||||
|
||||
tagCmd := exec.Command(dockerBinary, "tag", "emptyfs:latest", fmt.Sprintf("%v:latest", repoName))
|
||||
defer deleteImages(repoName)
|
||||
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
|
||||
t.Fatalf("failed to tag repo: %s, %v", out, err)
|
||||
c.Fatalf("failed to tag repo: %s, %v", out, err)
|
||||
}
|
||||
|
||||
idLongCmd := exec.Command(dockerBinary, "images", "-q", "--no-trunc", repoName)
|
||||
out, _, err := runCommandWithOutput(idLongCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get repo ID: %s, %v", out, err)
|
||||
c.Fatalf("failed to get repo ID: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedLongImageID := strings.TrimSpace(out)
|
||||
|
@ -175,7 +173,7 @@ func TestSaveImageId(t *testing.T) {
|
|||
idShortCmd := exec.Command(dockerBinary, "images", "-q", repoName)
|
||||
out, _, err = runCommandWithOutput(idShortCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get repo short ID: %s, %v", out, err)
|
||||
c.Fatalf("failed to get repo short ID: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedShortImageID := strings.TrimSpace(out)
|
||||
|
@ -184,19 +182,19 @@ func TestSaveImageId(t *testing.T) {
|
|||
tarCmd := exec.Command("tar", "t")
|
||||
tarCmd.Stdin, err = saveCmd.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatalf("cannot set stdout pipe for tar: %v", err)
|
||||
c.Fatalf("cannot set stdout pipe for tar: %v", err)
|
||||
}
|
||||
grepCmd := exec.Command("grep", cleanedLongImageID)
|
||||
grepCmd.Stdin, err = tarCmd.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatalf("cannot set stdout pipe for grep: %v", err)
|
||||
c.Fatalf("cannot set stdout pipe for grep: %v", err)
|
||||
}
|
||||
|
||||
if err = tarCmd.Start(); err != nil {
|
||||
t.Fatalf("tar failed with error: %v", err)
|
||||
c.Fatalf("tar failed with error: %v", err)
|
||||
}
|
||||
if err = saveCmd.Start(); err != nil {
|
||||
t.Fatalf("docker save failed with error: %v", err)
|
||||
c.Fatalf("docker save failed with error: %v", err)
|
||||
}
|
||||
defer saveCmd.Wait()
|
||||
defer tarCmd.Wait()
|
||||
|
@ -204,18 +202,17 @@ func TestSaveImageId(t *testing.T) {
|
|||
out, _, err = runCommandWithOutput(grepCmd)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("failed to save repo with image ID: %s, %v", out, err)
|
||||
c.Fatalf("failed to save repo with image ID: %s, %v", out, err)
|
||||
}
|
||||
|
||||
logDone("save - save a image by ID")
|
||||
}
|
||||
|
||||
// save a repo and try to load it using flags
|
||||
func TestSaveAndLoadRepoFlags(t *testing.T) {
|
||||
func (s *DockerSuite) TestSaveAndLoadRepoFlags(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create a container: %s, %v", out, err)
|
||||
c.Fatalf("failed to create a container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -225,19 +222,19 @@ func TestSaveAndLoadRepoFlags(t *testing.T) {
|
|||
|
||||
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
|
||||
t.Fatalf("output should've been a container id: %s, %v", out, err)
|
||||
c.Fatalf("output should've been a container id: %s, %v", out, err)
|
||||
}
|
||||
|
||||
commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, repoName)
|
||||
deleteImages(repoName)
|
||||
if out, _, err = runCommandWithOutput(commitCmd); err != nil {
|
||||
t.Fatalf("failed to commit container: %s, %v", out, err)
|
||||
c.Fatalf("failed to commit container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
inspectCmd = exec.Command(dockerBinary, "inspect", repoName)
|
||||
before, _, err := runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("the repo should exist before saving it: %s, %v", before, err)
|
||||
c.Fatalf("the repo should exist before saving it: %s, %v", before, err)
|
||||
|
||||
}
|
||||
|
||||
|
@ -245,29 +242,28 @@ func TestSaveAndLoadRepoFlags(t *testing.T) {
|
|||
exec.Command(dockerBinary, "save", repoName),
|
||||
exec.Command(dockerBinary, "load"))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to save and load repo: %s, %v", out, err)
|
||||
c.Fatalf("failed to save and load repo: %s, %v", out, err)
|
||||
}
|
||||
|
||||
inspectCmd = exec.Command(dockerBinary, "inspect", repoName)
|
||||
after, _, err := runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("the repo should exist after loading it: %s, %v", after, err)
|
||||
c.Fatalf("the repo should exist after loading it: %s, %v", after, err)
|
||||
}
|
||||
|
||||
if before != after {
|
||||
t.Fatalf("inspect is not the same after a save / load")
|
||||
c.Fatalf("inspect is not the same after a save / load")
|
||||
}
|
||||
|
||||
logDone("save - save a repo using -o && load a repo using -i")
|
||||
}
|
||||
|
||||
func TestSaveMultipleNames(t *testing.T) {
|
||||
func (s *DockerSuite) TestSaveMultipleNames(c *check.C) {
|
||||
repoName := "foobar-save-multi-name-test"
|
||||
|
||||
// Make one image
|
||||
tagCmd := exec.Command(dockerBinary, "tag", "emptyfs:latest", fmt.Sprintf("%v-one:latest", repoName))
|
||||
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
|
||||
t.Fatalf("failed to tag repo: %s, %v", out, err)
|
||||
c.Fatalf("failed to tag repo: %s, %v", out, err)
|
||||
}
|
||||
defer deleteImages(repoName + "-one")
|
||||
|
||||
|
@ -275,7 +271,7 @@ func TestSaveMultipleNames(t *testing.T) {
|
|||
tagCmd = exec.Command(dockerBinary, "tag", "emptyfs:latest", fmt.Sprintf("%v-two:latest", repoName))
|
||||
out, _, err := runCommandWithOutput(tagCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to tag repo: %s, %v", out, err)
|
||||
c.Fatalf("failed to tag repo: %s, %v", out, err)
|
||||
}
|
||||
defer deleteImages(repoName + "-two")
|
||||
|
||||
|
@ -285,13 +281,12 @@ func TestSaveMultipleNames(t *testing.T) {
|
|||
exec.Command("grep", "-q", "-E", "(-one|-two)"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to save multiple repos: %s, %v", out, err)
|
||||
c.Fatalf("failed to save multiple repos: %s, %v", out, err)
|
||||
}
|
||||
|
||||
logDone("save - save by multiple names")
|
||||
}
|
||||
|
||||
func TestSaveRepoWithMultipleImages(t *testing.T) {
|
||||
func (s *DockerSuite) TestSaveRepoWithMultipleImages(c *check.C) {
|
||||
|
||||
makeImage := func(from string, tag string) string {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", from, "true")
|
||||
|
@ -300,14 +295,14 @@ func TestSaveRepoWithMultipleImages(t *testing.T) {
|
|||
err error
|
||||
)
|
||||
if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatalf("failed to create a container: %v %v", out, err)
|
||||
c.Fatalf("failed to create a container: %v %v", out, err)
|
||||
}
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
defer deleteContainer(cleanedContainerID)
|
||||
|
||||
commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, tag)
|
||||
if out, _, err = runCommandWithOutput(commitCmd); err != nil {
|
||||
t.Fatalf("failed to commit container: %v %v", out, err)
|
||||
c.Fatalf("failed to commit container: %v %v", out, err)
|
||||
}
|
||||
imageID := strings.TrimSpace(out)
|
||||
return imageID
|
||||
|
@ -331,14 +326,14 @@ func TestSaveRepoWithMultipleImages(t *testing.T) {
|
|||
exec.Command("grep", "VERSION"),
|
||||
exec.Command("cut", "-d", "/", "-f1"))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to save multiple images: %s, %v", out, err)
|
||||
c.Fatalf("failed to save multiple images: %s, %v", out, err)
|
||||
}
|
||||
actual := strings.Split(strings.TrimSpace(out), "\n")
|
||||
|
||||
// make the list of expected layers
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "history", "-q", "--no-trunc", "busybox:latest"))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get history: %s, %v", out, err)
|
||||
c.Fatalf("failed to get history: %s, %v", out, err)
|
||||
}
|
||||
|
||||
expected := append(strings.Split(strings.TrimSpace(out), "\n"), idFoo, idBar)
|
||||
|
@ -346,21 +341,20 @@ func TestSaveRepoWithMultipleImages(t *testing.T) {
|
|||
sort.Strings(actual)
|
||||
sort.Strings(expected)
|
||||
if !reflect.DeepEqual(expected, actual) {
|
||||
t.Fatalf("achive does not contains the right layers: got %v, expected %v", actual, expected)
|
||||
c.Fatalf("achive does not contains the right layers: got %v, expected %v", actual, expected)
|
||||
}
|
||||
|
||||
logDone("save - save repository with multiple images")
|
||||
}
|
||||
|
||||
// Issue #6722 #5892 ensure directories are included in changes
|
||||
func TestSaveDirectoryPermissions(t *testing.T) {
|
||||
func (s *DockerSuite) TestSaveDirectoryPermissions(c *check.C) {
|
||||
layerEntries := []string{"opt/", "opt/a/", "opt/a/b/", "opt/a/b/c"}
|
||||
layerEntriesAUFS := []string{"./", ".wh..wh.aufs", ".wh..wh.orph/", ".wh..wh.plnk/", "opt/", "opt/a/", "opt/a/b/", "opt/a/b/c"}
|
||||
|
||||
name := "save-directory-permissions"
|
||||
tmpDir, err := ioutil.TempDir("", "save-layers-with-directories")
|
||||
if err != nil {
|
||||
t.Errorf("failed to create temporary directory: %s", err)
|
||||
c.Errorf("failed to create temporary directory: %s", err)
|
||||
}
|
||||
extractionDirectory := filepath.Join(tmpDir, "image-extraction-dir")
|
||||
os.Mkdir(extractionDirectory, 0777)
|
||||
|
@ -373,19 +367,19 @@ func TestSaveDirectoryPermissions(t *testing.T) {
|
|||
RUN touch /opt/a/b/c && chown user:user /opt/a/b/c`,
|
||||
true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
if out, _, err := runCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", name),
|
||||
exec.Command("tar", "-xf", "-", "-C", extractionDirectory),
|
||||
); err != nil {
|
||||
t.Errorf("failed to save and extract image: %s", out)
|
||||
c.Errorf("failed to save and extract image: %s", out)
|
||||
}
|
||||
|
||||
dirs, err := ioutil.ReadDir(extractionDirectory)
|
||||
if err != nil {
|
||||
t.Errorf("failed to get a listing of the layer directories: %s", err)
|
||||
c.Errorf("failed to get a listing of the layer directories: %s", err)
|
||||
}
|
||||
|
||||
found := false
|
||||
|
@ -396,7 +390,7 @@ func TestSaveDirectoryPermissions(t *testing.T) {
|
|||
|
||||
f, err := os.Open(layerPath)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open %s: %s", layerPath, err)
|
||||
c.Fatalf("failed to open %s: %s", layerPath, err)
|
||||
}
|
||||
|
||||
entries, err := ListTar(f)
|
||||
|
@ -406,7 +400,7 @@ func TestSaveDirectoryPermissions(t *testing.T) {
|
|||
}
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("encountered error while listing tar entries: %s", err)
|
||||
c.Fatalf("encountered error while listing tar entries: %s", err)
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(entriesSansDev, layerEntries) || reflect.DeepEqual(entriesSansDev, layerEntriesAUFS) {
|
||||
|
@ -417,8 +411,7 @@ func TestSaveDirectoryPermissions(t *testing.T) {
|
|||
}
|
||||
|
||||
if !found {
|
||||
t.Fatalf("failed to find the layer with the right content listing")
|
||||
c.Fatalf("failed to find the layer with the right content listing")
|
||||
}
|
||||
|
||||
logDone("save - ensure directories exist in exported layers")
|
||||
}
|
||||
|
|
|
@ -8,17 +8,17 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/vendor/src/github.com/kr/pty"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// save a repo and try to load it using stdout
|
||||
func TestSaveAndLoadRepoStdout(t *testing.T) {
|
||||
func (s *DockerSuite) TestSaveAndLoadRepoStdout(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create a container: %s, %v", out, err)
|
||||
c.Fatalf("failed to create a container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -27,25 +27,25 @@ func TestSaveAndLoadRepoStdout(t *testing.T) {
|
|||
|
||||
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
|
||||
t.Fatalf("output should've been a container id: %s, %v", out, err)
|
||||
c.Fatalf("output should've been a container id: %s, %v", out, err)
|
||||
}
|
||||
|
||||
commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, repoName)
|
||||
if out, _, err = runCommandWithOutput(commitCmd); err != nil {
|
||||
t.Fatalf("failed to commit container: %s, %v", out, err)
|
||||
c.Fatalf("failed to commit container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
inspectCmd = exec.Command(dockerBinary, "inspect", repoName)
|
||||
before, _, err := runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("the repo should exist before saving it: %s, %v", before, err)
|
||||
c.Fatalf("the repo should exist before saving it: %s, %v", before, err)
|
||||
}
|
||||
|
||||
saveCmdTemplate := `%v save %v > /tmp/foobar-save-load-test.tar`
|
||||
saveCmdFinal := fmt.Sprintf(saveCmdTemplate, dockerBinary, repoName)
|
||||
saveCmd := exec.Command("bash", "-c", saveCmdFinal)
|
||||
if out, _, err = runCommandWithOutput(saveCmd); err != nil {
|
||||
t.Fatalf("failed to save repo: %s, %v", out, err)
|
||||
c.Fatalf("failed to save repo: %s, %v", out, err)
|
||||
}
|
||||
|
||||
deleteImages(repoName)
|
||||
|
@ -53,17 +53,17 @@ func TestSaveAndLoadRepoStdout(t *testing.T) {
|
|||
loadCmdFinal := `cat /tmp/foobar-save-load-test.tar | docker load`
|
||||
loadCmd := exec.Command("bash", "-c", loadCmdFinal)
|
||||
if out, _, err = runCommandWithOutput(loadCmd); err != nil {
|
||||
t.Fatalf("failed to load repo: %s, %v", out, err)
|
||||
c.Fatalf("failed to load repo: %s, %v", out, err)
|
||||
}
|
||||
|
||||
inspectCmd = exec.Command(dockerBinary, "inspect", repoName)
|
||||
after, _, err := runCommandWithOutput(inspectCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("the repo should exist after loading it: %s %v", after, err)
|
||||
c.Fatalf("the repo should exist after loading it: %s %v", after, err)
|
||||
}
|
||||
|
||||
if before != after {
|
||||
t.Fatalf("inspect is not the same after a save / load")
|
||||
c.Fatalf("inspect is not the same after a save / load")
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
|
@ -73,29 +73,28 @@ func TestSaveAndLoadRepoStdout(t *testing.T) {
|
|||
|
||||
pty, tty, err := pty.Open()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not open pty: %v", err)
|
||||
c.Fatalf("Could not open pty: %v", err)
|
||||
}
|
||||
cmd := exec.Command(dockerBinary, "save", repoName)
|
||||
cmd.Stdin = tty
|
||||
cmd.Stdout = tty
|
||||
cmd.Stderr = tty
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatalf("start err: %v", err)
|
||||
c.Fatalf("start err: %v", err)
|
||||
}
|
||||
if err := cmd.Wait(); err == nil {
|
||||
t.Fatal("did not break writing to a TTY")
|
||||
c.Fatal("did not break writing to a TTY")
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
|
||||
n, err := pty.Read(buf)
|
||||
if err != nil {
|
||||
t.Fatal("could not read tty output")
|
||||
c.Fatal("could not read tty output")
|
||||
}
|
||||
|
||||
if !bytes.Contains(buf[:n], []byte("Cowardly refusing")) {
|
||||
t.Fatal("help output is not being yielded", out)
|
||||
c.Fatal("help output is not being yielded", out)
|
||||
}
|
||||
|
||||
logDone("save - save/load a repo using stdout")
|
||||
}
|
||||
|
|
|
@ -3,95 +3,93 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// search for repos named "registry" on the central registry
|
||||
func TestSearchOnCentralRegistry(t *testing.T) {
|
||||
testRequires(t, Network)
|
||||
func (s *DockerSuite) TestSearchOnCentralRegistry(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
searchCmd := exec.Command(dockerBinary, "search", "busybox")
|
||||
out, exitCode, err := runCommandWithOutput(searchCmd)
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Fatalf("failed to search on the central registry: %s, %v", out, err)
|
||||
c.Fatalf("failed to search on the central registry: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if !strings.Contains(out, "Busybox base image.") {
|
||||
t.Fatal("couldn't find any repository named (or containing) 'Busybox base image.'")
|
||||
c.Fatal("couldn't find any repository named (or containing) 'Busybox base image.'")
|
||||
}
|
||||
|
||||
logDone("search - search for repositories named (or containing) 'Busybox base image.'")
|
||||
}
|
||||
|
||||
func TestSearchStarsOptionWithWrongParameter(t *testing.T) {
|
||||
func (s *DockerSuite) TestSearchStarsOptionWithWrongParameter(c *check.C) {
|
||||
searchCmdStarsChars := exec.Command(dockerBinary, "search", "--stars=a", "busybox")
|
||||
out, exitCode, err := runCommandWithOutput(searchCmdStarsChars)
|
||||
if err == nil || exitCode == 0 {
|
||||
t.Fatalf("Should not get right information: %s, %v", out, err)
|
||||
c.Fatalf("Should not get right information: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if !strings.Contains(out, "invalid value") {
|
||||
t.Fatal("couldn't find the invalid value warning")
|
||||
c.Fatal("couldn't find the invalid value warning")
|
||||
}
|
||||
|
||||
searchCmdStarsNegativeNumber := exec.Command(dockerBinary, "search", "-s=-1", "busybox")
|
||||
out, exitCode, err = runCommandWithOutput(searchCmdStarsNegativeNumber)
|
||||
if err == nil || exitCode == 0 {
|
||||
t.Fatalf("Should not get right information: %s, %v", out, err)
|
||||
c.Fatalf("Should not get right information: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if !strings.Contains(out, "invalid value") {
|
||||
t.Fatal("couldn't find the invalid value warning")
|
||||
c.Fatal("couldn't find the invalid value warning")
|
||||
}
|
||||
|
||||
logDone("search - Verify search with wrong parameter.")
|
||||
}
|
||||
|
||||
func TestSearchCmdOptions(t *testing.T) {
|
||||
testRequires(t, Network)
|
||||
func (s *DockerSuite) TestSearchCmdOptions(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
searchCmdhelp := exec.Command(dockerBinary, "search", "--help")
|
||||
out, exitCode, err := runCommandWithOutput(searchCmdhelp)
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Fatalf("failed to get search help information: %s, %v", out, err)
|
||||
c.Fatalf("failed to get search help information: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if !strings.Contains(out, "Usage: docker search [OPTIONS] TERM") {
|
||||
t.Fatalf("failed to show docker search usage: %s, %v", out, err)
|
||||
c.Fatalf("failed to show docker search usage: %s, %v", out, err)
|
||||
}
|
||||
|
||||
searchCmd := exec.Command(dockerBinary, "search", "busybox")
|
||||
outSearchCmd, exitCode, err := runCommandWithOutput(searchCmd)
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Fatalf("failed to search on the central registry: %s, %v", outSearchCmd, err)
|
||||
c.Fatalf("failed to search on the central registry: %s, %v", outSearchCmd, err)
|
||||
}
|
||||
|
||||
searchCmdautomated := exec.Command(dockerBinary, "search", "--automated=true", "busybox")
|
||||
outSearchCmdautomated, exitCode, err := runCommandWithOutput(searchCmdautomated) //The busybox is a busybox base image, not an AUTOMATED image.
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Fatalf("failed to search with automated=true on the central registry: %s, %v", outSearchCmdautomated, err)
|
||||
c.Fatalf("failed to search with automated=true on the central registry: %s, %v", outSearchCmdautomated, err)
|
||||
}
|
||||
|
||||
outSearchCmdautomatedSlice := strings.Split(outSearchCmdautomated, "\n")
|
||||
for i := range outSearchCmdautomatedSlice {
|
||||
if strings.HasPrefix(outSearchCmdautomatedSlice[i], "busybox ") {
|
||||
t.Fatalf("The busybox is not an AUTOMATED image: %s, %v", out, err)
|
||||
c.Fatalf("The busybox is not an AUTOMATED image: %s, %v", out, err)
|
||||
}
|
||||
}
|
||||
|
||||
searchCmdStars := exec.Command(dockerBinary, "search", "-s=2", "busybox")
|
||||
outSearchCmdStars, exitCode, err := runCommandWithOutput(searchCmdStars)
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Fatalf("failed to search with stars=2 on the central registry: %s, %v", outSearchCmdStars, err)
|
||||
c.Fatalf("failed to search with stars=2 on the central registry: %s, %v", outSearchCmdStars, err)
|
||||
}
|
||||
|
||||
if strings.Count(outSearchCmdStars, "[OK]") > strings.Count(outSearchCmd, "[OK]") {
|
||||
t.Fatalf("The quantity of images with stars should be less than that of all images: %s, %v", outSearchCmdStars, err)
|
||||
c.Fatalf("The quantity of images with stars should be less than that of all images: %s, %v", outSearchCmdStars, err)
|
||||
}
|
||||
|
||||
searchCmdOptions := exec.Command(dockerBinary, "search", "--stars=2", "--automated=true", "--no-trunc=true", "busybox")
|
||||
out, exitCode, err = runCommandWithOutput(searchCmdOptions)
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Fatalf("failed to search with stars&automated&no-trunc options on the central registry: %s, %v", out, err)
|
||||
c.Fatalf("failed to search with stars&automated&no-trunc options on the central registry: %s, %v", out, err)
|
||||
}
|
||||
|
||||
logDone("search - have a try for search options.")
|
||||
}
|
||||
|
|
|
@ -4,20 +4,20 @@ import (
|
|||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// Regression test for https://github.com/docker/docker/issues/7843
|
||||
func TestStartAttachReturnsOnError(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestStartAttachReturnsOnError(c *check.C) {
|
||||
|
||||
dockerCmd(t, "run", "-d", "--name", "test", "busybox")
|
||||
dockerCmd(t, "wait", "test")
|
||||
dockerCmd(c, "run", "-d", "--name", "test", "busybox")
|
||||
dockerCmd(c, "wait", "test")
|
||||
|
||||
// Expect this to fail because the above container is stopped, this is what we want
|
||||
if _, err := runCommand(exec.Command(dockerBinary, "run", "-d", "--name", "test2", "--link", "test:test", "busybox")); err == nil {
|
||||
t.Fatal("Expected error but got none")
|
||||
c.Fatal("Expected error but got none")
|
||||
}
|
||||
|
||||
ch := make(chan struct{})
|
||||
|
@ -25,7 +25,7 @@ func TestStartAttachReturnsOnError(t *testing.T) {
|
|||
// Attempt to start attached to the container that won't start
|
||||
// This should return an error immediately since the container can't be started
|
||||
if _, err := runCommand(exec.Command(dockerBinary, "start", "-a", "test2")); err == nil {
|
||||
t.Fatal("Expected error but got none")
|
||||
c.Fatal("Expected error but got none")
|
||||
}
|
||||
close(ch)
|
||||
}()
|
||||
|
@ -33,20 +33,18 @@ func TestStartAttachReturnsOnError(t *testing.T) {
|
|||
select {
|
||||
case <-ch:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatalf("Attach did not exit properly")
|
||||
c.Fatalf("Attach did not exit properly")
|
||||
}
|
||||
|
||||
logDone("start - error on start with attach exits")
|
||||
}
|
||||
|
||||
// gh#8555: Exit code should be passed through when using start -a
|
||||
func TestStartAttachCorrectExitCode(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestStartAttachCorrectExitCode(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 2; exit 1")
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run container: %v, output: %q", err, out)
|
||||
c.Fatalf("failed to run container: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
out = strings.TrimSpace(out)
|
||||
|
@ -54,167 +52,157 @@ func TestStartAttachCorrectExitCode(t *testing.T) {
|
|||
// make sure the container has exited before trying the "start -a"
|
||||
waitCmd := exec.Command(dockerBinary, "wait", out)
|
||||
if _, _, err = runCommandWithOutput(waitCmd); err != nil {
|
||||
t.Fatalf("Failed to wait on container: %v", err)
|
||||
c.Fatalf("Failed to wait on container: %v", err)
|
||||
}
|
||||
|
||||
startCmd := exec.Command(dockerBinary, "start", "-a", out)
|
||||
startOut, exitCode, err := runCommandWithOutput(startCmd)
|
||||
if err != nil && !strings.Contains("exit status 1", fmt.Sprintf("%s", err)) {
|
||||
t.Fatalf("start command failed unexpectedly with error: %v, output: %q", err, startOut)
|
||||
c.Fatalf("start command failed unexpectedly with error: %v, output: %q", err, startOut)
|
||||
}
|
||||
if exitCode != 1 {
|
||||
t.Fatalf("start -a did not respond with proper exit code: expected 1, got %d", exitCode)
|
||||
c.Fatalf("start -a did not respond with proper exit code: expected 1, got %d", exitCode)
|
||||
}
|
||||
|
||||
logDone("start - correct exit code returned with -a")
|
||||
}
|
||||
|
||||
func TestStartAttachSilent(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestStartAttachSilent(c *check.C) {
|
||||
|
||||
name := "teststartattachcorrectexitcode"
|
||||
runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "echo", "test")
|
||||
out, _, _, err := runCommandWithStdoutStderr(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run container: %v, output: %q", err, out)
|
||||
c.Fatalf("failed to run container: %v, output: %q", err, out)
|
||||
}
|
||||
|
||||
// make sure the container has exited before trying the "start -a"
|
||||
waitCmd := exec.Command(dockerBinary, "wait", name)
|
||||
if _, _, err = runCommandWithOutput(waitCmd); err != nil {
|
||||
t.Fatalf("wait command failed with error: %v", err)
|
||||
c.Fatalf("wait command failed with error: %v", err)
|
||||
}
|
||||
|
||||
startCmd := exec.Command(dockerBinary, "start", "-a", name)
|
||||
startOut, _, err := runCommandWithOutput(startCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("start command failed unexpectedly with error: %v, output: %q", err, startOut)
|
||||
c.Fatalf("start command failed unexpectedly with error: %v, output: %q", err, startOut)
|
||||
}
|
||||
if expected := "test\n"; startOut != expected {
|
||||
t.Fatalf("start -a produced unexpected output: expected %q, got %q", expected, startOut)
|
||||
c.Fatalf("start -a produced unexpected output: expected %q, got %q", expected, startOut)
|
||||
}
|
||||
|
||||
logDone("start - don't echo container ID when attaching")
|
||||
}
|
||||
|
||||
func TestStartRecordError(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestStartRecordError(c *check.C) {
|
||||
|
||||
// when container runs successfully, we should not have state.Error
|
||||
dockerCmd(t, "run", "-d", "-p", "9999:9999", "--name", "test", "busybox", "top")
|
||||
dockerCmd(c, "run", "-d", "-p", "9999:9999", "--name", "test", "busybox", "top")
|
||||
stateErr, err := inspectField("test", "State.Error")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to inspect %q state's error, got error %q", "test", err)
|
||||
c.Fatalf("Failed to inspect %q state's error, got error %q", "test", err)
|
||||
}
|
||||
if stateErr != "" {
|
||||
t.Fatalf("Expected to not have state error but got state.Error(%q)", stateErr)
|
||||
c.Fatalf("Expected to not have state error but got state.Error(%q)", stateErr)
|
||||
}
|
||||
|
||||
// Expect this to fail and records error because of ports conflict
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "test2", "-p", "9999:9999", "busybox", "top"))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error but got none, output %q", out)
|
||||
c.Fatalf("Expected error but got none, output %q", out)
|
||||
}
|
||||
stateErr, err = inspectField("test2", "State.Error")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to inspect %q state's error, got error %q", "test2", err)
|
||||
c.Fatalf("Failed to inspect %q state's error, got error %q", "test2", err)
|
||||
}
|
||||
expected := "port is already allocated"
|
||||
if stateErr == "" || !strings.Contains(stateErr, expected) {
|
||||
t.Fatalf("State.Error(%q) does not include %q", stateErr, expected)
|
||||
c.Fatalf("State.Error(%q) does not include %q", stateErr, expected)
|
||||
}
|
||||
|
||||
// Expect the conflict to be resolved when we stop the initial container
|
||||
dockerCmd(t, "stop", "test")
|
||||
dockerCmd(t, "start", "test2")
|
||||
dockerCmd(c, "stop", "test")
|
||||
dockerCmd(c, "start", "test2")
|
||||
stateErr, err = inspectField("test2", "State.Error")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to inspect %q state's error, got error %q", "test", err)
|
||||
c.Fatalf("Failed to inspect %q state's error, got error %q", "test", err)
|
||||
}
|
||||
if stateErr != "" {
|
||||
t.Fatalf("Expected to not have state error but got state.Error(%q)", stateErr)
|
||||
c.Fatalf("Expected to not have state error but got state.Error(%q)", stateErr)
|
||||
}
|
||||
|
||||
logDone("start - set state error when start is unsuccessful")
|
||||
}
|
||||
|
||||
// gh#8726: a failed Start() breaks --volumes-from on subsequent Start()'s
|
||||
func TestStartVolumesFromFailsCleanly(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestStartVolumesFromFailsCleanly(c *check.C) {
|
||||
|
||||
// Create the first data volume
|
||||
dockerCmd(t, "run", "-d", "--name", "data_before", "-v", "/foo", "busybox")
|
||||
dockerCmd(c, "run", "-d", "--name", "data_before", "-v", "/foo", "busybox")
|
||||
|
||||
// Expect this to fail because the data test after contaienr doesn't exist yet
|
||||
if _, err := runCommand(exec.Command(dockerBinary, "run", "-d", "--name", "consumer", "--volumes-from", "data_before", "--volumes-from", "data_after", "busybox")); err == nil {
|
||||
t.Fatal("Expected error but got none")
|
||||
c.Fatal("Expected error but got none")
|
||||
}
|
||||
|
||||
// Create the second data volume
|
||||
dockerCmd(t, "run", "-d", "--name", "data_after", "-v", "/bar", "busybox")
|
||||
dockerCmd(c, "run", "-d", "--name", "data_after", "-v", "/bar", "busybox")
|
||||
|
||||
// Now, all the volumes should be there
|
||||
dockerCmd(t, "start", "consumer")
|
||||
dockerCmd(c, "start", "consumer")
|
||||
|
||||
// Check that we have the volumes we want
|
||||
out, _ := dockerCmd(t, "inspect", "--format='{{ len .Volumes }}'", "consumer")
|
||||
out, _ := dockerCmd(c, "inspect", "--format='{{ len .Volumes }}'", "consumer")
|
||||
nVolumes := strings.Trim(out, " \r\n'")
|
||||
if nVolumes != "2" {
|
||||
t.Fatalf("Missing volumes: expected 2, got %s", nVolumes)
|
||||
c.Fatalf("Missing volumes: expected 2, got %s", nVolumes)
|
||||
}
|
||||
|
||||
logDone("start - missing containers in --volumes-from did not affect subsequent runs")
|
||||
}
|
||||
|
||||
func TestStartPausedContainer(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestStartPausedContainer(c *check.C) {
|
||||
defer unpauseAllContainers()
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "top")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "pause", "testing")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
runCmd = exec.Command(dockerBinary, "start", "testing")
|
||||
if out, _, err := runCommandWithOutput(runCmd); err == nil || !strings.Contains(out, "Cannot start a paused container, try unpause instead.") {
|
||||
t.Fatalf("an error should have been shown that you cannot start paused container: %s\n%v", out, err)
|
||||
c.Fatalf("an error should have been shown that you cannot start paused container: %s\n%v", out, err)
|
||||
}
|
||||
|
||||
logDone("start - error should show if trying to start paused container")
|
||||
}
|
||||
|
||||
func TestStartMultipleContainers(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestStartMultipleContainers(c *check.C) {
|
||||
// run a container named 'parent' and create two container link to `parent`
|
||||
cmd := exec.Command(dockerBinary, "run", "-d", "--name", "parent", "busybox", "top")
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
for _, container := range []string{"child_first", "child_second"} {
|
||||
cmd = exec.Command(dockerBinary, "create", "--name", container, "--link", "parent:parent", "busybox", "top")
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
}
|
||||
|
||||
// stop 'parent' container
|
||||
cmd = exec.Command(dockerBinary, "stop", "parent")
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", "parent")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
out = strings.Trim(out, "\r\n")
|
||||
if out != "false" {
|
||||
t.Fatal("Container should be stopped")
|
||||
c.Fatal("Container should be stopped")
|
||||
}
|
||||
|
||||
// start all the three containers, container `child_first` start first which should be faild
|
||||
|
@ -222,35 +210,33 @@ func TestStartMultipleContainers(t *testing.T) {
|
|||
cmd = exec.Command(dockerBinary, "start", "child_first", "parent", "child_second")
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if !strings.Contains(out, "Cannot start container child_first") || err == nil {
|
||||
t.Fatal("Expected error but got none")
|
||||
c.Fatal("Expected error but got none")
|
||||
}
|
||||
|
||||
for container, expected := range map[string]string{"parent": "true", "child_first": "false", "child_second": "true"} {
|
||||
cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", container)
|
||||
out, _, err = runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
out = strings.Trim(out, "\r\n")
|
||||
if out != expected {
|
||||
t.Fatal("Container running state wrong")
|
||||
c.Fatal("Container running state wrong")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
logDone("start - start multiple containers continue on one failed")
|
||||
}
|
||||
|
||||
func TestStartAttachMultipleContainers(t *testing.T) {
|
||||
func (s *DockerSuite) TestStartAttachMultipleContainers(c *check.C) {
|
||||
|
||||
var cmd *exec.Cmd
|
||||
|
||||
defer deleteAllContainers()
|
||||
// run multiple containers to test
|
||||
for _, container := range []string{"test1", "test2", "test3"} {
|
||||
cmd = exec.Command(dockerBinary, "run", "-d", "--name", container, "busybox", "top")
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,7 +244,7 @@ func TestStartAttachMultipleContainers(t *testing.T) {
|
|||
for _, container := range []string{"test1", "test2", "test3"} {
|
||||
cmd = exec.Command(dockerBinary, "stop", container)
|
||||
if out, _, err := runCommandWithOutput(cmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,7 +253,7 @@ func TestStartAttachMultipleContainers(t *testing.T) {
|
|||
cmd = exec.Command(dockerBinary, "start", option, "test1", "test2", "test3")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if !strings.Contains(out, "You cannot start and attach multiple containers at once.") || err == nil {
|
||||
t.Fatal("Expected error but got none")
|
||||
c.Fatal("Expected error but got none")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,13 +262,12 @@ func TestStartAttachMultipleContainers(t *testing.T) {
|
|||
cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", container)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
out = strings.Trim(out, "\r\n")
|
||||
if out != expected {
|
||||
t.Fatal("Container running state wrong")
|
||||
c.Fatal("Container running state wrong")
|
||||
}
|
||||
}
|
||||
|
||||
logDone("start - error on start and attach multiple containers at once")
|
||||
}
|
||||
|
|
|
@ -3,48 +3,46 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// tagging a named image in a new unprefixed repo should work
|
||||
func TestTagUnprefixedRepoByName(t *testing.T) {
|
||||
func (s *DockerSuite) TestTagUnprefixedRepoByName(c *check.C) {
|
||||
if err := pullImageIfNotExist("busybox:latest"); err != nil {
|
||||
t.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
}
|
||||
|
||||
tagCmd := exec.Command(dockerBinary, "tag", "busybox:latest", "testfoobarbaz")
|
||||
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
deleteImages("testfoobarbaz")
|
||||
|
||||
logDone("tag - busybox -> testfoobarbaz")
|
||||
}
|
||||
|
||||
// tagging an image by ID in a new unprefixed repo should work
|
||||
func TestTagUnprefixedRepoByID(t *testing.T) {
|
||||
func (s *DockerSuite) TestTagUnprefixedRepoByID(c *check.C) {
|
||||
getIDCmd := exec.Command(dockerBinary, "inspect", "-f", "{{.Id}}", "busybox")
|
||||
out, _, err := runCommandWithOutput(getIDCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get the image ID of busybox: %s, %v", out, err)
|
||||
c.Fatalf("failed to get the image ID of busybox: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
tagCmd := exec.Command(dockerBinary, "tag", cleanedImageID, "testfoobarbaz")
|
||||
if out, _, err = runCommandWithOutput(tagCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
|
||||
deleteImages("testfoobarbaz")
|
||||
|
||||
logDone("tag - busybox's image ID -> testfoobarbaz")
|
||||
}
|
||||
|
||||
// ensure we don't allow the use of invalid repository names; these tag operations should fail
|
||||
func TestTagInvalidUnprefixedRepo(t *testing.T) {
|
||||
func (s *DockerSuite) TestTagInvalidUnprefixedRepo(c *check.C) {
|
||||
|
||||
invalidRepos := []string{"fo$z$", "Foo@3cc", "Foo$3", "Foo*3", "Fo^3", "Foo!3", "F)xcz(", "fo%asd"}
|
||||
|
||||
|
@ -52,14 +50,13 @@ func TestTagInvalidUnprefixedRepo(t *testing.T) {
|
|||
tagCmd := exec.Command(dockerBinary, "tag", "busybox", repo)
|
||||
_, _, err := runCommandWithOutput(tagCmd)
|
||||
if err == nil {
|
||||
t.Fatalf("tag busybox %v should have failed", repo)
|
||||
c.Fatalf("tag busybox %v should have failed", repo)
|
||||
}
|
||||
}
|
||||
logDone("tag - busybox invalid repo names --> must not work")
|
||||
}
|
||||
|
||||
// ensure we don't allow the use of invalid tags; these tag operations should fail
|
||||
func TestTagInvalidPrefixedRepo(t *testing.T) {
|
||||
func (s *DockerSuite) TestTagInvalidPrefixedRepo(c *check.C) {
|
||||
longTag := stringutils.GenerateRandomAlphaOnlyString(121)
|
||||
|
||||
invalidTags := []string{"repo:fo$z$", "repo:Foo@3cc", "repo:Foo$3", "repo:Foo*3", "repo:Fo^3", "repo:Foo!3", "repo:%goodbye", "repo:#hashtagit", "repo:F)xcz(", "repo:-foo", "repo:..", longTag}
|
||||
|
@ -68,16 +65,15 @@ func TestTagInvalidPrefixedRepo(t *testing.T) {
|
|||
tagCmd := exec.Command(dockerBinary, "tag", "busybox", repotag)
|
||||
_, _, err := runCommandWithOutput(tagCmd)
|
||||
if err == nil {
|
||||
t.Fatalf("tag busybox %v should have failed", repotag)
|
||||
c.Fatalf("tag busybox %v should have failed", repotag)
|
||||
}
|
||||
}
|
||||
logDone("tag - busybox with invalid repo:tagnames --> must not work")
|
||||
}
|
||||
|
||||
// ensure we allow the use of valid tags
|
||||
func TestTagValidPrefixedRepo(t *testing.T) {
|
||||
func (s *DockerSuite) TestTagValidPrefixedRepo(c *check.C) {
|
||||
if err := pullImageIfNotExist("busybox:latest"); err != nil {
|
||||
t.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
}
|
||||
|
||||
validRepos := []string{"fooo/bar", "fooaa/test", "foooo:t"}
|
||||
|
@ -86,56 +82,53 @@ func TestTagValidPrefixedRepo(t *testing.T) {
|
|||
tagCmd := exec.Command(dockerBinary, "tag", "busybox:latest", repo)
|
||||
_, _, err := runCommandWithOutput(tagCmd)
|
||||
if err != nil {
|
||||
t.Errorf("tag busybox %v should have worked: %s", repo, err)
|
||||
c.Errorf("tag busybox %v should have worked: %s", repo, err)
|
||||
continue
|
||||
}
|
||||
deleteImages(repo)
|
||||
}
|
||||
logDone("tag - tag valid prefixed repo")
|
||||
}
|
||||
|
||||
// tag an image with an existed tag name without -f option should fail
|
||||
func TestTagExistedNameWithoutForce(t *testing.T) {
|
||||
func (s *DockerSuite) TestTagExistedNameWithoutForce(c *check.C) {
|
||||
if err := pullImageIfNotExist("busybox:latest"); err != nil {
|
||||
t.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
}
|
||||
|
||||
tagCmd := exec.Command(dockerBinary, "tag", "busybox:latest", "busybox:test")
|
||||
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
tagCmd = exec.Command(dockerBinary, "tag", "busybox:latest", "busybox:test")
|
||||
out, _, err := runCommandWithOutput(tagCmd)
|
||||
if err == nil || !strings.Contains(out, "Conflict: Tag test is already set to image") {
|
||||
t.Fatal("tag busybox busybox:test should have failed,because busybox:test is existed")
|
||||
c.Fatal("tag busybox busybox:test should have failed,because busybox:test is existed")
|
||||
}
|
||||
deleteImages("busybox:test")
|
||||
|
||||
logDone("tag - busybox with an existed tag name without -f option --> must not work")
|
||||
}
|
||||
|
||||
// tag an image with an existed tag name with -f option should work
|
||||
func TestTagExistedNameWithForce(t *testing.T) {
|
||||
func (s *DockerSuite) TestTagExistedNameWithForce(c *check.C) {
|
||||
if err := pullImageIfNotExist("busybox:latest"); err != nil {
|
||||
t.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
}
|
||||
|
||||
tagCmd := exec.Command(dockerBinary, "tag", "busybox:latest", "busybox:test")
|
||||
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
tagCmd = exec.Command(dockerBinary, "tag", "-f", "busybox:latest", "busybox:test")
|
||||
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
deleteImages("busybox:test")
|
||||
|
||||
logDone("tag - busybox with an existed tag name with -f option work")
|
||||
}
|
||||
|
||||
// ensure tagging using official names works
|
||||
// ensure all tags result in the same name
|
||||
func TestTagOfficialNames(t *testing.T) {
|
||||
func (s *DockerSuite) TestTagOfficialNames(c *check.C) {
|
||||
names := []string{
|
||||
"docker.io/busybox",
|
||||
"index.docker.io/busybox",
|
||||
|
@ -148,7 +141,7 @@ func TestTagOfficialNames(t *testing.T) {
|
|||
tagCmd := exec.Command(dockerBinary, "tag", "-f", "busybox:latest", name+":latest")
|
||||
out, exitCode, err := runCommandWithOutput(tagCmd)
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Errorf("tag busybox %v should have worked: %s, %s", name, err, out)
|
||||
c.Errorf("tag busybox %v should have worked: %s, %s", name, err, out)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -156,9 +149,9 @@ func TestTagOfficialNames(t *testing.T) {
|
|||
imagesCmd := exec.Command(dockerBinary, "images")
|
||||
out, _, err = runCommandWithOutput(imagesCmd)
|
||||
if err != nil {
|
||||
t.Errorf("listing images failed with errors: %v, %s", err, out)
|
||||
c.Errorf("listing images failed with errors: %v, %s", err, out)
|
||||
} else if strings.Contains(out, name) {
|
||||
t.Errorf("images should not have listed '%s'", name)
|
||||
c.Errorf("images should not have listed '%s'", name)
|
||||
deleteImages(name + ":latest")
|
||||
}
|
||||
}
|
||||
|
@ -167,10 +160,9 @@ func TestTagOfficialNames(t *testing.T) {
|
|||
tagCmd := exec.Command(dockerBinary, "tag", "-f", name+":latest", "fooo/bar:latest")
|
||||
_, exitCode, err := runCommandWithOutput(tagCmd)
|
||||
if err != nil || exitCode != 0 {
|
||||
t.Errorf("tag %v fooo/bar should have worked: %s", name, err)
|
||||
c.Errorf("tag %v fooo/bar should have worked: %s", name, err)
|
||||
continue
|
||||
}
|
||||
deleteImages("fooo/bar:latest")
|
||||
}
|
||||
logDone("tag - tag official names")
|
||||
}
|
||||
|
|
|
@ -3,14 +3,15 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func TestTopMultipleArgs(t *testing.T) {
|
||||
func (s *DockerSuite) TestTopMultipleArgs(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-i", "-d", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start the container: %s, %v", out, err)
|
||||
c.Fatalf("failed to start the container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -19,21 +20,20 @@ func TestTopMultipleArgs(t *testing.T) {
|
|||
topCmd := exec.Command(dockerBinary, "top", cleanedContainerID, "-o", "pid")
|
||||
out, _, err = runCommandWithOutput(topCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run top: %s, %v", out, err)
|
||||
c.Fatalf("failed to run top: %s, %v", out, err)
|
||||
}
|
||||
|
||||
if !strings.Contains(out, "PID") {
|
||||
t.Fatalf("did not see PID after top -o pid: %s", out)
|
||||
c.Fatalf("did not see PID after top -o pid: %s", out)
|
||||
}
|
||||
|
||||
logDone("top - multiple arguments")
|
||||
}
|
||||
|
||||
func TestTopNonPrivileged(t *testing.T) {
|
||||
func (s *DockerSuite) TestTopNonPrivileged(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "-i", "-d", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start the container: %s, %v", out, err)
|
||||
c.Fatalf("failed to start the container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -41,38 +41,37 @@ func TestTopNonPrivileged(t *testing.T) {
|
|||
topCmd := exec.Command(dockerBinary, "top", cleanedContainerID)
|
||||
out1, _, err := runCommandWithOutput(topCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run top: %s, %v", out1, err)
|
||||
c.Fatalf("failed to run top: %s, %v", out1, err)
|
||||
}
|
||||
|
||||
topCmd = exec.Command(dockerBinary, "top", cleanedContainerID)
|
||||
out2, _, err := runCommandWithOutput(topCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run top: %s, %v", out2, err)
|
||||
c.Fatalf("failed to run top: %s, %v", out2, err)
|
||||
}
|
||||
|
||||
killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(killCmd); err != nil {
|
||||
t.Fatalf("failed to kill container: %s, %v", out, err)
|
||||
c.Fatalf("failed to kill container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
|
||||
if !strings.Contains(out1, "top") && !strings.Contains(out2, "top") {
|
||||
t.Fatal("top should've listed `top` in the process list, but failed twice")
|
||||
c.Fatal("top should've listed `top` in the process list, but failed twice")
|
||||
} else if !strings.Contains(out1, "top") {
|
||||
t.Fatal("top should've listed `top` in the process list, but failed the first time")
|
||||
c.Fatal("top should've listed `top` in the process list, but failed the first time")
|
||||
} else if !strings.Contains(out2, "top") {
|
||||
t.Fatal("top should've listed `top` in the process list, but failed the second itime")
|
||||
c.Fatal("top should've listed `top` in the process list, but failed the second itime")
|
||||
}
|
||||
|
||||
logDone("top - top process should be listed in non privileged mode")
|
||||
}
|
||||
|
||||
func TestTopPrivileged(t *testing.T) {
|
||||
func (s *DockerSuite) TestTopPrivileged(c *check.C) {
|
||||
runCmd := exec.Command(dockerBinary, "run", "--privileged", "-i", "-d", "busybox", "top")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start the container: %s, %v", out, err)
|
||||
c.Fatalf("failed to start the container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
@ -80,29 +79,28 @@ func TestTopPrivileged(t *testing.T) {
|
|||
topCmd := exec.Command(dockerBinary, "top", cleanedContainerID)
|
||||
out1, _, err := runCommandWithOutput(topCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run top: %s, %v", out1, err)
|
||||
c.Fatalf("failed to run top: %s, %v", out1, err)
|
||||
}
|
||||
|
||||
topCmd = exec.Command(dockerBinary, "top", cleanedContainerID)
|
||||
out2, _, err := runCommandWithOutput(topCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run top: %s, %v", out2, err)
|
||||
c.Fatalf("failed to run top: %s, %v", out2, err)
|
||||
}
|
||||
|
||||
killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID)
|
||||
if out, _, err = runCommandWithOutput(killCmd); err != nil {
|
||||
t.Fatalf("failed to kill container: %s, %v", out, err)
|
||||
c.Fatalf("failed to kill container: %s, %v", out, err)
|
||||
}
|
||||
|
||||
deleteContainer(cleanedContainerID)
|
||||
|
||||
if !strings.Contains(out1, "top") && !strings.Contains(out2, "top") {
|
||||
t.Fatal("top should've listed `top` in the process list, but failed twice")
|
||||
c.Fatal("top should've listed `top` in the process list, but failed twice")
|
||||
} else if !strings.Contains(out1, "top") {
|
||||
t.Fatal("top should've listed `top` in the process list, but failed the first time")
|
||||
c.Fatal("top should've listed `top` in the process list, but failed the first time")
|
||||
} else if !strings.Contains(out2, "top") {
|
||||
t.Fatal("top should've listed `top` in the process list, but failed the second itime")
|
||||
c.Fatal("top should've listed `top` in the process list, but failed the second itime")
|
||||
}
|
||||
|
||||
logDone("top - top process should be listed in privileged mode")
|
||||
}
|
||||
|
|
|
@ -3,15 +3,16 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// ensure docker version works
|
||||
func TestVersionEnsureSucceeds(t *testing.T) {
|
||||
func (s *DockerSuite) TestVersionEnsureSucceeds(c *check.C) {
|
||||
versionCmd := exec.Command(dockerBinary, "version")
|
||||
out, _, err := runCommandWithOutput(versionCmd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to execute docker version: %s, %v", out, err)
|
||||
c.Fatalf("failed to execute docker version: %s, %v", out, err)
|
||||
}
|
||||
|
||||
stringsToCheck := []string{
|
||||
|
@ -29,9 +30,8 @@ func TestVersionEnsureSucceeds(t *testing.T) {
|
|||
|
||||
for _, linePrefix := range stringsToCheck {
|
||||
if !strings.Contains(out, linePrefix) {
|
||||
t.Errorf("couldn't find string %v in output", linePrefix)
|
||||
c.Errorf("couldn't find string %v in output", linePrefix)
|
||||
}
|
||||
}
|
||||
|
||||
logDone("version - verify that it works and that the output is properly formatted")
|
||||
}
|
||||
|
|
|
@ -3,18 +3,18 @@ package main
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// non-blocking wait with 0 exit code
|
||||
func TestWaitNonBlockedExitZero(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestWaitNonBlockedExitZero(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "true")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
|
@ -23,13 +23,13 @@ func TestWaitNonBlockedExitZero(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "inspect", "--format='{{.State.Running}}'", containerID)
|
||||
status, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(status, err)
|
||||
c.Fatal(status, err)
|
||||
}
|
||||
status = strings.TrimSpace(status)
|
||||
|
||||
time.Sleep(time.Second)
|
||||
if i >= 60 {
|
||||
t.Fatal("Container should have stopped by now")
|
||||
c.Fatal("Container should have stopped by now")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,20 +37,18 @@ func TestWaitNonBlockedExitZero(t *testing.T) {
|
|||
out, _, err = runCommandWithOutput(runCmd)
|
||||
|
||||
if err != nil || strings.TrimSpace(out) != "0" {
|
||||
t.Fatal("failed to set up container", out, err)
|
||||
c.Fatal("failed to set up container", out, err)
|
||||
}
|
||||
|
||||
logDone("wait - non-blocking wait with 0 exit code")
|
||||
}
|
||||
|
||||
// blocking wait with 0 exit code
|
||||
func TestWaitBlockedExitZero(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestWaitBlockedExitZero(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 10")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
|
@ -58,20 +56,18 @@ func TestWaitBlockedExitZero(t *testing.T) {
|
|||
out, _, err = runCommandWithOutput(runCmd)
|
||||
|
||||
if err != nil || strings.TrimSpace(out) != "0" {
|
||||
t.Fatal("failed to set up container", out, err)
|
||||
c.Fatal("failed to set up container", out, err)
|
||||
}
|
||||
|
||||
logDone("wait - blocking wait with 0 exit code")
|
||||
}
|
||||
|
||||
// non-blocking wait with random exit code
|
||||
func TestWaitNonBlockedExitRandom(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestWaitNonBlockedExitRandom(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "exit 99")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
|
@ -80,13 +76,13 @@ func TestWaitNonBlockedExitRandom(t *testing.T) {
|
|||
runCmd = exec.Command(dockerBinary, "inspect", "--format='{{.State.Running}}'", containerID)
|
||||
status, _, err = runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(status, err)
|
||||
c.Fatal(status, err)
|
||||
}
|
||||
status = strings.TrimSpace(status)
|
||||
|
||||
time.Sleep(time.Second)
|
||||
if i >= 60 {
|
||||
t.Fatal("Container should have stopped by now")
|
||||
c.Fatal("Container should have stopped by now")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,20 +90,18 @@ func TestWaitNonBlockedExitRandom(t *testing.T) {
|
|||
out, _, err = runCommandWithOutput(runCmd)
|
||||
|
||||
if err != nil || strings.TrimSpace(out) != "99" {
|
||||
t.Fatal("failed to set up container", out, err)
|
||||
c.Fatal("failed to set up container", out, err)
|
||||
}
|
||||
|
||||
logDone("wait - non-blocking wait with random exit code")
|
||||
}
|
||||
|
||||
// blocking wait with random exit code
|
||||
func TestWaitBlockedExitRandom(t *testing.T) {
|
||||
defer deleteAllContainers()
|
||||
func (s *DockerSuite) TestWaitBlockedExitRandom(c *check.C) {
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 10; exit 99")
|
||||
out, _, err := runCommandWithOutput(runCmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
c.Fatal(out, err)
|
||||
}
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
|
@ -115,8 +109,7 @@ func TestWaitBlockedExitRandom(t *testing.T) {
|
|||
out, _, err = runCommandWithOutput(runCmd)
|
||||
|
||||
if err != nil || strings.TrimSpace(out) != "99" {
|
||||
t.Fatal("failed to set up container", out, err)
|
||||
c.Fatal("failed to set up container", out, err)
|
||||
}
|
||||
|
||||
logDone("wait - blocking wait with random exit code")
|
||||
}
|
||||
|
|
|
@ -18,17 +18,17 @@ import (
|
|||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// Daemon represents a Docker daemon for the testing framework.
|
||||
type Daemon struct {
|
||||
t *testing.T
|
||||
c *check.C
|
||||
logFile *os.File
|
||||
folder string
|
||||
stdin io.WriteCloser
|
||||
|
@ -42,24 +42,24 @@ type Daemon struct {
|
|||
// NewDaemon returns a Daemon instance to be used for testing.
|
||||
// This will create a directory such as daemon123456789 in the folder specified by $DEST.
|
||||
// The daemon will not automatically start.
|
||||
func NewDaemon(t *testing.T) *Daemon {
|
||||
func NewDaemon(c *check.C) *Daemon {
|
||||
dest := os.Getenv("DEST")
|
||||
if dest == "" {
|
||||
t.Fatal("Please set the DEST environment variable")
|
||||
c.Fatal("Please set the DEST environment variable")
|
||||
}
|
||||
|
||||
dir := filepath.Join(dest, fmt.Sprintf("daemon%d", time.Now().UnixNano()%100000000))
|
||||
daemonFolder, err := filepath.Abs(dir)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not make %q an absolute path: %v", dir, err)
|
||||
c.Fatalf("Could not make %q an absolute path: %v", dir, err)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(filepath.Join(daemonFolder, "graph"), 0600); err != nil {
|
||||
t.Fatalf("Could not create %s/graph directory", daemonFolder)
|
||||
c.Fatalf("Could not create %s/graph directory", daemonFolder)
|
||||
}
|
||||
|
||||
return &Daemon{
|
||||
t: t,
|
||||
c: c,
|
||||
folder: daemonFolder,
|
||||
storageDriver: os.Getenv("DOCKER_GRAPHDRIVER"),
|
||||
execDriver: os.Getenv("DOCKER_EXECDRIVER"),
|
||||
|
@ -71,7 +71,7 @@ func NewDaemon(t *testing.T) *Daemon {
|
|||
func (d *Daemon) Start(arg ...string) error {
|
||||
dockerBinary, err := exec.LookPath(dockerBinary)
|
||||
if err != nil {
|
||||
d.t.Fatalf("could not find docker binary in $PATH: %v", err)
|
||||
d.c.Fatalf("could not find docker binary in $PATH: %v", err)
|
||||
}
|
||||
|
||||
args := []string{
|
||||
|
@ -105,7 +105,7 @@ func (d *Daemon) Start(arg ...string) error {
|
|||
|
||||
d.logFile, err = os.OpenFile(filepath.Join(d.folder, "docker.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
|
||||
if err != nil {
|
||||
d.t.Fatalf("Could not create %s/docker.log: %v", d.folder, err)
|
||||
d.c.Fatalf("Could not create %s/docker.log: %v", d.folder, err)
|
||||
}
|
||||
|
||||
d.cmd.Stdout = d.logFile
|
||||
|
@ -119,7 +119,7 @@ func (d *Daemon) Start(arg ...string) error {
|
|||
|
||||
go func() {
|
||||
wait <- d.cmd.Wait()
|
||||
d.t.Log("exiting daemon")
|
||||
d.c.Log("exiting daemon")
|
||||
close(wait)
|
||||
}()
|
||||
|
||||
|
@ -129,7 +129,7 @@ func (d *Daemon) Start(arg ...string) error {
|
|||
// make sure daemon is ready to receive requests
|
||||
startTime := time.Now().Unix()
|
||||
for {
|
||||
d.t.Log("waiting for daemon to start")
|
||||
d.c.Log("waiting for daemon to start")
|
||||
if time.Now().Unix()-startTime > 5 {
|
||||
// After 5 seconds, give up
|
||||
return errors.New("Daemon exited and never started")
|
||||
|
@ -148,7 +148,7 @@ func (d *Daemon) Start(arg ...string) error {
|
|||
|
||||
req, err := http.NewRequest("GET", "/_ping", nil)
|
||||
if err != nil {
|
||||
d.t.Fatalf("could not create new request: %v", err)
|
||||
d.c.Fatalf("could not create new request: %v", err)
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
|
@ -156,10 +156,10 @@ func (d *Daemon) Start(arg ...string) error {
|
|||
continue
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
d.t.Logf("received status != 200 OK: %s", resp.Status)
|
||||
d.c.Logf("received status != 200 OK: %s", resp.Status)
|
||||
}
|
||||
|
||||
d.t.Log("daemon started")
|
||||
d.c.Log("daemon started")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ func (d *Daemon) StartWithBusybox(arg ...string) error {
|
|||
return fmt.Errorf("could not load busybox image: %v", err)
|
||||
}
|
||||
if err := os.Remove(bb); err != nil {
|
||||
d.t.Logf("Could not remove %s: %v", bb, err)
|
||||
d.c.Logf("Could not remove %s: %v", bb, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ out1:
|
|||
return err
|
||||
case <-time.After(15 * time.Second):
|
||||
// time for stopping jobs and run onShutdown hooks
|
||||
d.t.Log("timeout")
|
||||
d.c.Log("timeout")
|
||||
break out1
|
||||
}
|
||||
}
|
||||
|
@ -231,10 +231,10 @@ out2:
|
|||
case <-tick:
|
||||
i++
|
||||
if i > 4 {
|
||||
d.t.Logf("tried to interrupt daemon for %d times, now try to kill it", i)
|
||||
d.c.Logf("tried to interrupt daemon for %d times, now try to kill it", i)
|
||||
break out2
|
||||
}
|
||||
d.t.Logf("Attempt #%d: daemon is still running with pid %d", i, d.cmd.Process.Pid)
|
||||
d.c.Logf("Attempt #%d: daemon is still running with pid %d", i, d.cmd.Process.Pid)
|
||||
if err := d.cmd.Process.Signal(os.Interrupt); err != nil {
|
||||
return fmt.Errorf("could not send signal: %v", err)
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ out2:
|
|||
}
|
||||
|
||||
if err := d.cmd.Process.Kill(); err != nil {
|
||||
d.t.Logf("Could not kill daemon: %v", err)
|
||||
d.c.Logf("Could not kill daemon: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -478,10 +478,10 @@ func pullImageIfNotExist(image string) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func dockerCmd(t *testing.T, args ...string) (string, int) {
|
||||
func dockerCmd(c *check.C, args ...string) (string, int) {
|
||||
out, status, err := runCommandWithOutput(exec.Command(dockerBinary, args...))
|
||||
if err != nil {
|
||||
t.Fatalf("%q failed with errors: %s, %v", strings.Join(args, " "), out, err)
|
||||
c.Fatalf("%q failed with errors: %s, %v", strings.Join(args, " "), out, err)
|
||||
}
|
||||
return out, status
|
||||
}
|
||||
|
@ -496,7 +496,7 @@ func dockerCmdWithTimeout(timeout time.Duration, args ...string) (string, int, e
|
|||
}
|
||||
|
||||
// execute a docker command in a directory
|
||||
func dockerCmdInDir(t *testing.T, path string, args ...string) (string, int, error) {
|
||||
func dockerCmdInDir(c *check.C, path string, args ...string) (string, int, error) {
|
||||
dockerCommand := exec.Command(dockerBinary, args...)
|
||||
dockerCommand.Dir = path
|
||||
out, status, err := runCommandWithOutput(dockerCommand)
|
||||
|
@ -517,11 +517,11 @@ func dockerCmdInDirWithTimeout(timeout time.Duration, path string, args ...strin
|
|||
return out, status, err
|
||||
}
|
||||
|
||||
func findContainerIP(t *testing.T, id string) string {
|
||||
func findContainerIP(c *check.C, id string) string {
|
||||
cmd := exec.Command(dockerBinary, "inspect", "--format='{{ .NetworkSettings.IPAddress }}'", id)
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
return strings.Trim(out, " \r\n'")
|
||||
|
@ -779,12 +779,12 @@ func getIDByName(name string) (string, error) {
|
|||
// getContainerState returns the exit code of the container
|
||||
// and true if it's running
|
||||
// the exit code should be ignored if it's running
|
||||
func getContainerState(t *testing.T, id string) (int, bool, error) {
|
||||
func getContainerState(c *check.C, id string) (int, bool, error) {
|
||||
var (
|
||||
exitStatus int
|
||||
running bool
|
||||
)
|
||||
out, exitCode := dockerCmd(t, "inspect", "--format={{.State.Running}} {{.State.ExitCode}}", id)
|
||||
out, exitCode := dockerCmd(c, "inspect", "--format={{.State.Running}} {{.State.ExitCode}}", id)
|
||||
if exitCode != 0 {
|
||||
return 0, false, fmt.Errorf("%q doesn't exist: %s", id, out)
|
||||
}
|
||||
|
@ -985,28 +985,28 @@ func fakeGIT(name string, files map[string]string, enforceLocalServer bool) (*Fa
|
|||
// Write `content` to the file at path `dst`, creating it if necessary,
|
||||
// as well as any missing directories.
|
||||
// The file is truncated if it already exists.
|
||||
// Call t.Fatal() at the first error.
|
||||
func writeFile(dst, content string, t *testing.T) {
|
||||
// Call c.Fatal() at the first error.
|
||||
func writeFile(dst, content string, c *check.C) {
|
||||
// Create subdirectories if necessary
|
||||
if err := os.MkdirAll(path.Dir(dst), 0700); err != nil && !os.IsExist(err) {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
f, err := os.OpenFile(dst, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0700)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
// Write content (truncate if it exists)
|
||||
if _, err := io.Copy(f, strings.NewReader(content)); err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Return the contents of file at path `src`.
|
||||
// Call t.Fatal() at the first error (including if the file doesn't exist)
|
||||
func readFile(src string, t *testing.T) (content string) {
|
||||
// Call c.Fatal() at the first error (including if the file doesn't exist)
|
||||
func readFile(src string, c *check.C) (content string) {
|
||||
data, err := ioutil.ReadFile(src)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
return string(data)
|
||||
|
@ -1051,14 +1051,14 @@ func readContainerFileWithExec(containerId, filename string) ([]byte, error) {
|
|||
}
|
||||
|
||||
// daemonTime provides the current time on the daemon host
|
||||
func daemonTime(t *testing.T) time.Time {
|
||||
func daemonTime(c *check.C) time.Time {
|
||||
if isLocalDaemon {
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
_, body, err := sockRequest("GET", "/info", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("daemonTime: failed to get /info: %v", err)
|
||||
c.Fatalf("daemonTime: failed to get /info: %v", err)
|
||||
}
|
||||
|
||||
type infoJSON struct {
|
||||
|
@ -1066,21 +1066,21 @@ func daemonTime(t *testing.T) time.Time {
|
|||
}
|
||||
var info infoJSON
|
||||
if err = json.Unmarshal(body, &info); err != nil {
|
||||
t.Fatalf("unable to unmarshal /info response: %v", err)
|
||||
c.Fatalf("unable to unmarshal /info response: %v", err)
|
||||
}
|
||||
|
||||
dt, err := time.Parse(time.RFC3339Nano, info.SystemTime)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
return dt
|
||||
}
|
||||
|
||||
func setupRegistry(t *testing.T) func() {
|
||||
testRequires(t, RegistryHosting)
|
||||
reg, err := newTestRegistryV2(t)
|
||||
func setupRegistry(c *check.C) func() {
|
||||
testRequires(c, RegistryHosting)
|
||||
reg, err := newTestRegistryV2(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// Wait for registry to be ready to serve requests.
|
||||
|
@ -1092,7 +1092,7 @@ func setupRegistry(t *testing.T) func() {
|
|||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("Timeout waiting for test registry to become available")
|
||||
c.Fatal("Timeout waiting for test registry to become available")
|
||||
}
|
||||
|
||||
return func() { reg.Close() }
|
||||
|
|
|
@ -7,7 +7,8 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
const v2binary = "registry-v2"
|
||||
|
@ -17,7 +18,7 @@ type testRegistryV2 struct {
|
|||
dir string
|
||||
}
|
||||
|
||||
func newTestRegistryV2(t *testing.T) (*testRegistryV2, error) {
|
||||
func newTestRegistryV2(c *check.C) (*testRegistryV2, error) {
|
||||
template := `version: 0.1
|
||||
loglevel: debug
|
||||
storage:
|
||||
|
@ -43,7 +44,7 @@ http:
|
|||
if err := cmd.Start(); err != nil {
|
||||
os.RemoveAll(tmp)
|
||||
if os.IsNotExist(err) {
|
||||
t.Skip()
|
||||
c.Skip(err.Error())
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@ import (
|
|||
"net/http"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
type TestCondition func() bool
|
||||
|
@ -92,10 +93,10 @@ var (
|
|||
|
||||
// testRequires checks if the environment satisfies the requirements
|
||||
// for the test to run or skips the tests.
|
||||
func testRequires(t *testing.T, requirements ...TestRequirement) {
|
||||
func testRequires(c *check.C, requirements ...TestRequirement) {
|
||||
for _, r := range requirements {
|
||||
if !r.Condition() {
|
||||
t.Skip(r.SkipMessage)
|
||||
c.Skip(r.SkipMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,10 +168,6 @@ func runCommandPipelineWithOutput(cmds ...*exec.Cmd) (output string, exitCode in
|
|||
return runCommandWithOutput(cmds[len(cmds)-1])
|
||||
}
|
||||
|
||||
func logDone(message string) {
|
||||
fmt.Printf("[PASSED]: %.69s\n", message)
|
||||
}
|
||||
|
||||
func unmarshalJSON(data []byte, result interface{}) error {
|
||||
err := json.Unmarshal(data, result)
|
||||
if err != nil {
|
||||
|
|
4
vendor/src/github.com/go-check/check/.gitignore
vendored
Normal file
4
vendor/src/github.com/go-check/check/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
_*
|
||||
*.swp
|
||||
*.[568]
|
||||
[568].out
|
25
vendor/src/github.com/go-check/check/LICENSE
vendored
Normal file
25
vendor/src/github.com/go-check/check/LICENSE
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
Gocheck - A rich testing framework for Go
|
||||
|
||||
Copyright (c) 2010-2013 Gustavo Niemeyer <gustavo@niemeyer.net>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
20
vendor/src/github.com/go-check/check/README.md
vendored
Normal file
20
vendor/src/github.com/go-check/check/README.md
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
Instructions
|
||||
============
|
||||
|
||||
Install the package with:
|
||||
|
||||
go get gopkg.in/check.v1
|
||||
|
||||
Import it with:
|
||||
|
||||
import "gopkg.in/check.v1"
|
||||
|
||||
and use _check_ as the package name inside the code.
|
||||
|
||||
For more details, visit the project page:
|
||||
|
||||
* http://labix.org/gocheck
|
||||
|
||||
and the API documentation:
|
||||
|
||||
* https://gopkg.in/check.v1
|
2
vendor/src/github.com/go-check/check/TODO
vendored
Normal file
2
vendor/src/github.com/go-check/check/TODO
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
- Assert(slice, Contains, item)
|
||||
- Parallel test support
|
163
vendor/src/github.com/go-check/check/benchmark.go
vendored
Normal file
163
vendor/src/github.com/go-check/check/benchmark.go
vendored
Normal file
|
@ -0,0 +1,163 @@
|
|||
// Copyright 2009 The Go 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 check
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
var memStats runtime.MemStats
|
||||
|
||||
// testingB is a type passed to Benchmark functions to manage benchmark
|
||||
// timing and to specify the number of iterations to run.
|
||||
type timer struct {
|
||||
start time.Time // Time test or benchmark started
|
||||
duration time.Duration
|
||||
N int
|
||||
bytes int64
|
||||
timerOn bool
|
||||
benchTime time.Duration
|
||||
// The initial states of memStats.Mallocs and memStats.TotalAlloc.
|
||||
startAllocs uint64
|
||||
startBytes uint64
|
||||
// The net total of this test after being run.
|
||||
netAllocs uint64
|
||||
netBytes uint64
|
||||
}
|
||||
|
||||
// StartTimer starts timing a test. This function is called automatically
|
||||
// before a benchmark starts, but it can also used to resume timing after
|
||||
// a call to StopTimer.
|
||||
func (c *C) StartTimer() {
|
||||
if !c.timerOn {
|
||||
c.start = time.Now()
|
||||
c.timerOn = true
|
||||
|
||||
runtime.ReadMemStats(&memStats)
|
||||
c.startAllocs = memStats.Mallocs
|
||||
c.startBytes = memStats.TotalAlloc
|
||||
}
|
||||
}
|
||||
|
||||
// StopTimer stops timing a test. This can be used to pause the timer
|
||||
// while performing complex initialization that you don't
|
||||
// want to measure.
|
||||
func (c *C) StopTimer() {
|
||||
if c.timerOn {
|
||||
c.duration += time.Now().Sub(c.start)
|
||||
c.timerOn = false
|
||||
runtime.ReadMemStats(&memStats)
|
||||
c.netAllocs += memStats.Mallocs - c.startAllocs
|
||||
c.netBytes += memStats.TotalAlloc - c.startBytes
|
||||
}
|
||||
}
|
||||
|
||||
// ResetTimer sets the elapsed benchmark time to zero.
|
||||
// It does not affect whether the timer is running.
|
||||
func (c *C) ResetTimer() {
|
||||
if c.timerOn {
|
||||
c.start = time.Now()
|
||||
runtime.ReadMemStats(&memStats)
|
||||
c.startAllocs = memStats.Mallocs
|
||||
c.startBytes = memStats.TotalAlloc
|
||||
}
|
||||
c.duration = 0
|
||||
c.netAllocs = 0
|
||||
c.netBytes = 0
|
||||
}
|
||||
|
||||
// SetBytes informs the number of bytes that the benchmark processes
|
||||
// on each iteration. If this is called in a benchmark it will also
|
||||
// report MB/s.
|
||||
func (c *C) SetBytes(n int64) {
|
||||
c.bytes = n
|
||||
}
|
||||
|
||||
func (c *C) nsPerOp() int64 {
|
||||
if c.N <= 0 {
|
||||
return 0
|
||||
}
|
||||
return c.duration.Nanoseconds() / int64(c.N)
|
||||
}
|
||||
|
||||
func (c *C) mbPerSec() float64 {
|
||||
if c.bytes <= 0 || c.duration <= 0 || c.N <= 0 {
|
||||
return 0
|
||||
}
|
||||
return (float64(c.bytes) * float64(c.N) / 1e6) / c.duration.Seconds()
|
||||
}
|
||||
|
||||
func (c *C) timerString() string {
|
||||
if c.N <= 0 {
|
||||
return fmt.Sprintf("%3.3fs", float64(c.duration.Nanoseconds())/1e9)
|
||||
}
|
||||
mbs := c.mbPerSec()
|
||||
mb := ""
|
||||
if mbs != 0 {
|
||||
mb = fmt.Sprintf("\t%7.2f MB/s", mbs)
|
||||
}
|
||||
nsop := c.nsPerOp()
|
||||
ns := fmt.Sprintf("%10d ns/op", nsop)
|
||||
if c.N > 0 && nsop < 100 {
|
||||
// The format specifiers here make sure that
|
||||
// the ones digits line up for all three possible formats.
|
||||
if nsop < 10 {
|
||||
ns = fmt.Sprintf("%13.2f ns/op", float64(c.duration.Nanoseconds())/float64(c.N))
|
||||
} else {
|
||||
ns = fmt.Sprintf("%12.1f ns/op", float64(c.duration.Nanoseconds())/float64(c.N))
|
||||
}
|
||||
}
|
||||
memStats := ""
|
||||
if c.benchMem {
|
||||
allocedBytes := fmt.Sprintf("%8d B/op", int64(c.netBytes)/int64(c.N))
|
||||
allocs := fmt.Sprintf("%8d allocs/op", int64(c.netAllocs)/int64(c.N))
|
||||
memStats = fmt.Sprintf("\t%s\t%s", allocedBytes, allocs)
|
||||
}
|
||||
return fmt.Sprintf("%8d\t%s%s%s", c.N, ns, mb, memStats)
|
||||
}
|
||||
|
||||
func min(x, y int) int {
|
||||
if x > y {
|
||||
return y
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
func max(x, y int) int {
|
||||
if x < y {
|
||||
return y
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
// roundDown10 rounds a number down to the nearest power of 10.
|
||||
func roundDown10(n int) int {
|
||||
var tens = 0
|
||||
// tens = floor(log_10(n))
|
||||
for n > 10 {
|
||||
n = n / 10
|
||||
tens++
|
||||
}
|
||||
// result = 10^tens
|
||||
result := 1
|
||||
for i := 0; i < tens; i++ {
|
||||
result *= 10
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// roundUp rounds x up to a number of the form [1eX, 2eX, 5eX].
|
||||
func roundUp(n int) int {
|
||||
base := roundDown10(n)
|
||||
if n < (2 * base) {
|
||||
return 2 * base
|
||||
}
|
||||
if n < (5 * base) {
|
||||
return 5 * base
|
||||
}
|
||||
return 10 * base
|
||||
}
|
91
vendor/src/github.com/go-check/check/benchmark_test.go
vendored
Normal file
91
vendor/src/github.com/go-check/check/benchmark_test.go
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
// These tests verify the test running logic.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"time"
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
var benchmarkS = Suite(&BenchmarkS{})
|
||||
|
||||
type BenchmarkS struct{}
|
||||
|
||||
func (s *BenchmarkS) TestCountSuite(c *C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
func (s *BenchmarkS) TestBasicTestTiming(c *C) {
|
||||
helper := FixtureHelper{sleepOn: "Test1", sleep: 1000000 * time.Nanosecond}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Verbose: true}
|
||||
Run(&helper, &runConf)
|
||||
|
||||
expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t0\\.001s\n" +
|
||||
"PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t0\\.000s\n"
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *BenchmarkS) TestStreamTestTiming(c *C) {
|
||||
helper := FixtureHelper{sleepOn: "SetUpSuite", sleep: 1000000 * time.Nanosecond}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Stream: true}
|
||||
Run(&helper, &runConf)
|
||||
|
||||
expected := "(?s).*\nPASS: check_test\\.go:[0-9]+: FixtureHelper\\.SetUpSuite\t *0\\.001s\n.*"
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *BenchmarkS) TestBenchmark(c *C) {
|
||||
helper := FixtureHelper{sleep: 100000}
|
||||
output := String{}
|
||||
runConf := RunConf{
|
||||
Output: &output,
|
||||
Benchmark: true,
|
||||
BenchmarkTime: 10000000,
|
||||
Filter: "Benchmark1",
|
||||
}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Benchmark1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[5], Equals, "Benchmark1")
|
||||
c.Check(helper.calls[6], Equals, "TearDownTest")
|
||||
// ... and more.
|
||||
|
||||
expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark1\t *100\t *[12][0-9]{5} ns/op\n"
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *BenchmarkS) TestBenchmarkBytes(c *C) {
|
||||
helper := FixtureHelper{sleep: 100000}
|
||||
output := String{}
|
||||
runConf := RunConf{
|
||||
Output: &output,
|
||||
Benchmark: true,
|
||||
BenchmarkTime: 10000000,
|
||||
Filter: "Benchmark2",
|
||||
}
|
||||
Run(&helper, &runConf)
|
||||
|
||||
expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark2\t *100\t *[12][0-9]{5} ns/op\t *[4-9]\\.[0-9]{2} MB/s\n"
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *BenchmarkS) TestBenchmarkMem(c *C) {
|
||||
helper := FixtureHelper{sleep: 100000}
|
||||
output := String{}
|
||||
runConf := RunConf{
|
||||
Output: &output,
|
||||
Benchmark: true,
|
||||
BenchmarkMem: true,
|
||||
BenchmarkTime: 10000000,
|
||||
Filter: "Benchmark3",
|
||||
}
|
||||
Run(&helper, &runConf)
|
||||
|
||||
expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark3\t *100\t *[12][0-9]{5} ns/op\t *[0-9]+ B/op\t *[1-9] allocs/op\n"
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
82
vendor/src/github.com/go-check/check/bootstrap_test.go
vendored
Normal file
82
vendor/src/github.com/go-check/check/bootstrap_test.go
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
// These initial tests are for bootstrapping. They verify that we can
|
||||
// basically use the testing infrastructure itself to check if the test
|
||||
// system is working.
|
||||
//
|
||||
// These tests use will break down the test runner badly in case of
|
||||
// errors because if they simply fail, we can't be sure the developer
|
||||
// will ever see anything (because failing means the failing system
|
||||
// somehow isn't working! :-)
|
||||
//
|
||||
// Do not assume *any* internal functionality works as expected besides
|
||||
// what's actually tested here.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gopkg.in/check.v1"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BootstrapS struct{}
|
||||
|
||||
var boostrapS = check.Suite(&BootstrapS{})
|
||||
|
||||
func (s *BootstrapS) TestCountSuite(c *check.C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestFailedAndFail(c *check.C) {
|
||||
if c.Failed() {
|
||||
critical("c.Failed() must be false first!")
|
||||
}
|
||||
c.Fail()
|
||||
if !c.Failed() {
|
||||
critical("c.Fail() didn't put the test in a failed state!")
|
||||
}
|
||||
c.Succeed()
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestFailedAndSucceed(c *check.C) {
|
||||
c.Fail()
|
||||
c.Succeed()
|
||||
if c.Failed() {
|
||||
critical("c.Succeed() didn't put the test back in a non-failed state")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestLogAndGetTestLog(c *check.C) {
|
||||
c.Log("Hello there!")
|
||||
log := c.GetTestLog()
|
||||
if log != "Hello there!\n" {
|
||||
critical(fmt.Sprintf("Log() or GetTestLog() is not working! Got: %#v", log))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestLogfAndGetTestLog(c *check.C) {
|
||||
c.Logf("Hello %v", "there!")
|
||||
log := c.GetTestLog()
|
||||
if log != "Hello there!\n" {
|
||||
critical(fmt.Sprintf("Logf() or GetTestLog() is not working! Got: %#v", log))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestRunShowsErrors(c *check.C) {
|
||||
output := String{}
|
||||
check.Run(&FailHelper{}, &check.RunConf{Output: &output})
|
||||
if strings.Index(output.value, "Expected failure!") == -1 {
|
||||
critical(fmt.Sprintf("RunWithWriter() output did not contain the "+
|
||||
"expected failure! Got: %#v",
|
||||
output.value))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestRunDoesntShowSuccesses(c *check.C) {
|
||||
output := String{}
|
||||
check.Run(&SuccessHelper{}, &check.RunConf{Output: &output})
|
||||
if strings.Index(output.value, "Expected success!") != -1 {
|
||||
critical(fmt.Sprintf("RunWithWriter() output contained a successful "+
|
||||
"test! Got: %#v",
|
||||
output.value))
|
||||
}
|
||||
}
|
945
vendor/src/github.com/go-check/check/check.go
vendored
Normal file
945
vendor/src/github.com/go-check/check/check.go
vendored
Normal file
|
@ -0,0 +1,945 @@
|
|||
// Package check is a rich testing extension for Go's testing package.
|
||||
//
|
||||
// For details about the project, see:
|
||||
//
|
||||
// http://labix.org/gocheck
|
||||
//
|
||||
package check
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Internal type which deals with suite method calling.
|
||||
|
||||
const (
|
||||
fixtureKd = iota
|
||||
testKd
|
||||
)
|
||||
|
||||
type funcKind int
|
||||
|
||||
const (
|
||||
succeededSt = iota
|
||||
failedSt
|
||||
skippedSt
|
||||
panickedSt
|
||||
fixturePanickedSt
|
||||
missedSt
|
||||
)
|
||||
|
||||
type funcStatus int
|
||||
|
||||
// A method value can't reach its own Method structure.
|
||||
type methodType struct {
|
||||
reflect.Value
|
||||
Info reflect.Method
|
||||
}
|
||||
|
||||
func newMethod(receiver reflect.Value, i int) *methodType {
|
||||
return &methodType{receiver.Method(i), receiver.Type().Method(i)}
|
||||
}
|
||||
|
||||
func (method *methodType) PC() uintptr {
|
||||
return method.Info.Func.Pointer()
|
||||
}
|
||||
|
||||
func (method *methodType) suiteName() string {
|
||||
t := method.Info.Type.In(0)
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
return t.Name()
|
||||
}
|
||||
|
||||
func (method *methodType) String() string {
|
||||
return method.suiteName() + "." + method.Info.Name
|
||||
}
|
||||
|
||||
func (method *methodType) matches(re *regexp.Regexp) bool {
|
||||
return (re.MatchString(method.Info.Name) ||
|
||||
re.MatchString(method.suiteName()) ||
|
||||
re.MatchString(method.String()))
|
||||
}
|
||||
|
||||
type C struct {
|
||||
method *methodType
|
||||
kind funcKind
|
||||
testName string
|
||||
status funcStatus
|
||||
logb *logger
|
||||
logw io.Writer
|
||||
done chan *C
|
||||
reason string
|
||||
mustFail bool
|
||||
tempDir *tempDir
|
||||
benchMem bool
|
||||
startTime time.Time
|
||||
timer
|
||||
}
|
||||
|
||||
func (c *C) stopNow() {
|
||||
runtime.Goexit()
|
||||
}
|
||||
|
||||
// logger is a concurrency safe byte.Buffer
|
||||
type logger struct {
|
||||
sync.Mutex
|
||||
writer bytes.Buffer
|
||||
}
|
||||
|
||||
func (l *logger) Write(buf []byte) (int, error) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
return l.writer.Write(buf)
|
||||
}
|
||||
|
||||
func (l *logger) WriteTo(w io.Writer) (int64, error) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
return l.writer.WriteTo(w)
|
||||
}
|
||||
|
||||
func (l *logger) String() string {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
return l.writer.String()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Handling of temporary files and directories.
|
||||
|
||||
type tempDir struct {
|
||||
sync.Mutex
|
||||
path string
|
||||
counter int
|
||||
}
|
||||
|
||||
func (td *tempDir) newPath() string {
|
||||
td.Lock()
|
||||
defer td.Unlock()
|
||||
if td.path == "" {
|
||||
var err error
|
||||
for i := 0; i != 100; i++ {
|
||||
path := fmt.Sprintf("%s%ccheck-%d", os.TempDir(), os.PathSeparator, rand.Int())
|
||||
if err = os.Mkdir(path, 0700); err == nil {
|
||||
td.path = path
|
||||
break
|
||||
}
|
||||
}
|
||||
if td.path == "" {
|
||||
panic("Couldn't create temporary directory: " + err.Error())
|
||||
}
|
||||
}
|
||||
result := filepath.Join(td.path, strconv.Itoa(td.counter))
|
||||
td.counter += 1
|
||||
return result
|
||||
}
|
||||
|
||||
func (td *tempDir) removeAll() {
|
||||
td.Lock()
|
||||
defer td.Unlock()
|
||||
if td.path != "" {
|
||||
err := os.RemoveAll(td.path)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARNING: Error cleaning up temporaries: "+err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new temporary directory which is automatically removed after
|
||||
// the suite finishes running.
|
||||
func (c *C) MkDir() string {
|
||||
path := c.tempDir.newPath()
|
||||
if err := os.Mkdir(path, 0700); err != nil {
|
||||
panic(fmt.Sprintf("Couldn't create temporary directory %s: %s", path, err.Error()))
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Low-level logging functions.
|
||||
|
||||
func (c *C) log(args ...interface{}) {
|
||||
c.writeLog([]byte(fmt.Sprint(args...) + "\n"))
|
||||
}
|
||||
|
||||
func (c *C) logf(format string, args ...interface{}) {
|
||||
c.writeLog([]byte(fmt.Sprintf(format+"\n", args...)))
|
||||
}
|
||||
|
||||
func (c *C) logNewLine() {
|
||||
c.writeLog([]byte{'\n'})
|
||||
}
|
||||
|
||||
func (c *C) writeLog(buf []byte) {
|
||||
c.logb.Write(buf)
|
||||
if c.logw != nil {
|
||||
c.logw.Write(buf)
|
||||
}
|
||||
}
|
||||
|
||||
func hasStringOrError(x interface{}) (ok bool) {
|
||||
_, ok = x.(fmt.Stringer)
|
||||
if ok {
|
||||
return
|
||||
}
|
||||
_, ok = x.(error)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *C) logValue(label string, value interface{}) {
|
||||
if label == "" {
|
||||
if hasStringOrError(value) {
|
||||
c.logf("... %#v (%q)", value, value)
|
||||
} else {
|
||||
c.logf("... %#v", value)
|
||||
}
|
||||
} else if value == nil {
|
||||
c.logf("... %s = nil", label)
|
||||
} else {
|
||||
if hasStringOrError(value) {
|
||||
fv := fmt.Sprintf("%#v", value)
|
||||
qv := fmt.Sprintf("%q", value)
|
||||
if fv != qv {
|
||||
c.logf("... %s %s = %s (%s)", label, reflect.TypeOf(value), fv, qv)
|
||||
return
|
||||
}
|
||||
}
|
||||
if s, ok := value.(string); ok && isMultiLine(s) {
|
||||
c.logf(`... %s %s = "" +`, label, reflect.TypeOf(value))
|
||||
c.logMultiLine(s)
|
||||
} else {
|
||||
c.logf("... %s %s = %#v", label, reflect.TypeOf(value), value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *C) logMultiLine(s string) {
|
||||
b := make([]byte, 0, len(s)*2)
|
||||
i := 0
|
||||
n := len(s)
|
||||
for i < n {
|
||||
j := i + 1
|
||||
for j < n && s[j-1] != '\n' {
|
||||
j++
|
||||
}
|
||||
b = append(b, "... "...)
|
||||
b = strconv.AppendQuote(b, s[i:j])
|
||||
if j < n {
|
||||
b = append(b, " +"...)
|
||||
}
|
||||
b = append(b, '\n')
|
||||
i = j
|
||||
}
|
||||
c.writeLog(b)
|
||||
}
|
||||
|
||||
func isMultiLine(s string) bool {
|
||||
for i := 0; i+1 < len(s); i++ {
|
||||
if s[i] == '\n' {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *C) logString(issue string) {
|
||||
c.log("... ", issue)
|
||||
}
|
||||
|
||||
func (c *C) logCaller(skip int) {
|
||||
// This is a bit heavier than it ought to be.
|
||||
skip += 1 // Our own frame.
|
||||
pc, callerFile, callerLine, ok := runtime.Caller(skip)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var testFile string
|
||||
var testLine int
|
||||
testFunc := runtime.FuncForPC(c.method.PC())
|
||||
if runtime.FuncForPC(pc) != testFunc {
|
||||
for {
|
||||
skip += 1
|
||||
if pc, file, line, ok := runtime.Caller(skip); ok {
|
||||
// Note that the test line may be different on
|
||||
// distinct calls for the same test. Showing
|
||||
// the "internal" line is helpful when debugging.
|
||||
if runtime.FuncForPC(pc) == testFunc {
|
||||
testFile, testLine = file, line
|
||||
break
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if testFile != "" && (testFile != callerFile || testLine != callerLine) {
|
||||
c.logCode(testFile, testLine)
|
||||
}
|
||||
c.logCode(callerFile, callerLine)
|
||||
}
|
||||
|
||||
func (c *C) logCode(path string, line int) {
|
||||
c.logf("%s:%d:", nicePath(path), line)
|
||||
code, err := printLine(path, line)
|
||||
if code == "" {
|
||||
code = "..." // XXX Open the file and take the raw line.
|
||||
if err != nil {
|
||||
code += err.Error()
|
||||
}
|
||||
}
|
||||
c.log(indent(code, " "))
|
||||
}
|
||||
|
||||
var valueGo = filepath.Join("reflect", "value.go")
|
||||
var asmGo = filepath.Join("runtime", "asm_")
|
||||
|
||||
func (c *C) logPanic(skip int, value interface{}) {
|
||||
skip++ // Our own frame.
|
||||
initialSkip := skip
|
||||
for ; ; skip++ {
|
||||
if pc, file, line, ok := runtime.Caller(skip); ok {
|
||||
if skip == initialSkip {
|
||||
c.logf("... Panic: %s (PC=0x%X)\n", value, pc)
|
||||
}
|
||||
name := niceFuncName(pc)
|
||||
path := nicePath(file)
|
||||
if strings.Contains(path, "/gopkg.in/check.v") {
|
||||
continue
|
||||
}
|
||||
if name == "Value.call" && strings.HasSuffix(path, valueGo) {
|
||||
continue
|
||||
}
|
||||
if name == "call16" && strings.Contains(path, asmGo) {
|
||||
continue
|
||||
}
|
||||
c.logf("%s:%d\n in %s", nicePath(file), line, name)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *C) logSoftPanic(issue string) {
|
||||
c.log("... Panic: ", issue)
|
||||
}
|
||||
|
||||
func (c *C) logArgPanic(method *methodType, expectedType string) {
|
||||
c.logf("... Panic: %s argument should be %s",
|
||||
niceFuncName(method.PC()), expectedType)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Some simple formatting helpers.
|
||||
|
||||
var initWD, initWDErr = os.Getwd()
|
||||
|
||||
func init() {
|
||||
if initWDErr == nil {
|
||||
initWD = strings.Replace(initWD, "\\", "/", -1) + "/"
|
||||
}
|
||||
}
|
||||
|
||||
func nicePath(path string) string {
|
||||
if initWDErr == nil {
|
||||
if strings.HasPrefix(path, initWD) {
|
||||
return path[len(initWD):]
|
||||
}
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func niceFuncPath(pc uintptr) string {
|
||||
function := runtime.FuncForPC(pc)
|
||||
if function != nil {
|
||||
filename, line := function.FileLine(pc)
|
||||
return fmt.Sprintf("%s:%d", nicePath(filename), line)
|
||||
}
|
||||
return "<unknown path>"
|
||||
}
|
||||
|
||||
func niceFuncName(pc uintptr) string {
|
||||
function := runtime.FuncForPC(pc)
|
||||
if function != nil {
|
||||
name := path.Base(function.Name())
|
||||
if i := strings.Index(name, "."); i > 0 {
|
||||
name = name[i+1:]
|
||||
}
|
||||
if strings.HasPrefix(name, "(*") {
|
||||
if i := strings.Index(name, ")"); i > 0 {
|
||||
name = name[2:i] + name[i+1:]
|
||||
}
|
||||
}
|
||||
if i := strings.LastIndex(name, ".*"); i != -1 {
|
||||
name = name[:i] + "." + name[i+2:]
|
||||
}
|
||||
if i := strings.LastIndex(name, "·"); i != -1 {
|
||||
name = name[:i] + "." + name[i+2:]
|
||||
}
|
||||
return name
|
||||
}
|
||||
return "<unknown function>"
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Result tracker to aggregate call results.
|
||||
|
||||
type Result struct {
|
||||
Succeeded int
|
||||
Failed int
|
||||
Skipped int
|
||||
Panicked int
|
||||
FixturePanicked int
|
||||
ExpectedFailures int
|
||||
Missed int // Not even tried to run, related to a panic in the fixture.
|
||||
RunError error // Houston, we've got a problem.
|
||||
WorkDir string // If KeepWorkDir is true
|
||||
}
|
||||
|
||||
type resultTracker struct {
|
||||
result Result
|
||||
_lastWasProblem bool
|
||||
_waiting int
|
||||
_missed int
|
||||
_expectChan chan *C
|
||||
_doneChan chan *C
|
||||
_stopChan chan bool
|
||||
}
|
||||
|
||||
func newResultTracker() *resultTracker {
|
||||
return &resultTracker{_expectChan: make(chan *C), // Synchronous
|
||||
_doneChan: make(chan *C, 32), // Asynchronous
|
||||
_stopChan: make(chan bool)} // Synchronous
|
||||
}
|
||||
|
||||
func (tracker *resultTracker) start() {
|
||||
go tracker._loopRoutine()
|
||||
}
|
||||
|
||||
func (tracker *resultTracker) waitAndStop() {
|
||||
<-tracker._stopChan
|
||||
}
|
||||
|
||||
func (tracker *resultTracker) expectCall(c *C) {
|
||||
tracker._expectChan <- c
|
||||
}
|
||||
|
||||
func (tracker *resultTracker) callDone(c *C) {
|
||||
tracker._doneChan <- c
|
||||
}
|
||||
|
||||
func (tracker *resultTracker) _loopRoutine() {
|
||||
for {
|
||||
var c *C
|
||||
if tracker._waiting > 0 {
|
||||
// Calls still running. Can't stop.
|
||||
select {
|
||||
// XXX Reindent this (not now to make diff clear)
|
||||
case c = <-tracker._expectChan:
|
||||
tracker._waiting += 1
|
||||
case c = <-tracker._doneChan:
|
||||
tracker._waiting -= 1
|
||||
switch c.status {
|
||||
case succeededSt:
|
||||
if c.kind == testKd {
|
||||
if c.mustFail {
|
||||
tracker.result.ExpectedFailures++
|
||||
} else {
|
||||
tracker.result.Succeeded++
|
||||
}
|
||||
}
|
||||
case failedSt:
|
||||
tracker.result.Failed++
|
||||
case panickedSt:
|
||||
if c.kind == fixtureKd {
|
||||
tracker.result.FixturePanicked++
|
||||
} else {
|
||||
tracker.result.Panicked++
|
||||
}
|
||||
case fixturePanickedSt:
|
||||
// Track it as missed, since the panic
|
||||
// was on the fixture, not on the test.
|
||||
tracker.result.Missed++
|
||||
case missedSt:
|
||||
tracker.result.Missed++
|
||||
case skippedSt:
|
||||
if c.kind == testKd {
|
||||
tracker.result.Skipped++
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No calls. Can stop, but no done calls here.
|
||||
select {
|
||||
case tracker._stopChan <- true:
|
||||
return
|
||||
case c = <-tracker._expectChan:
|
||||
tracker._waiting += 1
|
||||
case c = <-tracker._doneChan:
|
||||
panic("Tracker got an unexpected done call.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// The underlying suite runner.
|
||||
|
||||
type suiteRunner struct {
|
||||
suite interface{}
|
||||
setUpSuite, tearDownSuite *methodType
|
||||
setUpTest, tearDownTest *methodType
|
||||
tests []*methodType
|
||||
tracker *resultTracker
|
||||
tempDir *tempDir
|
||||
keepDir bool
|
||||
output *outputWriter
|
||||
reportedProblemLast bool
|
||||
benchTime time.Duration
|
||||
benchMem bool
|
||||
}
|
||||
|
||||
type RunConf struct {
|
||||
Output io.Writer
|
||||
Stream bool
|
||||
Verbose bool
|
||||
Filter string
|
||||
Benchmark bool
|
||||
BenchmarkTime time.Duration // Defaults to 1 second
|
||||
BenchmarkMem bool
|
||||
KeepWorkDir bool
|
||||
}
|
||||
|
||||
// Create a new suiteRunner able to run all methods in the given suite.
|
||||
func newSuiteRunner(suite interface{}, runConf *RunConf) *suiteRunner {
|
||||
var conf RunConf
|
||||
if runConf != nil {
|
||||
conf = *runConf
|
||||
}
|
||||
if conf.Output == nil {
|
||||
conf.Output = os.Stdout
|
||||
}
|
||||
if conf.Benchmark {
|
||||
conf.Verbose = true
|
||||
}
|
||||
|
||||
suiteType := reflect.TypeOf(suite)
|
||||
suiteNumMethods := suiteType.NumMethod()
|
||||
suiteValue := reflect.ValueOf(suite)
|
||||
|
||||
runner := &suiteRunner{
|
||||
suite: suite,
|
||||
output: newOutputWriter(conf.Output, conf.Stream, conf.Verbose),
|
||||
tracker: newResultTracker(),
|
||||
benchTime: conf.BenchmarkTime,
|
||||
benchMem: conf.BenchmarkMem,
|
||||
tempDir: &tempDir{},
|
||||
keepDir: conf.KeepWorkDir,
|
||||
tests: make([]*methodType, 0, suiteNumMethods),
|
||||
}
|
||||
if runner.benchTime == 0 {
|
||||
runner.benchTime = 1 * time.Second
|
||||
}
|
||||
|
||||
var filterRegexp *regexp.Regexp
|
||||
if conf.Filter != "" {
|
||||
if regexp, err := regexp.Compile(conf.Filter); err != nil {
|
||||
msg := "Bad filter expression: " + err.Error()
|
||||
runner.tracker.result.RunError = errors.New(msg)
|
||||
return runner
|
||||
} else {
|
||||
filterRegexp = regexp
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i != suiteNumMethods; i++ {
|
||||
method := newMethod(suiteValue, i)
|
||||
switch method.Info.Name {
|
||||
case "SetUpSuite":
|
||||
runner.setUpSuite = method
|
||||
case "TearDownSuite":
|
||||
runner.tearDownSuite = method
|
||||
case "SetUpTest":
|
||||
runner.setUpTest = method
|
||||
case "TearDownTest":
|
||||
runner.tearDownTest = method
|
||||
default:
|
||||
prefix := "Test"
|
||||
if conf.Benchmark {
|
||||
prefix = "Benchmark"
|
||||
}
|
||||
if !strings.HasPrefix(method.Info.Name, prefix) {
|
||||
continue
|
||||
}
|
||||
if filterRegexp == nil || method.matches(filterRegexp) {
|
||||
runner.tests = append(runner.tests, method)
|
||||
}
|
||||
}
|
||||
}
|
||||
return runner
|
||||
}
|
||||
|
||||
// Run all methods in the given suite.
|
||||
func (runner *suiteRunner) run() *Result {
|
||||
if runner.tracker.result.RunError == nil && len(runner.tests) > 0 {
|
||||
runner.tracker.start()
|
||||
if runner.checkFixtureArgs() {
|
||||
c := runner.runFixture(runner.setUpSuite, "", nil)
|
||||
if c == nil || c.status == succeededSt {
|
||||
for i := 0; i != len(runner.tests); i++ {
|
||||
c := runner.runTest(runner.tests[i])
|
||||
if c.status == fixturePanickedSt {
|
||||
runner.skipTests(missedSt, runner.tests[i+1:])
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if c != nil && c.status == skippedSt {
|
||||
runner.skipTests(skippedSt, runner.tests)
|
||||
} else {
|
||||
runner.skipTests(missedSt, runner.tests)
|
||||
}
|
||||
runner.runFixture(runner.tearDownSuite, "", nil)
|
||||
} else {
|
||||
runner.skipTests(missedSt, runner.tests)
|
||||
}
|
||||
runner.tracker.waitAndStop()
|
||||
if runner.keepDir {
|
||||
runner.tracker.result.WorkDir = runner.tempDir.path
|
||||
} else {
|
||||
runner.tempDir.removeAll()
|
||||
}
|
||||
}
|
||||
return &runner.tracker.result
|
||||
}
|
||||
|
||||
// Create a call object with the given suite method, and fork a
|
||||
// goroutine with the provided dispatcher for running it.
|
||||
func (runner *suiteRunner) forkCall(method *methodType, kind funcKind, testName string, logb *logger, dispatcher func(c *C)) *C {
|
||||
var logw io.Writer
|
||||
if runner.output.Stream {
|
||||
logw = runner.output
|
||||
}
|
||||
if logb == nil {
|
||||
logb = new(logger)
|
||||
}
|
||||
c := &C{
|
||||
method: method,
|
||||
kind: kind,
|
||||
testName: testName,
|
||||
logb: logb,
|
||||
logw: logw,
|
||||
tempDir: runner.tempDir,
|
||||
done: make(chan *C, 1),
|
||||
timer: timer{benchTime: runner.benchTime},
|
||||
startTime: time.Now(),
|
||||
benchMem: runner.benchMem,
|
||||
}
|
||||
runner.tracker.expectCall(c)
|
||||
go (func() {
|
||||
runner.reportCallStarted(c)
|
||||
defer runner.callDone(c)
|
||||
dispatcher(c)
|
||||
})()
|
||||
return c
|
||||
}
|
||||
|
||||
// Same as forkCall(), but wait for call to finish before returning.
|
||||
func (runner *suiteRunner) runFunc(method *methodType, kind funcKind, testName string, logb *logger, dispatcher func(c *C)) *C {
|
||||
c := runner.forkCall(method, kind, testName, logb, dispatcher)
|
||||
<-c.done
|
||||
return c
|
||||
}
|
||||
|
||||
// Handle a finished call. If there were any panics, update the call status
|
||||
// accordingly. Then, mark the call as done and report to the tracker.
|
||||
func (runner *suiteRunner) callDone(c *C) {
|
||||
value := recover()
|
||||
if value != nil {
|
||||
switch v := value.(type) {
|
||||
case *fixturePanic:
|
||||
if v.status == skippedSt {
|
||||
c.status = skippedSt
|
||||
} else {
|
||||
c.logSoftPanic("Fixture has panicked (see related PANIC)")
|
||||
c.status = fixturePanickedSt
|
||||
}
|
||||
default:
|
||||
c.logPanic(1, value)
|
||||
c.status = panickedSt
|
||||
}
|
||||
}
|
||||
if c.mustFail {
|
||||
switch c.status {
|
||||
case failedSt:
|
||||
c.status = succeededSt
|
||||
case succeededSt:
|
||||
c.status = failedSt
|
||||
c.logString("Error: Test succeeded, but was expected to fail")
|
||||
c.logString("Reason: " + c.reason)
|
||||
}
|
||||
}
|
||||
|
||||
runner.reportCallDone(c)
|
||||
c.done <- c
|
||||
}
|
||||
|
||||
// Runs a fixture call synchronously. The fixture will still be run in a
|
||||
// goroutine like all suite methods, but this method will not return
|
||||
// while the fixture goroutine is not done, because the fixture must be
|
||||
// run in a desired order.
|
||||
func (runner *suiteRunner) runFixture(method *methodType, testName string, logb *logger) *C {
|
||||
if method != nil {
|
||||
c := runner.runFunc(method, fixtureKd, testName, logb, func(c *C) {
|
||||
c.ResetTimer()
|
||||
c.StartTimer()
|
||||
defer c.StopTimer()
|
||||
c.method.Call([]reflect.Value{reflect.ValueOf(c)})
|
||||
})
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run the fixture method with runFixture(), but panic with a fixturePanic{}
|
||||
// in case the fixture method panics. This makes it easier to track the
|
||||
// fixture panic together with other call panics within forkTest().
|
||||
func (runner *suiteRunner) runFixtureWithPanic(method *methodType, testName string, logb *logger, skipped *bool) *C {
|
||||
if skipped != nil && *skipped {
|
||||
return nil
|
||||
}
|
||||
c := runner.runFixture(method, testName, logb)
|
||||
if c != nil && c.status != succeededSt {
|
||||
if skipped != nil {
|
||||
*skipped = c.status == skippedSt
|
||||
}
|
||||
panic(&fixturePanic{c.status, method})
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
type fixturePanic struct {
|
||||
status funcStatus
|
||||
method *methodType
|
||||
}
|
||||
|
||||
// Run the suite test method, together with the test-specific fixture,
|
||||
// asynchronously.
|
||||
func (runner *suiteRunner) forkTest(method *methodType) *C {
|
||||
testName := method.String()
|
||||
return runner.forkCall(method, testKd, testName, nil, func(c *C) {
|
||||
var skipped bool
|
||||
defer runner.runFixtureWithPanic(runner.tearDownTest, testName, nil, &skipped)
|
||||
defer c.StopTimer()
|
||||
benchN := 1
|
||||
for {
|
||||
runner.runFixtureWithPanic(runner.setUpTest, testName, c.logb, &skipped)
|
||||
mt := c.method.Type()
|
||||
if mt.NumIn() != 1 || mt.In(0) != reflect.TypeOf(c) {
|
||||
// Rather than a plain panic, provide a more helpful message when
|
||||
// the argument type is incorrect.
|
||||
c.status = panickedSt
|
||||
c.logArgPanic(c.method, "*check.C")
|
||||
return
|
||||
}
|
||||
if strings.HasPrefix(c.method.Info.Name, "Test") {
|
||||
c.ResetTimer()
|
||||
c.StartTimer()
|
||||
c.method.Call([]reflect.Value{reflect.ValueOf(c)})
|
||||
return
|
||||
}
|
||||
if !strings.HasPrefix(c.method.Info.Name, "Benchmark") {
|
||||
panic("unexpected method prefix: " + c.method.Info.Name)
|
||||
}
|
||||
|
||||
runtime.GC()
|
||||
c.N = benchN
|
||||
c.ResetTimer()
|
||||
c.StartTimer()
|
||||
c.method.Call([]reflect.Value{reflect.ValueOf(c)})
|
||||
c.StopTimer()
|
||||
if c.status != succeededSt || c.duration >= c.benchTime || benchN >= 1e9 {
|
||||
return
|
||||
}
|
||||
perOpN := int(1e9)
|
||||
if c.nsPerOp() != 0 {
|
||||
perOpN = int(c.benchTime.Nanoseconds() / c.nsPerOp())
|
||||
}
|
||||
|
||||
// Logic taken from the stock testing package:
|
||||
// - Run more iterations than we think we'll need for a second (1.5x).
|
||||
// - Don't grow too fast in case we had timing errors previously.
|
||||
// - Be sure to run at least one more than last time.
|
||||
benchN = max(min(perOpN+perOpN/2, 100*benchN), benchN+1)
|
||||
benchN = roundUp(benchN)
|
||||
|
||||
skipped = true // Don't run the deferred one if this panics.
|
||||
runner.runFixtureWithPanic(runner.tearDownTest, testName, nil, nil)
|
||||
skipped = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Same as forkTest(), but wait for the test to finish before returning.
|
||||
func (runner *suiteRunner) runTest(method *methodType) *C {
|
||||
c := runner.forkTest(method)
|
||||
<-c.done
|
||||
return c
|
||||
}
|
||||
|
||||
// Helper to mark tests as skipped or missed. A bit heavy for what
|
||||
// it does, but it enables homogeneous handling of tracking, including
|
||||
// nice verbose output.
|
||||
func (runner *suiteRunner) skipTests(status funcStatus, methods []*methodType) {
|
||||
for _, method := range methods {
|
||||
runner.runFunc(method, testKd, "", nil, func(c *C) {
|
||||
c.status = status
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Verify if the fixture arguments are *check.C. In case of errors,
|
||||
// log the error as a panic in the fixture method call, and return false.
|
||||
func (runner *suiteRunner) checkFixtureArgs() bool {
|
||||
succeeded := true
|
||||
argType := reflect.TypeOf(&C{})
|
||||
for _, method := range []*methodType{runner.setUpSuite, runner.tearDownSuite, runner.setUpTest, runner.tearDownTest} {
|
||||
if method != nil {
|
||||
mt := method.Type()
|
||||
if mt.NumIn() != 1 || mt.In(0) != argType {
|
||||
succeeded = false
|
||||
runner.runFunc(method, fixtureKd, "", nil, func(c *C) {
|
||||
c.logArgPanic(method, "*check.C")
|
||||
c.status = panickedSt
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return succeeded
|
||||
}
|
||||
|
||||
func (runner *suiteRunner) reportCallStarted(c *C) {
|
||||
runner.output.WriteCallStarted("START", c)
|
||||
}
|
||||
|
||||
func (runner *suiteRunner) reportCallDone(c *C) {
|
||||
runner.tracker.callDone(c)
|
||||
switch c.status {
|
||||
case succeededSt:
|
||||
if c.mustFail {
|
||||
runner.output.WriteCallSuccess("FAIL EXPECTED", c)
|
||||
} else {
|
||||
runner.output.WriteCallSuccess("PASS", c)
|
||||
}
|
||||
case skippedSt:
|
||||
runner.output.WriteCallSuccess("SKIP", c)
|
||||
case failedSt:
|
||||
runner.output.WriteCallProblem("FAIL", c)
|
||||
case panickedSt:
|
||||
runner.output.WriteCallProblem("PANIC", c)
|
||||
case fixturePanickedSt:
|
||||
// That's a testKd call reporting that its fixture
|
||||
// has panicked. The fixture call which caused the
|
||||
// panic itself was tracked above. We'll report to
|
||||
// aid debugging.
|
||||
runner.output.WriteCallProblem("PANIC", c)
|
||||
case missedSt:
|
||||
runner.output.WriteCallSuccess("MISS", c)
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Output writer manages atomic output writing according to settings.
|
||||
|
||||
type outputWriter struct {
|
||||
m sync.Mutex
|
||||
writer io.Writer
|
||||
wroteCallProblemLast bool
|
||||
Stream bool
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
func newOutputWriter(writer io.Writer, stream, verbose bool) *outputWriter {
|
||||
return &outputWriter{writer: writer, Stream: stream, Verbose: verbose}
|
||||
}
|
||||
|
||||
func (ow *outputWriter) Write(content []byte) (n int, err error) {
|
||||
ow.m.Lock()
|
||||
n, err = ow.writer.Write(content)
|
||||
ow.m.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
func (ow *outputWriter) WriteCallStarted(label string, c *C) {
|
||||
if ow.Stream {
|
||||
header := renderCallHeader(label, c, "", "\n")
|
||||
ow.m.Lock()
|
||||
ow.writer.Write([]byte(header))
|
||||
ow.m.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (ow *outputWriter) WriteCallProblem(label string, c *C) {
|
||||
var prefix string
|
||||
if !ow.Stream {
|
||||
prefix = "\n-----------------------------------" +
|
||||
"-----------------------------------\n"
|
||||
}
|
||||
header := renderCallHeader(label, c, prefix, "\n\n")
|
||||
ow.m.Lock()
|
||||
ow.wroteCallProblemLast = true
|
||||
ow.writer.Write([]byte(header))
|
||||
if !ow.Stream {
|
||||
c.logb.WriteTo(ow.writer)
|
||||
}
|
||||
ow.m.Unlock()
|
||||
}
|
||||
|
||||
func (ow *outputWriter) WriteCallSuccess(label string, c *C) {
|
||||
if ow.Stream || (ow.Verbose && c.kind == testKd) {
|
||||
// TODO Use a buffer here.
|
||||
var suffix string
|
||||
if c.reason != "" {
|
||||
suffix = " (" + c.reason + ")"
|
||||
}
|
||||
if c.status == succeededSt {
|
||||
suffix += "\t" + c.timerString()
|
||||
}
|
||||
suffix += "\n"
|
||||
if ow.Stream {
|
||||
suffix += "\n"
|
||||
}
|
||||
header := renderCallHeader(label, c, "", suffix)
|
||||
ow.m.Lock()
|
||||
// Resist temptation of using line as prefix above due to race.
|
||||
if !ow.Stream && ow.wroteCallProblemLast {
|
||||
header = "\n-----------------------------------" +
|
||||
"-----------------------------------\n" +
|
||||
header
|
||||
}
|
||||
ow.wroteCallProblemLast = false
|
||||
ow.writer.Write([]byte(header))
|
||||
ow.m.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func renderCallHeader(label string, c *C, prefix, suffix string) string {
|
||||
pc := c.method.PC()
|
||||
return fmt.Sprintf("%s%s: %s: %s%s", prefix, label, niceFuncPath(pc),
|
||||
niceFuncName(pc), suffix)
|
||||
}
|
207
vendor/src/github.com/go-check/check/check_test.go
vendored
Normal file
207
vendor/src/github.com/go-check/check/check_test.go
vendored
Normal file
|
@ -0,0 +1,207 @@
|
|||
// This file contains just a few generic helpers which are used by the
|
||||
// other test files.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
// We count the number of suites run at least to get a vague hint that the
|
||||
// test suite is behaving as it should. Otherwise a bug introduced at the
|
||||
// very core of the system could go unperceived.
|
||||
const suitesRunExpected = 8
|
||||
|
||||
var suitesRun int = 0
|
||||
|
||||
func Test(t *testing.T) {
|
||||
check.TestingT(t)
|
||||
if suitesRun != suitesRunExpected && flag.Lookup("check.f").Value.String() == "" {
|
||||
critical(fmt.Sprintf("Expected %d suites to run rather than %d",
|
||||
suitesRunExpected, suitesRun))
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper functions.
|
||||
|
||||
// Break down badly. This is used in test cases which can't yet assume
|
||||
// that the fundamental bits are working.
|
||||
func critical(error string) {
|
||||
fmt.Fprintln(os.Stderr, "CRITICAL: "+error)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Return the file line where it's called.
|
||||
func getMyLine() int {
|
||||
if _, _, line, ok := runtime.Caller(1); ok {
|
||||
return line
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper type implementing a basic io.Writer for testing output.
|
||||
|
||||
// Type implementing the io.Writer interface for analyzing output.
|
||||
type String struct {
|
||||
value string
|
||||
}
|
||||
|
||||
// The only function required by the io.Writer interface. Will append
|
||||
// written data to the String.value string.
|
||||
func (s *String) Write(p []byte) (n int, err error) {
|
||||
s.value += string(p)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// Trivial wrapper to test errors happening on a different file
|
||||
// than the test itself.
|
||||
func checkEqualWrapper(c *check.C, obtained, expected interface{}) (result bool, line int) {
|
||||
return c.Check(obtained, check.Equals, expected), getMyLine()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper suite for testing basic fail behavior.
|
||||
|
||||
type FailHelper struct {
|
||||
testLine int
|
||||
}
|
||||
|
||||
func (s *FailHelper) TestLogAndFail(c *check.C) {
|
||||
s.testLine = getMyLine() - 1
|
||||
c.Log("Expected failure!")
|
||||
c.Fail()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper suite for testing basic success behavior.
|
||||
|
||||
type SuccessHelper struct{}
|
||||
|
||||
func (s *SuccessHelper) TestLogAndSucceed(c *check.C) {
|
||||
c.Log("Expected success!")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper suite for testing ordering and behavior of fixture.
|
||||
|
||||
type FixtureHelper struct {
|
||||
calls []string
|
||||
panicOn string
|
||||
skip bool
|
||||
skipOnN int
|
||||
sleepOn string
|
||||
sleep time.Duration
|
||||
bytes int64
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) trace(name string, c *check.C) {
|
||||
s.calls = append(s.calls, name)
|
||||
if name == s.panicOn {
|
||||
panic(name)
|
||||
}
|
||||
if s.sleep > 0 && s.sleepOn == name {
|
||||
time.Sleep(s.sleep)
|
||||
}
|
||||
if s.skip && s.skipOnN == len(s.calls)-1 {
|
||||
c.Skip("skipOnN == n")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) SetUpSuite(c *check.C) {
|
||||
s.trace("SetUpSuite", c)
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) TearDownSuite(c *check.C) {
|
||||
s.trace("TearDownSuite", c)
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) SetUpTest(c *check.C) {
|
||||
s.trace("SetUpTest", c)
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) TearDownTest(c *check.C) {
|
||||
s.trace("TearDownTest", c)
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) Test1(c *check.C) {
|
||||
s.trace("Test1", c)
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) Test2(c *check.C) {
|
||||
s.trace("Test2", c)
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) Benchmark1(c *check.C) {
|
||||
s.trace("Benchmark1", c)
|
||||
for i := 0; i < c.N; i++ {
|
||||
time.Sleep(s.sleep)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) Benchmark2(c *check.C) {
|
||||
s.trace("Benchmark2", c)
|
||||
c.SetBytes(1024)
|
||||
for i := 0; i < c.N; i++ {
|
||||
time.Sleep(s.sleep)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) Benchmark3(c *check.C) {
|
||||
var x []int64
|
||||
s.trace("Benchmark3", c)
|
||||
for i := 0; i < c.N; i++ {
|
||||
time.Sleep(s.sleep)
|
||||
x = make([]int64, 5)
|
||||
_ = x
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper which checks the state of the test and ensures that it matches
|
||||
// the given expectations. Depends on c.Errorf() working, so shouldn't
|
||||
// be used to test this one function.
|
||||
|
||||
type expectedState struct {
|
||||
name string
|
||||
result interface{}
|
||||
failed bool
|
||||
log string
|
||||
}
|
||||
|
||||
// Verify the state of the test. Note that since this also verifies if
|
||||
// the test is supposed to be in a failed state, no other checks should
|
||||
// be done in addition to what is being tested.
|
||||
func checkState(c *check.C, result interface{}, expected *expectedState) {
|
||||
failed := c.Failed()
|
||||
c.Succeed()
|
||||
log := c.GetTestLog()
|
||||
matched, matchError := regexp.MatchString("^"+expected.log+"$", log)
|
||||
if matchError != nil {
|
||||
c.Errorf("Error in matching expression used in testing %s",
|
||||
expected.name)
|
||||
} else if !matched {
|
||||
c.Errorf("%s logged:\n----------\n%s----------\n\nExpected:\n----------\n%s\n----------",
|
||||
expected.name, log, expected.log)
|
||||
}
|
||||
if result != expected.result {
|
||||
c.Errorf("%s returned %#v rather than %#v",
|
||||
expected.name, result, expected.result)
|
||||
}
|
||||
if failed != expected.failed {
|
||||
if failed {
|
||||
c.Errorf("%s has failed when it shouldn't", expected.name)
|
||||
} else {
|
||||
c.Errorf("%s has not failed when it should", expected.name)
|
||||
}
|
||||
}
|
||||
}
|
458
vendor/src/github.com/go-check/check/checkers.go
vendored
Normal file
458
vendor/src/github.com/go-check/check/checkers.go
vendored
Normal file
|
@ -0,0 +1,458 @@
|
|||
package check
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// CommentInterface and Commentf helper, to attach extra information to checks.
|
||||
|
||||
type comment struct {
|
||||
format string
|
||||
args []interface{}
|
||||
}
|
||||
|
||||
// Commentf returns an infomational value to use with Assert or Check calls.
|
||||
// If the checker test fails, the provided arguments will be passed to
|
||||
// fmt.Sprintf, and will be presented next to the logged failure.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// c.Assert(v, Equals, 42, Commentf("Iteration #%d failed.", i))
|
||||
//
|
||||
// Note that if the comment is constant, a better option is to
|
||||
// simply use a normal comment right above or next to the line, as
|
||||
// it will also get printed with any errors:
|
||||
//
|
||||
// c.Assert(l, Equals, 8192) // Ensure buffer size is correct (bug #123)
|
||||
//
|
||||
func Commentf(format string, args ...interface{}) CommentInterface {
|
||||
return &comment{format, args}
|
||||
}
|
||||
|
||||
// CommentInterface must be implemented by types that attach extra
|
||||
// information to failed checks. See the Commentf function for details.
|
||||
type CommentInterface interface {
|
||||
CheckCommentString() string
|
||||
}
|
||||
|
||||
func (c *comment) CheckCommentString() string {
|
||||
return fmt.Sprintf(c.format, c.args...)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// The Checker interface.
|
||||
|
||||
// The Checker interface must be provided by checkers used with
|
||||
// the Assert and Check verification methods.
|
||||
type Checker interface {
|
||||
Info() *CheckerInfo
|
||||
Check(params []interface{}, names []string) (result bool, error string)
|
||||
}
|
||||
|
||||
// See the Checker interface.
|
||||
type CheckerInfo struct {
|
||||
Name string
|
||||
Params []string
|
||||
}
|
||||
|
||||
func (info *CheckerInfo) Info() *CheckerInfo {
|
||||
return info
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Not checker logic inverter.
|
||||
|
||||
// The Not checker inverts the logic of the provided checker. The
|
||||
// resulting checker will succeed where the original one failed, and
|
||||
// vice-versa.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// c.Assert(a, Not(Equals), b)
|
||||
//
|
||||
func Not(checker Checker) Checker {
|
||||
return ¬Checker{checker}
|
||||
}
|
||||
|
||||
type notChecker struct {
|
||||
sub Checker
|
||||
}
|
||||
|
||||
func (checker *notChecker) Info() *CheckerInfo {
|
||||
info := *checker.sub.Info()
|
||||
info.Name = "Not(" + info.Name + ")"
|
||||
return &info
|
||||
}
|
||||
|
||||
func (checker *notChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||
result, error = checker.sub.Check(params, names)
|
||||
result = !result
|
||||
return
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// IsNil checker.
|
||||
|
||||
type isNilChecker struct {
|
||||
*CheckerInfo
|
||||
}
|
||||
|
||||
// The IsNil checker tests whether the obtained value is nil.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// c.Assert(err, IsNil)
|
||||
//
|
||||
var IsNil Checker = &isNilChecker{
|
||||
&CheckerInfo{Name: "IsNil", Params: []string{"value"}},
|
||||
}
|
||||
|
||||
func (checker *isNilChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||
return isNil(params[0]), ""
|
||||
}
|
||||
|
||||
func isNil(obtained interface{}) (result bool) {
|
||||
if obtained == nil {
|
||||
result = true
|
||||
} else {
|
||||
switch v := reflect.ValueOf(obtained); v.Kind() {
|
||||
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||
return v.IsNil()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// NotNil checker. Alias for Not(IsNil), since it's so common.
|
||||
|
||||
type notNilChecker struct {
|
||||
*CheckerInfo
|
||||
}
|
||||
|
||||
// The NotNil checker verifies that the obtained value is not nil.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// c.Assert(iface, NotNil)
|
||||
//
|
||||
// This is an alias for Not(IsNil), made available since it's a
|
||||
// fairly common check.
|
||||
//
|
||||
var NotNil Checker = ¬NilChecker{
|
||||
&CheckerInfo{Name: "NotNil", Params: []string{"value"}},
|
||||
}
|
||||
|
||||
func (checker *notNilChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||
return !isNil(params[0]), ""
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Equals checker.
|
||||
|
||||
type equalsChecker struct {
|
||||
*CheckerInfo
|
||||
}
|
||||
|
||||
// The Equals checker verifies that the obtained value is equal to
|
||||
// the expected value, according to usual Go semantics for ==.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// c.Assert(value, Equals, 42)
|
||||
//
|
||||
var Equals Checker = &equalsChecker{
|
||||
&CheckerInfo{Name: "Equals", Params: []string{"obtained", "expected"}},
|
||||
}
|
||||
|
||||
func (checker *equalsChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||
defer func() {
|
||||
if v := recover(); v != nil {
|
||||
result = false
|
||||
error = fmt.Sprint(v)
|
||||
}
|
||||
}()
|
||||
return params[0] == params[1], ""
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// DeepEquals checker.
|
||||
|
||||
type deepEqualsChecker struct {
|
||||
*CheckerInfo
|
||||
}
|
||||
|
||||
// The DeepEquals checker verifies that the obtained value is deep-equal to
|
||||
// the expected value. The check will work correctly even when facing
|
||||
// slices, interfaces, and values of different types (which always fail
|
||||
// the test).
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// c.Assert(value, DeepEquals, 42)
|
||||
// c.Assert(array, DeepEquals, []string{"hi", "there"})
|
||||
//
|
||||
var DeepEquals Checker = &deepEqualsChecker{
|
||||
&CheckerInfo{Name: "DeepEquals", Params: []string{"obtained", "expected"}},
|
||||
}
|
||||
|
||||
func (checker *deepEqualsChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||
return reflect.DeepEqual(params[0], params[1]), ""
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// HasLen checker.
|
||||
|
||||
type hasLenChecker struct {
|
||||
*CheckerInfo
|
||||
}
|
||||
|
||||
// The HasLen checker verifies that the obtained value has the
|
||||
// provided length. In many cases this is superior to using Equals
|
||||
// in conjuction with the len function because in case the check
|
||||
// fails the value itself will be printed, instead of its length,
|
||||
// providing more details for figuring the problem.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// c.Assert(list, HasLen, 5)
|
||||
//
|
||||
var HasLen Checker = &hasLenChecker{
|
||||
&CheckerInfo{Name: "HasLen", Params: []string{"obtained", "n"}},
|
||||
}
|
||||
|
||||
func (checker *hasLenChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||
n, ok := params[1].(int)
|
||||
if !ok {
|
||||
return false, "n must be an int"
|
||||
}
|
||||
value := reflect.ValueOf(params[0])
|
||||
switch value.Kind() {
|
||||
case reflect.Map, reflect.Array, reflect.Slice, reflect.Chan, reflect.String:
|
||||
default:
|
||||
return false, "obtained value type has no length"
|
||||
}
|
||||
return value.Len() == n, ""
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// ErrorMatches checker.
|
||||
|
||||
type errorMatchesChecker struct {
|
||||
*CheckerInfo
|
||||
}
|
||||
|
||||
// The ErrorMatches checker verifies that the error value
|
||||
// is non nil and matches the regular expression provided.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// c.Assert(err, ErrorMatches, "perm.*denied")
|
||||
//
|
||||
var ErrorMatches Checker = errorMatchesChecker{
|
||||
&CheckerInfo{Name: "ErrorMatches", Params: []string{"value", "regex"}},
|
||||
}
|
||||
|
||||
func (checker errorMatchesChecker) Check(params []interface{}, names []string) (result bool, errStr string) {
|
||||
if params[0] == nil {
|
||||
return false, "Error value is nil"
|
||||
}
|
||||
err, ok := params[0].(error)
|
||||
if !ok {
|
||||
return false, "Value is not an error"
|
||||
}
|
||||
params[0] = err.Error()
|
||||
names[0] = "error"
|
||||
return matches(params[0], params[1])
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Matches checker.
|
||||
|
||||
type matchesChecker struct {
|
||||
*CheckerInfo
|
||||
}
|
||||
|
||||
// The Matches checker verifies that the string provided as the obtained
|
||||
// value (or the string resulting from obtained.String()) matches the
|
||||
// regular expression provided.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// c.Assert(err, Matches, "perm.*denied")
|
||||
//
|
||||
var Matches Checker = &matchesChecker{
|
||||
&CheckerInfo{Name: "Matches", Params: []string{"value", "regex"}},
|
||||
}
|
||||
|
||||
func (checker *matchesChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||
return matches(params[0], params[1])
|
||||
}
|
||||
|
||||
func matches(value, regex interface{}) (result bool, error string) {
|
||||
reStr, ok := regex.(string)
|
||||
if !ok {
|
||||
return false, "Regex must be a string"
|
||||
}
|
||||
valueStr, valueIsStr := value.(string)
|
||||
if !valueIsStr {
|
||||
if valueWithStr, valueHasStr := value.(fmt.Stringer); valueHasStr {
|
||||
valueStr, valueIsStr = valueWithStr.String(), true
|
||||
}
|
||||
}
|
||||
if valueIsStr {
|
||||
matches, err := regexp.MatchString("^"+reStr+"$", valueStr)
|
||||
if err != nil {
|
||||
return false, "Can't compile regex: " + err.Error()
|
||||
}
|
||||
return matches, ""
|
||||
}
|
||||
return false, "Obtained value is not a string and has no .String()"
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Panics checker.
|
||||
|
||||
type panicsChecker struct {
|
||||
*CheckerInfo
|
||||
}
|
||||
|
||||
// The Panics checker verifies that calling the provided zero-argument
|
||||
// function will cause a panic which is deep-equal to the provided value.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// c.Assert(func() { f(1, 2) }, Panics, &SomeErrorType{"BOOM"}).
|
||||
//
|
||||
//
|
||||
var Panics Checker = &panicsChecker{
|
||||
&CheckerInfo{Name: "Panics", Params: []string{"function", "expected"}},
|
||||
}
|
||||
|
||||
func (checker *panicsChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||
f := reflect.ValueOf(params[0])
|
||||
if f.Kind() != reflect.Func || f.Type().NumIn() != 0 {
|
||||
return false, "Function must take zero arguments"
|
||||
}
|
||||
defer func() {
|
||||
// If the function has not panicked, then don't do the check.
|
||||
if error != "" {
|
||||
return
|
||||
}
|
||||
params[0] = recover()
|
||||
names[0] = "panic"
|
||||
result = reflect.DeepEqual(params[0], params[1])
|
||||
}()
|
||||
f.Call(nil)
|
||||
return false, "Function has not panicked"
|
||||
}
|
||||
|
||||
type panicMatchesChecker struct {
|
||||
*CheckerInfo
|
||||
}
|
||||
|
||||
// The PanicMatches checker verifies that calling the provided zero-argument
|
||||
// function will cause a panic with an error value matching
|
||||
// the regular expression provided.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// c.Assert(func() { f(1, 2) }, PanicMatches, `open.*: no such file or directory`).
|
||||
//
|
||||
//
|
||||
var PanicMatches Checker = &panicMatchesChecker{
|
||||
&CheckerInfo{Name: "PanicMatches", Params: []string{"function", "expected"}},
|
||||
}
|
||||
|
||||
func (checker *panicMatchesChecker) Check(params []interface{}, names []string) (result bool, errmsg string) {
|
||||
f := reflect.ValueOf(params[0])
|
||||
if f.Kind() != reflect.Func || f.Type().NumIn() != 0 {
|
||||
return false, "Function must take zero arguments"
|
||||
}
|
||||
defer func() {
|
||||
// If the function has not panicked, then don't do the check.
|
||||
if errmsg != "" {
|
||||
return
|
||||
}
|
||||
obtained := recover()
|
||||
names[0] = "panic"
|
||||
if e, ok := obtained.(error); ok {
|
||||
params[0] = e.Error()
|
||||
} else if _, ok := obtained.(string); ok {
|
||||
params[0] = obtained
|
||||
} else {
|
||||
errmsg = "Panic value is not a string or an error"
|
||||
return
|
||||
}
|
||||
result, errmsg = matches(params[0], params[1])
|
||||
}()
|
||||
f.Call(nil)
|
||||
return false, "Function has not panicked"
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// FitsTypeOf checker.
|
||||
|
||||
type fitsTypeChecker struct {
|
||||
*CheckerInfo
|
||||
}
|
||||
|
||||
// The FitsTypeOf checker verifies that the obtained value is
|
||||
// assignable to a variable with the same type as the provided
|
||||
// sample value.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// c.Assert(value, FitsTypeOf, int64(0))
|
||||
// c.Assert(value, FitsTypeOf, os.Error(nil))
|
||||
//
|
||||
var FitsTypeOf Checker = &fitsTypeChecker{
|
||||
&CheckerInfo{Name: "FitsTypeOf", Params: []string{"obtained", "sample"}},
|
||||
}
|
||||
|
||||
func (checker *fitsTypeChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||
obtained := reflect.ValueOf(params[0])
|
||||
sample := reflect.ValueOf(params[1])
|
||||
if !obtained.IsValid() {
|
||||
return false, ""
|
||||
}
|
||||
if !sample.IsValid() {
|
||||
return false, "Invalid sample value"
|
||||
}
|
||||
return obtained.Type().AssignableTo(sample.Type()), ""
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Implements checker.
|
||||
|
||||
type implementsChecker struct {
|
||||
*CheckerInfo
|
||||
}
|
||||
|
||||
// The Implements checker verifies that the obtained value
|
||||
// implements the interface specified via a pointer to an interface
|
||||
// variable.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// var e os.Error
|
||||
// c.Assert(err, Implements, &e)
|
||||
//
|
||||
var Implements Checker = &implementsChecker{
|
||||
&CheckerInfo{Name: "Implements", Params: []string{"obtained", "ifaceptr"}},
|
||||
}
|
||||
|
||||
func (checker *implementsChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||
obtained := reflect.ValueOf(params[0])
|
||||
ifaceptr := reflect.ValueOf(params[1])
|
||||
if !obtained.IsValid() {
|
||||
return false, ""
|
||||
}
|
||||
if !ifaceptr.IsValid() || ifaceptr.Kind() != reflect.Ptr || ifaceptr.Elem().Kind() != reflect.Interface {
|
||||
return false, "ifaceptr should be a pointer to an interface variable"
|
||||
}
|
||||
return obtained.Type().Implements(ifaceptr.Elem().Type()), ""
|
||||
}
|
272
vendor/src/github.com/go-check/check/checkers_test.go
vendored
Normal file
272
vendor/src/github.com/go-check/check/checkers_test.go
vendored
Normal file
|
@ -0,0 +1,272 @@
|
|||
package check_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"gopkg.in/check.v1"
|
||||
"reflect"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type CheckersS struct{}
|
||||
|
||||
var _ = check.Suite(&CheckersS{})
|
||||
|
||||
func testInfo(c *check.C, checker check.Checker, name string, paramNames []string) {
|
||||
info := checker.Info()
|
||||
if info.Name != name {
|
||||
c.Fatalf("Got name %s, expected %s", info.Name, name)
|
||||
}
|
||||
if !reflect.DeepEqual(info.Params, paramNames) {
|
||||
c.Fatalf("Got param names %#v, expected %#v", info.Params, paramNames)
|
||||
}
|
||||
}
|
||||
|
||||
func testCheck(c *check.C, checker check.Checker, result bool, error string, params ...interface{}) ([]interface{}, []string) {
|
||||
info := checker.Info()
|
||||
if len(params) != len(info.Params) {
|
||||
c.Fatalf("unexpected param count in test; expected %d got %d", len(info.Params), len(params))
|
||||
}
|
||||
names := append([]string{}, info.Params...)
|
||||
result_, error_ := checker.Check(params, names)
|
||||
if result_ != result || error_ != error {
|
||||
c.Fatalf("%s.Check(%#v) returned (%#v, %#v) rather than (%#v, %#v)",
|
||||
info.Name, params, result_, error_, result, error)
|
||||
}
|
||||
return params, names
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestComment(c *check.C) {
|
||||
bug := check.Commentf("a %d bc", 42)
|
||||
comment := bug.CheckCommentString()
|
||||
if comment != "a 42 bc" {
|
||||
c.Fatalf("Commentf returned %#v", comment)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestIsNil(c *check.C) {
|
||||
testInfo(c, check.IsNil, "IsNil", []string{"value"})
|
||||
|
||||
testCheck(c, check.IsNil, true, "", nil)
|
||||
testCheck(c, check.IsNil, false, "", "a")
|
||||
|
||||
testCheck(c, check.IsNil, true, "", (chan int)(nil))
|
||||
testCheck(c, check.IsNil, false, "", make(chan int))
|
||||
testCheck(c, check.IsNil, true, "", (error)(nil))
|
||||
testCheck(c, check.IsNil, false, "", errors.New(""))
|
||||
testCheck(c, check.IsNil, true, "", ([]int)(nil))
|
||||
testCheck(c, check.IsNil, false, "", make([]int, 1))
|
||||
testCheck(c, check.IsNil, false, "", int(0))
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestNotNil(c *check.C) {
|
||||
testInfo(c, check.NotNil, "NotNil", []string{"value"})
|
||||
|
||||
testCheck(c, check.NotNil, false, "", nil)
|
||||
testCheck(c, check.NotNil, true, "", "a")
|
||||
|
||||
testCheck(c, check.NotNil, false, "", (chan int)(nil))
|
||||
testCheck(c, check.NotNil, true, "", make(chan int))
|
||||
testCheck(c, check.NotNil, false, "", (error)(nil))
|
||||
testCheck(c, check.NotNil, true, "", errors.New(""))
|
||||
testCheck(c, check.NotNil, false, "", ([]int)(nil))
|
||||
testCheck(c, check.NotNil, true, "", make([]int, 1))
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestNot(c *check.C) {
|
||||
testInfo(c, check.Not(check.IsNil), "Not(IsNil)", []string{"value"})
|
||||
|
||||
testCheck(c, check.Not(check.IsNil), false, "", nil)
|
||||
testCheck(c, check.Not(check.IsNil), true, "", "a")
|
||||
}
|
||||
|
||||
type simpleStruct struct {
|
||||
i int
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestEquals(c *check.C) {
|
||||
testInfo(c, check.Equals, "Equals", []string{"obtained", "expected"})
|
||||
|
||||
// The simplest.
|
||||
testCheck(c, check.Equals, true, "", 42, 42)
|
||||
testCheck(c, check.Equals, false, "", 42, 43)
|
||||
|
||||
// Different native types.
|
||||
testCheck(c, check.Equals, false, "", int32(42), int64(42))
|
||||
|
||||
// With nil.
|
||||
testCheck(c, check.Equals, false, "", 42, nil)
|
||||
|
||||
// Slices
|
||||
testCheck(c, check.Equals, false, "runtime error: comparing uncomparable type []uint8", []byte{1, 2}, []byte{1, 2})
|
||||
|
||||
// Struct values
|
||||
testCheck(c, check.Equals, true, "", simpleStruct{1}, simpleStruct{1})
|
||||
testCheck(c, check.Equals, false, "", simpleStruct{1}, simpleStruct{2})
|
||||
|
||||
// Struct pointers
|
||||
testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{1})
|
||||
testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{2})
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestDeepEquals(c *check.C) {
|
||||
testInfo(c, check.DeepEquals, "DeepEquals", []string{"obtained", "expected"})
|
||||
|
||||
// The simplest.
|
||||
testCheck(c, check.DeepEquals, true, "", 42, 42)
|
||||
testCheck(c, check.DeepEquals, false, "", 42, 43)
|
||||
|
||||
// Different native types.
|
||||
testCheck(c, check.DeepEquals, false, "", int32(42), int64(42))
|
||||
|
||||
// With nil.
|
||||
testCheck(c, check.DeepEquals, false, "", 42, nil)
|
||||
|
||||
// Slices
|
||||
testCheck(c, check.DeepEquals, true, "", []byte{1, 2}, []byte{1, 2})
|
||||
testCheck(c, check.DeepEquals, false, "", []byte{1, 2}, []byte{1, 3})
|
||||
|
||||
// Struct values
|
||||
testCheck(c, check.DeepEquals, true, "", simpleStruct{1}, simpleStruct{1})
|
||||
testCheck(c, check.DeepEquals, false, "", simpleStruct{1}, simpleStruct{2})
|
||||
|
||||
// Struct pointers
|
||||
testCheck(c, check.DeepEquals, true, "", &simpleStruct{1}, &simpleStruct{1})
|
||||
testCheck(c, check.DeepEquals, false, "", &simpleStruct{1}, &simpleStruct{2})
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestHasLen(c *check.C) {
|
||||
testInfo(c, check.HasLen, "HasLen", []string{"obtained", "n"})
|
||||
|
||||
testCheck(c, check.HasLen, true, "", "abcd", 4)
|
||||
testCheck(c, check.HasLen, true, "", []int{1, 2}, 2)
|
||||
testCheck(c, check.HasLen, false, "", []int{1, 2}, 3)
|
||||
|
||||
testCheck(c, check.HasLen, false, "n must be an int", []int{1, 2}, "2")
|
||||
testCheck(c, check.HasLen, false, "obtained value type has no length", nil, 2)
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestErrorMatches(c *check.C) {
|
||||
testInfo(c, check.ErrorMatches, "ErrorMatches", []string{"value", "regex"})
|
||||
|
||||
testCheck(c, check.ErrorMatches, false, "Error value is nil", nil, "some error")
|
||||
testCheck(c, check.ErrorMatches, false, "Value is not an error", 1, "some error")
|
||||
testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "some error")
|
||||
testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "so.*or")
|
||||
|
||||
// Verify params mutation
|
||||
params, names := testCheck(c, check.ErrorMatches, false, "", errors.New("some error"), "other error")
|
||||
c.Assert(params[0], check.Equals, "some error")
|
||||
c.Assert(names[0], check.Equals, "error")
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestMatches(c *check.C) {
|
||||
testInfo(c, check.Matches, "Matches", []string{"value", "regex"})
|
||||
|
||||
// Simple matching
|
||||
testCheck(c, check.Matches, true, "", "abc", "abc")
|
||||
testCheck(c, check.Matches, true, "", "abc", "a.c")
|
||||
|
||||
// Must match fully
|
||||
testCheck(c, check.Matches, false, "", "abc", "ab")
|
||||
testCheck(c, check.Matches, false, "", "abc", "bc")
|
||||
|
||||
// String()-enabled values accepted
|
||||
testCheck(c, check.Matches, true, "", reflect.ValueOf("abc"), "a.c")
|
||||
testCheck(c, check.Matches, false, "", reflect.ValueOf("abc"), "a.d")
|
||||
|
||||
// Some error conditions.
|
||||
testCheck(c, check.Matches, false, "Obtained value is not a string and has no .String()", 1, "a.c")
|
||||
testCheck(c, check.Matches, false, "Can't compile regex: error parsing regexp: missing closing ]: `[c$`", "abc", "a[c")
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestPanics(c *check.C) {
|
||||
testInfo(c, check.Panics, "Panics", []string{"function", "expected"})
|
||||
|
||||
// Some errors.
|
||||
testCheck(c, check.Panics, false, "Function has not panicked", func() bool { return false }, "BOOM")
|
||||
testCheck(c, check.Panics, false, "Function must take zero arguments", 1, "BOOM")
|
||||
|
||||
// Plain strings.
|
||||
testCheck(c, check.Panics, true, "", func() { panic("BOOM") }, "BOOM")
|
||||
testCheck(c, check.Panics, false, "", func() { panic("KABOOM") }, "BOOM")
|
||||
testCheck(c, check.Panics, true, "", func() bool { panic("BOOM") }, "BOOM")
|
||||
|
||||
// Error values.
|
||||
testCheck(c, check.Panics, true, "", func() { panic(errors.New("BOOM")) }, errors.New("BOOM"))
|
||||
testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM"))
|
||||
|
||||
type deep struct{ i int }
|
||||
// Deep value
|
||||
testCheck(c, check.Panics, true, "", func() { panic(&deep{99}) }, &deep{99})
|
||||
|
||||
// Verify params/names mutation
|
||||
params, names := testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM"))
|
||||
c.Assert(params[0], check.ErrorMatches, "KABOOM")
|
||||
c.Assert(names[0], check.Equals, "panic")
|
||||
|
||||
// Verify a nil panic
|
||||
testCheck(c, check.Panics, true, "", func() { panic(nil) }, nil)
|
||||
testCheck(c, check.Panics, false, "", func() { panic(nil) }, "NOPE")
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestPanicMatches(c *check.C) {
|
||||
testInfo(c, check.PanicMatches, "PanicMatches", []string{"function", "expected"})
|
||||
|
||||
// Error matching.
|
||||
testCheck(c, check.PanicMatches, true, "", func() { panic(errors.New("BOOM")) }, "BO.M")
|
||||
testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BO.M")
|
||||
|
||||
// Some errors.
|
||||
testCheck(c, check.PanicMatches, false, "Function has not panicked", func() bool { return false }, "BOOM")
|
||||
testCheck(c, check.PanicMatches, false, "Function must take zero arguments", 1, "BOOM")
|
||||
|
||||
// Plain strings.
|
||||
testCheck(c, check.PanicMatches, true, "", func() { panic("BOOM") }, "BO.M")
|
||||
testCheck(c, check.PanicMatches, false, "", func() { panic("KABOOM") }, "BOOM")
|
||||
testCheck(c, check.PanicMatches, true, "", func() bool { panic("BOOM") }, "BO.M")
|
||||
|
||||
// Verify params/names mutation
|
||||
params, names := testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BOOM")
|
||||
c.Assert(params[0], check.Equals, "KABOOM")
|
||||
c.Assert(names[0], check.Equals, "panic")
|
||||
|
||||
// Verify a nil panic
|
||||
testCheck(c, check.PanicMatches, false, "Panic value is not a string or an error", func() { panic(nil) }, "")
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestFitsTypeOf(c *check.C) {
|
||||
testInfo(c, check.FitsTypeOf, "FitsTypeOf", []string{"obtained", "sample"})
|
||||
|
||||
// Basic types
|
||||
testCheck(c, check.FitsTypeOf, true, "", 1, 0)
|
||||
testCheck(c, check.FitsTypeOf, false, "", 1, int64(0))
|
||||
|
||||
// Aliases
|
||||
testCheck(c, check.FitsTypeOf, false, "", 1, errors.New(""))
|
||||
testCheck(c, check.FitsTypeOf, false, "", "error", errors.New(""))
|
||||
testCheck(c, check.FitsTypeOf, true, "", errors.New("error"), errors.New(""))
|
||||
|
||||
// Structures
|
||||
testCheck(c, check.FitsTypeOf, false, "", 1, simpleStruct{})
|
||||
testCheck(c, check.FitsTypeOf, false, "", simpleStruct{42}, &simpleStruct{})
|
||||
testCheck(c, check.FitsTypeOf, true, "", simpleStruct{42}, simpleStruct{})
|
||||
testCheck(c, check.FitsTypeOf, true, "", &simpleStruct{42}, &simpleStruct{})
|
||||
|
||||
// Some bad values
|
||||
testCheck(c, check.FitsTypeOf, false, "Invalid sample value", 1, interface{}(nil))
|
||||
testCheck(c, check.FitsTypeOf, false, "", interface{}(nil), 0)
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestImplements(c *check.C) {
|
||||
testInfo(c, check.Implements, "Implements", []string{"obtained", "ifaceptr"})
|
||||
|
||||
var e error
|
||||
var re runtime.Error
|
||||
testCheck(c, check.Implements, true, "", errors.New(""), &e)
|
||||
testCheck(c, check.Implements, false, "", errors.New(""), &re)
|
||||
|
||||
// Some bad values
|
||||
testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, errors.New(""))
|
||||
testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, interface{}(nil))
|
||||
testCheck(c, check.Implements, false, "", interface{}(nil), &e)
|
||||
}
|
9
vendor/src/github.com/go-check/check/export_test.go
vendored
Normal file
9
vendor/src/github.com/go-check/check/export_test.go
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
package check
|
||||
|
||||
func PrintLine(filename string, line int) (string, error) {
|
||||
return printLine(filename, line)
|
||||
}
|
||||
|
||||
func Indent(s, with string) string {
|
||||
return indent(s, with)
|
||||
}
|
484
vendor/src/github.com/go-check/check/fixture_test.go
vendored
Normal file
484
vendor/src/github.com/go-check/check/fixture_test.go
vendored
Normal file
|
@ -0,0 +1,484 @@
|
|||
// Tests for the behavior of the test fixture system.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Fixture test suite.
|
||||
|
||||
type FixtureS struct{}
|
||||
|
||||
var fixtureS = Suite(&FixtureS{})
|
||||
|
||||
func (s *FixtureS) TestCountSuite(c *C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Basic fixture ordering verification.
|
||||
|
||||
func (s *FixtureS) TestOrder(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
Run(&helper, nil)
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[5], Equals, "Test2")
|
||||
c.Check(helper.calls[6], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[7], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 8)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Check the behavior when panics occur within tests and fixtures.
|
||||
|
||||
func (s *FixtureS) TestPanicOnTest(c *C) {
|
||||
helper := FixtureHelper{panicOn: "Test1"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[5], Equals, "Test2")
|
||||
c.Check(helper.calls[6], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[7], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 8)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: FixtureHelper.Test1\n\n" +
|
||||
"\\.\\.\\. Panic: Test1 \\(PC=[xA-F0-9]+\\)\n\n" +
|
||||
".+:[0-9]+\n" +
|
||||
" in (go)?panic\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.trace\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.Test1\n" +
|
||||
"(.|\n)*$"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnSetUpTest(c *C) {
|
||||
helper := FixtureHelper{panicOn: "SetUpTest"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[3], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 4)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: " +
|
||||
"FixtureHelper\\.SetUpTest\n\n" +
|
||||
"\\.\\.\\. Panic: SetUpTest \\(PC=[xA-F0-9]+\\)\n\n" +
|
||||
".+:[0-9]+\n" +
|
||||
" in (go)?panic\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.trace\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.SetUpTest\n" +
|
||||
"(.|\n)*" +
|
||||
"\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: " +
|
||||
"FixtureHelper\\.Test1\n\n" +
|
||||
"\\.\\.\\. Panic: Fixture has panicked " +
|
||||
"\\(see related PANIC\\)\n$"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnTearDownTest(c *C) {
|
||||
helper := FixtureHelper{panicOn: "TearDownTest"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 5)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: " +
|
||||
"FixtureHelper.TearDownTest\n\n" +
|
||||
"\\.\\.\\. Panic: TearDownTest \\(PC=[xA-F0-9]+\\)\n\n" +
|
||||
".+:[0-9]+\n" +
|
||||
" in (go)?panic\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.trace\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.TearDownTest\n" +
|
||||
"(.|\n)*" +
|
||||
"\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: " +
|
||||
"FixtureHelper\\.Test1\n\n" +
|
||||
"\\.\\.\\. Panic: Fixture has panicked " +
|
||||
"\\(see related PANIC\\)\n$"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnSetUpSuite(c *C) {
|
||||
helper := FixtureHelper{panicOn: "SetUpSuite"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 2)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: " +
|
||||
"FixtureHelper.SetUpSuite\n\n" +
|
||||
"\\.\\.\\. Panic: SetUpSuite \\(PC=[xA-F0-9]+\\)\n\n" +
|
||||
".+:[0-9]+\n" +
|
||||
" in (go)?panic\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.trace\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.SetUpSuite\n" +
|
||||
"(.|\n)*$"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnTearDownSuite(c *C) {
|
||||
helper := FixtureHelper{panicOn: "TearDownSuite"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[5], Equals, "Test2")
|
||||
c.Check(helper.calls[6], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[7], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 8)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: " +
|
||||
"FixtureHelper.TearDownSuite\n\n" +
|
||||
"\\.\\.\\. Panic: TearDownSuite \\(PC=[xA-F0-9]+\\)\n\n" +
|
||||
".+:[0-9]+\n" +
|
||||
" in (go)?panic\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.trace\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.TearDownSuite\n" +
|
||||
"(.|\n)*$"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// A wrong argument on a test or fixture will produce a nice error.
|
||||
|
||||
func (s *FixtureS) TestPanicOnWrongTestArg(c *C) {
|
||||
helper := WrongTestArgHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[3], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[4], Equals, "Test2")
|
||||
c.Check(helper.calls[5], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[6], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 7)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: fixture_test\\.go:[0-9]+: " +
|
||||
"WrongTestArgHelper\\.Test1\n\n" +
|
||||
"\\.\\.\\. Panic: WrongTestArgHelper\\.Test1 argument " +
|
||||
"should be \\*check\\.C\n"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnWrongSetUpTestArg(c *C) {
|
||||
helper := WrongSetUpTestArgHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(len(helper.calls), Equals, 0)
|
||||
|
||||
expected :=
|
||||
"^\n-+\n" +
|
||||
"PANIC: fixture_test\\.go:[0-9]+: " +
|
||||
"WrongSetUpTestArgHelper\\.SetUpTest\n\n" +
|
||||
"\\.\\.\\. Panic: WrongSetUpTestArgHelper\\.SetUpTest argument " +
|
||||
"should be \\*check\\.C\n"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnWrongSetUpSuiteArg(c *C) {
|
||||
helper := WrongSetUpSuiteArgHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(len(helper.calls), Equals, 0)
|
||||
|
||||
expected :=
|
||||
"^\n-+\n" +
|
||||
"PANIC: fixture_test\\.go:[0-9]+: " +
|
||||
"WrongSetUpSuiteArgHelper\\.SetUpSuite\n\n" +
|
||||
"\\.\\.\\. Panic: WrongSetUpSuiteArgHelper\\.SetUpSuite argument " +
|
||||
"should be \\*check\\.C\n"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Nice errors also when tests or fixture have wrong arg count.
|
||||
|
||||
func (s *FixtureS) TestPanicOnWrongTestArgCount(c *C) {
|
||||
helper := WrongTestArgCountHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[3], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[4], Equals, "Test2")
|
||||
c.Check(helper.calls[5], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[6], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 7)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: fixture_test\\.go:[0-9]+: " +
|
||||
"WrongTestArgCountHelper\\.Test1\n\n" +
|
||||
"\\.\\.\\. Panic: WrongTestArgCountHelper\\.Test1 argument " +
|
||||
"should be \\*check\\.C\n"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnWrongSetUpTestArgCount(c *C) {
|
||||
helper := WrongSetUpTestArgCountHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(len(helper.calls), Equals, 0)
|
||||
|
||||
expected :=
|
||||
"^\n-+\n" +
|
||||
"PANIC: fixture_test\\.go:[0-9]+: " +
|
||||
"WrongSetUpTestArgCountHelper\\.SetUpTest\n\n" +
|
||||
"\\.\\.\\. Panic: WrongSetUpTestArgCountHelper\\.SetUpTest argument " +
|
||||
"should be \\*check\\.C\n"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnWrongSetUpSuiteArgCount(c *C) {
|
||||
helper := WrongSetUpSuiteArgCountHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(len(helper.calls), Equals, 0)
|
||||
|
||||
expected :=
|
||||
"^\n-+\n" +
|
||||
"PANIC: fixture_test\\.go:[0-9]+: " +
|
||||
"WrongSetUpSuiteArgCountHelper\\.SetUpSuite\n\n" +
|
||||
"\\.\\.\\. Panic: WrongSetUpSuiteArgCountHelper" +
|
||||
"\\.SetUpSuite argument should be \\*check\\.C\n"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper test suites with wrong function arguments.
|
||||
|
||||
type WrongTestArgHelper struct {
|
||||
FixtureHelper
|
||||
}
|
||||
|
||||
func (s *WrongTestArgHelper) Test1(t int) {
|
||||
}
|
||||
|
||||
type WrongSetUpTestArgHelper struct {
|
||||
FixtureHelper
|
||||
}
|
||||
|
||||
func (s *WrongSetUpTestArgHelper) SetUpTest(t int) {
|
||||
}
|
||||
|
||||
type WrongSetUpSuiteArgHelper struct {
|
||||
FixtureHelper
|
||||
}
|
||||
|
||||
func (s *WrongSetUpSuiteArgHelper) SetUpSuite(t int) {
|
||||
}
|
||||
|
||||
type WrongTestArgCountHelper struct {
|
||||
FixtureHelper
|
||||
}
|
||||
|
||||
func (s *WrongTestArgCountHelper) Test1(c *C, i int) {
|
||||
}
|
||||
|
||||
type WrongSetUpTestArgCountHelper struct {
|
||||
FixtureHelper
|
||||
}
|
||||
|
||||
func (s *WrongSetUpTestArgCountHelper) SetUpTest(c *C, i int) {
|
||||
}
|
||||
|
||||
type WrongSetUpSuiteArgCountHelper struct {
|
||||
FixtureHelper
|
||||
}
|
||||
|
||||
func (s *WrongSetUpSuiteArgCountHelper) SetUpSuite(c *C, i int) {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Ensure fixture doesn't run without tests.
|
||||
|
||||
type NoTestsHelper struct {
|
||||
hasRun bool
|
||||
}
|
||||
|
||||
func (s *NoTestsHelper) SetUpSuite(c *C) {
|
||||
s.hasRun = true
|
||||
}
|
||||
|
||||
func (s *NoTestsHelper) TearDownSuite(c *C) {
|
||||
s.hasRun = true
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestFixtureDoesntRunWithoutTests(c *C) {
|
||||
helper := NoTestsHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.hasRun, Equals, false)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify that checks and assertions work correctly inside the fixture.
|
||||
|
||||
type FixtureCheckHelper struct {
|
||||
fail string
|
||||
completed bool
|
||||
}
|
||||
|
||||
func (s *FixtureCheckHelper) SetUpSuite(c *C) {
|
||||
switch s.fail {
|
||||
case "SetUpSuiteAssert":
|
||||
c.Assert(false, Equals, true)
|
||||
case "SetUpSuiteCheck":
|
||||
c.Check(false, Equals, true)
|
||||
}
|
||||
s.completed = true
|
||||
}
|
||||
|
||||
func (s *FixtureCheckHelper) SetUpTest(c *C) {
|
||||
switch s.fail {
|
||||
case "SetUpTestAssert":
|
||||
c.Assert(false, Equals, true)
|
||||
case "SetUpTestCheck":
|
||||
c.Check(false, Equals, true)
|
||||
}
|
||||
s.completed = true
|
||||
}
|
||||
|
||||
func (s *FixtureCheckHelper) Test(c *C) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestSetUpSuiteCheck(c *C) {
|
||||
helper := FixtureCheckHelper{fail: "SetUpSuiteCheck"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Assert(output.value, Matches,
|
||||
"\n---+\n"+
|
||||
"FAIL: fixture_test\\.go:[0-9]+: "+
|
||||
"FixtureCheckHelper\\.SetUpSuite\n\n"+
|
||||
"fixture_test\\.go:[0-9]+:\n"+
|
||||
" c\\.Check\\(false, Equals, true\\)\n"+
|
||||
"\\.+ obtained bool = false\n"+
|
||||
"\\.+ expected bool = true\n\n")
|
||||
c.Assert(helper.completed, Equals, true)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestSetUpSuiteAssert(c *C) {
|
||||
helper := FixtureCheckHelper{fail: "SetUpSuiteAssert"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Assert(output.value, Matches,
|
||||
"\n---+\n"+
|
||||
"FAIL: fixture_test\\.go:[0-9]+: "+
|
||||
"FixtureCheckHelper\\.SetUpSuite\n\n"+
|
||||
"fixture_test\\.go:[0-9]+:\n"+
|
||||
" c\\.Assert\\(false, Equals, true\\)\n"+
|
||||
"\\.+ obtained bool = false\n"+
|
||||
"\\.+ expected bool = true\n\n")
|
||||
c.Assert(helper.completed, Equals, false)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify that logging within SetUpTest() persists within the test log itself.
|
||||
|
||||
type FixtureLogHelper struct {
|
||||
c *C
|
||||
}
|
||||
|
||||
func (s *FixtureLogHelper) SetUpTest(c *C) {
|
||||
s.c = c
|
||||
c.Log("1")
|
||||
}
|
||||
|
||||
func (s *FixtureLogHelper) Test(c *C) {
|
||||
c.Log("2")
|
||||
s.c.Log("3")
|
||||
c.Log("4")
|
||||
c.Fail()
|
||||
}
|
||||
|
||||
func (s *FixtureLogHelper) TearDownTest(c *C) {
|
||||
s.c.Log("5")
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestFixtureLogging(c *C) {
|
||||
helper := FixtureLogHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Assert(output.value, Matches,
|
||||
"\n---+\n"+
|
||||
"FAIL: fixture_test\\.go:[0-9]+: "+
|
||||
"FixtureLogHelper\\.Test\n\n"+
|
||||
"1\n2\n3\n4\n5\n")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Skip() within fixture methods.
|
||||
|
||||
func (s *FixtureS) TestSkipSuite(c *C) {
|
||||
helper := FixtureHelper{skip: true, skipOnN: 0}
|
||||
output := String{}
|
||||
result := Run(&helper, &RunConf{Output: &output})
|
||||
c.Assert(output.value, Equals, "")
|
||||
c.Assert(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Assert(helper.calls[1], Equals, "TearDownSuite")
|
||||
c.Assert(len(helper.calls), Equals, 2)
|
||||
c.Assert(result.Skipped, Equals, 2)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestSkipTest(c *C) {
|
||||
helper := FixtureHelper{skip: true, skipOnN: 1}
|
||||
output := String{}
|
||||
result := Run(&helper, &RunConf{Output: &output})
|
||||
c.Assert(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Assert(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Assert(helper.calls[2], Equals, "SetUpTest")
|
||||
c.Assert(helper.calls[3], Equals, "Test2")
|
||||
c.Assert(helper.calls[4], Equals, "TearDownTest")
|
||||
c.Assert(helper.calls[5], Equals, "TearDownSuite")
|
||||
c.Assert(len(helper.calls), Equals, 6)
|
||||
c.Assert(result.Skipped, Equals, 1)
|
||||
}
|
335
vendor/src/github.com/go-check/check/foundation_test.go
vendored
Normal file
335
vendor/src/github.com/go-check/check/foundation_test.go
vendored
Normal file
|
@ -0,0 +1,335 @@
|
|||
// These tests check that the foundations of gocheck are working properly.
|
||||
// They already assume that fundamental failing is working already, though,
|
||||
// since this was tested in bootstrap_test.go. Even then, some care may
|
||||
// still have to be taken when using external functions, since they should
|
||||
// of course not rely on functionality tested here.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gopkg.in/check.v1"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Foundation test suite.
|
||||
|
||||
type FoundationS struct{}
|
||||
|
||||
var foundationS = check.Suite(&FoundationS{})
|
||||
|
||||
func (s *FoundationS) TestCountSuite(c *check.C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestErrorf(c *check.C) {
|
||||
// Do not use checkState() here. It depends on Errorf() working.
|
||||
expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+
|
||||
" c.Errorf(\"Error %%v!\", \"message\")\n"+
|
||||
"... Error: Error message!\n\n",
|
||||
getMyLine()+1)
|
||||
c.Errorf("Error %v!", "message")
|
||||
failed := c.Failed()
|
||||
c.Succeed()
|
||||
if log := c.GetTestLog(); log != expectedLog {
|
||||
c.Logf("Errorf() logged %#v rather than %#v", log, expectedLog)
|
||||
c.Fail()
|
||||
}
|
||||
if !failed {
|
||||
c.Logf("Errorf() didn't put the test in a failed state")
|
||||
c.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestError(c *check.C) {
|
||||
expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+
|
||||
" c\\.Error\\(\"Error \", \"message!\"\\)\n"+
|
||||
"\\.\\.\\. Error: Error message!\n\n",
|
||||
getMyLine()+1)
|
||||
c.Error("Error ", "message!")
|
||||
checkState(c, nil,
|
||||
&expectedState{
|
||||
name: "Error(`Error `, `message!`)",
|
||||
failed: true,
|
||||
log: expectedLog,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestFailNow(c *check.C) {
|
||||
defer (func() {
|
||||
if !c.Failed() {
|
||||
c.Error("FailNow() didn't fail the test")
|
||||
} else {
|
||||
c.Succeed()
|
||||
if c.GetTestLog() != "" {
|
||||
c.Error("Something got logged:\n" + c.GetTestLog())
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
c.FailNow()
|
||||
c.Log("FailNow() didn't stop the test")
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestSucceedNow(c *check.C) {
|
||||
defer (func() {
|
||||
if c.Failed() {
|
||||
c.Error("SucceedNow() didn't succeed the test")
|
||||
}
|
||||
if c.GetTestLog() != "" {
|
||||
c.Error("Something got logged:\n" + c.GetTestLog())
|
||||
}
|
||||
})()
|
||||
|
||||
c.Fail()
|
||||
c.SucceedNow()
|
||||
c.Log("SucceedNow() didn't stop the test")
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestFailureHeader(c *check.C) {
|
||||
output := String{}
|
||||
failHelper := FailHelper{}
|
||||
check.Run(&failHelper, &check.RunConf{Output: &output})
|
||||
header := fmt.Sprintf(""+
|
||||
"\n-----------------------------------"+
|
||||
"-----------------------------------\n"+
|
||||
"FAIL: check_test.go:%d: FailHelper.TestLogAndFail\n",
|
||||
failHelper.testLine)
|
||||
if strings.Index(output.value, header) == -1 {
|
||||
c.Errorf(""+
|
||||
"Failure didn't print a proper header.\n"+
|
||||
"... Got:\n%s... Expected something with:\n%s",
|
||||
output.value, header)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestFatal(c *check.C) {
|
||||
var line int
|
||||
defer (func() {
|
||||
if !c.Failed() {
|
||||
c.Error("Fatal() didn't fail the test")
|
||||
} else {
|
||||
c.Succeed()
|
||||
expected := fmt.Sprintf("foundation_test.go:%d:\n"+
|
||||
" c.Fatal(\"Die \", \"now!\")\n"+
|
||||
"... Error: Die now!\n\n",
|
||||
line)
|
||||
if c.GetTestLog() != expected {
|
||||
c.Error("Incorrect log:", c.GetTestLog())
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
line = getMyLine() + 1
|
||||
c.Fatal("Die ", "now!")
|
||||
c.Log("Fatal() didn't stop the test")
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestFatalf(c *check.C) {
|
||||
var line int
|
||||
defer (func() {
|
||||
if !c.Failed() {
|
||||
c.Error("Fatalf() didn't fail the test")
|
||||
} else {
|
||||
c.Succeed()
|
||||
expected := fmt.Sprintf("foundation_test.go:%d:\n"+
|
||||
" c.Fatalf(\"Die %%s!\", \"now\")\n"+
|
||||
"... Error: Die now!\n\n",
|
||||
line)
|
||||
if c.GetTestLog() != expected {
|
||||
c.Error("Incorrect log:", c.GetTestLog())
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
line = getMyLine() + 1
|
||||
c.Fatalf("Die %s!", "now")
|
||||
c.Log("Fatalf() didn't stop the test")
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestCallerLoggingInsideTest(c *check.C) {
|
||||
log := fmt.Sprintf(""+
|
||||
"foundation_test.go:%d:\n"+
|
||||
" result := c.Check\\(10, check.Equals, 20\\)\n"+
|
||||
"\\.\\.\\. obtained int = 10\n"+
|
||||
"\\.\\.\\. expected int = 20\n\n",
|
||||
getMyLine()+1)
|
||||
result := c.Check(10, check.Equals, 20)
|
||||
checkState(c, result,
|
||||
&expectedState{
|
||||
name: "Check(10, Equals, 20)",
|
||||
result: false,
|
||||
failed: true,
|
||||
log: log,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestCallerLoggingInDifferentFile(c *check.C) {
|
||||
result, line := checkEqualWrapper(c, 10, 20)
|
||||
testLine := getMyLine() - 1
|
||||
log := fmt.Sprintf(""+
|
||||
"foundation_test.go:%d:\n"+
|
||||
" result, line := checkEqualWrapper\\(c, 10, 20\\)\n"+
|
||||
"check_test.go:%d:\n"+
|
||||
" return c.Check\\(obtained, check.Equals, expected\\), getMyLine\\(\\)\n"+
|
||||
"\\.\\.\\. obtained int = 10\n"+
|
||||
"\\.\\.\\. expected int = 20\n\n",
|
||||
testLine, line)
|
||||
checkState(c, result,
|
||||
&expectedState{
|
||||
name: "Check(10, Equals, 20)",
|
||||
result: false,
|
||||
failed: true,
|
||||
log: log,
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// ExpectFailure() inverts the logic of failure.
|
||||
|
||||
type ExpectFailureSucceedHelper struct{}
|
||||
|
||||
func (s *ExpectFailureSucceedHelper) TestSucceed(c *check.C) {
|
||||
c.ExpectFailure("It booms!")
|
||||
c.Error("Boom!")
|
||||
}
|
||||
|
||||
type ExpectFailureFailHelper struct{}
|
||||
|
||||
func (s *ExpectFailureFailHelper) TestFail(c *check.C) {
|
||||
c.ExpectFailure("Bug #XYZ")
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestExpectFailureFail(c *check.C) {
|
||||
helper := ExpectFailureFailHelper{}
|
||||
output := String{}
|
||||
result := check.Run(&helper, &check.RunConf{Output: &output})
|
||||
|
||||
expected := "" +
|
||||
"^\n-+\n" +
|
||||
"FAIL: foundation_test\\.go:[0-9]+:" +
|
||||
" ExpectFailureFailHelper\\.TestFail\n\n" +
|
||||
"\\.\\.\\. Error: Test succeeded, but was expected to fail\n" +
|
||||
"\\.\\.\\. Reason: Bug #XYZ\n$"
|
||||
|
||||
matched, err := regexp.MatchString(expected, output.value)
|
||||
if err != nil {
|
||||
c.Error("Bad expression: ", expected)
|
||||
} else if !matched {
|
||||
c.Error("ExpectFailure() didn't log properly:\n", output.value)
|
||||
}
|
||||
|
||||
c.Assert(result.ExpectedFailures, check.Equals, 0)
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestExpectFailureSucceed(c *check.C) {
|
||||
helper := ExpectFailureSucceedHelper{}
|
||||
output := String{}
|
||||
result := check.Run(&helper, &check.RunConf{Output: &output})
|
||||
|
||||
c.Assert(output.value, check.Equals, "")
|
||||
c.Assert(result.ExpectedFailures, check.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestExpectFailureSucceedVerbose(c *check.C) {
|
||||
helper := ExpectFailureSucceedHelper{}
|
||||
output := String{}
|
||||
result := check.Run(&helper, &check.RunConf{Output: &output, Verbose: true})
|
||||
|
||||
expected := "" +
|
||||
"FAIL EXPECTED: foundation_test\\.go:[0-9]+:" +
|
||||
" ExpectFailureSucceedHelper\\.TestSucceed \\(It booms!\\)\t *[.0-9]+s\n"
|
||||
|
||||
matched, err := regexp.MatchString(expected, output.value)
|
||||
if err != nil {
|
||||
c.Error("Bad expression: ", expected)
|
||||
} else if !matched {
|
||||
c.Error("ExpectFailure() didn't log properly:\n", output.value)
|
||||
}
|
||||
|
||||
c.Assert(result.ExpectedFailures, check.Equals, 1)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Skip() allows stopping a test without positive/negative results.
|
||||
|
||||
type SkipTestHelper struct{}
|
||||
|
||||
func (s *SkipTestHelper) TestFail(c *check.C) {
|
||||
c.Skip("Wrong platform or whatever")
|
||||
c.Error("Boom!")
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestSkip(c *check.C) {
|
||||
helper := SkipTestHelper{}
|
||||
output := String{}
|
||||
check.Run(&helper, &check.RunConf{Output: &output})
|
||||
|
||||
if output.value != "" {
|
||||
c.Error("Skip() logged something:\n", output.value)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestSkipVerbose(c *check.C) {
|
||||
helper := SkipTestHelper{}
|
||||
output := String{}
|
||||
check.Run(&helper, &check.RunConf{Output: &output, Verbose: true})
|
||||
|
||||
expected := "SKIP: foundation_test\\.go:[0-9]+: SkipTestHelper\\.TestFail" +
|
||||
" \\(Wrong platform or whatever\\)"
|
||||
matched, err := regexp.MatchString(expected, output.value)
|
||||
if err != nil {
|
||||
c.Error("Bad expression: ", expected)
|
||||
} else if !matched {
|
||||
c.Error("Skip() didn't log properly:\n", output.value)
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Check minimum *log.Logger interface provided by *check.C.
|
||||
|
||||
type minLogger interface {
|
||||
Output(calldepth int, s string) error
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestMinLogger(c *check.C) {
|
||||
var logger minLogger
|
||||
logger = log.New(os.Stderr, "", 0)
|
||||
logger = c
|
||||
logger.Output(0, "Hello there")
|
||||
expected := `\[LOG\] [0-9]+:[0-9][0-9]\.[0-9][0-9][0-9] +Hello there\n`
|
||||
output := c.GetTestLog()
|
||||
c.Assert(output, check.Matches, expected)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Ensure that suites with embedded types are working fine, including the
|
||||
// the workaround for issue 906.
|
||||
|
||||
type EmbeddedInternalS struct {
|
||||
called bool
|
||||
}
|
||||
|
||||
type EmbeddedS struct {
|
||||
EmbeddedInternalS
|
||||
}
|
||||
|
||||
var embeddedS = check.Suite(&EmbeddedS{})
|
||||
|
||||
func (s *EmbeddedS) TestCountSuite(c *check.C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
func (s *EmbeddedInternalS) TestMethod(c *check.C) {
|
||||
c.Error("TestMethod() of the embedded type was called!?")
|
||||
}
|
||||
|
||||
func (s *EmbeddedS) TestMethod(c *check.C) {
|
||||
// http://code.google.com/p/go/issues/detail?id=906
|
||||
c.Check(s.called, check.Equals, false) // Go issue 906 is affecting the runner?
|
||||
s.called = true
|
||||
}
|
231
vendor/src/github.com/go-check/check/helpers.go
vendored
Normal file
231
vendor/src/github.com/go-check/check/helpers.go
vendored
Normal file
|
@ -0,0 +1,231 @@
|
|||
package check
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestName returns the current test name in the form "SuiteName.TestName"
|
||||
func (c *C) TestName() string {
|
||||
return c.testName
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Basic succeeding/failing logic.
|
||||
|
||||
// Failed returns whether the currently running test has already failed.
|
||||
func (c *C) Failed() bool {
|
||||
return c.status == failedSt
|
||||
}
|
||||
|
||||
// Fail marks the currently running test as failed.
|
||||
//
|
||||
// Something ought to have been previously logged so the developer can tell
|
||||
// what went wrong. The higher level helper functions will fail the test
|
||||
// and do the logging properly.
|
||||
func (c *C) Fail() {
|
||||
c.status = failedSt
|
||||
}
|
||||
|
||||
// FailNow marks the currently running test as failed and stops running it.
|
||||
// Something ought to have been previously logged so the developer can tell
|
||||
// what went wrong. The higher level helper functions will fail the test
|
||||
// and do the logging properly.
|
||||
func (c *C) FailNow() {
|
||||
c.Fail()
|
||||
c.stopNow()
|
||||
}
|
||||
|
||||
// Succeed marks the currently running test as succeeded, undoing any
|
||||
// previous failures.
|
||||
func (c *C) Succeed() {
|
||||
c.status = succeededSt
|
||||
}
|
||||
|
||||
// SucceedNow marks the currently running test as succeeded, undoing any
|
||||
// previous failures, and stops running the test.
|
||||
func (c *C) SucceedNow() {
|
||||
c.Succeed()
|
||||
c.stopNow()
|
||||
}
|
||||
|
||||
// ExpectFailure informs that the running test is knowingly broken for
|
||||
// the provided reason. If the test does not fail, an error will be reported
|
||||
// to raise attention to this fact. This method is useful to temporarily
|
||||
// disable tests which cover well known problems until a better time to
|
||||
// fix the problem is found, without forgetting about the fact that a
|
||||
// failure still exists.
|
||||
func (c *C) ExpectFailure(reason string) {
|
||||
if reason == "" {
|
||||
panic("Missing reason why the test is expected to fail")
|
||||
}
|
||||
c.mustFail = true
|
||||
c.reason = reason
|
||||
}
|
||||
|
||||
// Skip skips the running test for the provided reason. If run from within
|
||||
// SetUpTest, the individual test being set up will be skipped, and if run
|
||||
// from within SetUpSuite, the whole suite is skipped.
|
||||
func (c *C) Skip(reason string) {
|
||||
if reason == "" {
|
||||
panic("Missing reason why the test is being skipped")
|
||||
}
|
||||
c.reason = reason
|
||||
c.status = skippedSt
|
||||
c.stopNow()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Basic logging.
|
||||
|
||||
// GetTestLog returns the current test error output.
|
||||
func (c *C) GetTestLog() string {
|
||||
return c.logb.String()
|
||||
}
|
||||
|
||||
// Log logs some information into the test error output.
|
||||
// The provided arguments are assembled together into a string with fmt.Sprint.
|
||||
func (c *C) Log(args ...interface{}) {
|
||||
c.log(args...)
|
||||
}
|
||||
|
||||
// Log logs some information into the test error output.
|
||||
// The provided arguments are assembled together into a string with fmt.Sprintf.
|
||||
func (c *C) Logf(format string, args ...interface{}) {
|
||||
c.logf(format, args...)
|
||||
}
|
||||
|
||||
// Output enables *C to be used as a logger in functions that require only
|
||||
// the minimum interface of *log.Logger.
|
||||
func (c *C) Output(calldepth int, s string) error {
|
||||
d := time.Now().Sub(c.startTime)
|
||||
msec := d / time.Millisecond
|
||||
sec := d / time.Second
|
||||
min := d / time.Minute
|
||||
|
||||
c.Logf("[LOG] %d:%02d.%03d %s", min, sec%60, msec%1000, s)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Error logs an error into the test error output and marks the test as failed.
|
||||
// The provided arguments are assembled together into a string with fmt.Sprint.
|
||||
func (c *C) Error(args ...interface{}) {
|
||||
c.logCaller(1)
|
||||
c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...)))
|
||||
c.logNewLine()
|
||||
c.Fail()
|
||||
}
|
||||
|
||||
// Errorf logs an error into the test error output and marks the test as failed.
|
||||
// The provided arguments are assembled together into a string with fmt.Sprintf.
|
||||
func (c *C) Errorf(format string, args ...interface{}) {
|
||||
c.logCaller(1)
|
||||
c.logString(fmt.Sprintf("Error: "+format, args...))
|
||||
c.logNewLine()
|
||||
c.Fail()
|
||||
}
|
||||
|
||||
// Fatal logs an error into the test error output, marks the test as failed, and
|
||||
// stops the test execution. The provided arguments are assembled together into
|
||||
// a string with fmt.Sprint.
|
||||
func (c *C) Fatal(args ...interface{}) {
|
||||
c.logCaller(1)
|
||||
c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...)))
|
||||
c.logNewLine()
|
||||
c.FailNow()
|
||||
}
|
||||
|
||||
// Fatlaf logs an error into the test error output, marks the test as failed, and
|
||||
// stops the test execution. The provided arguments are assembled together into
|
||||
// a string with fmt.Sprintf.
|
||||
func (c *C) Fatalf(format string, args ...interface{}) {
|
||||
c.logCaller(1)
|
||||
c.logString(fmt.Sprint("Error: ", fmt.Sprintf(format, args...)))
|
||||
c.logNewLine()
|
||||
c.FailNow()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Generic checks and assertions based on checkers.
|
||||
|
||||
// Check verifies if the first value matches the expected value according
|
||||
// to the provided checker. If they do not match, an error is logged, the
|
||||
// test is marked as failed, and the test execution continues.
|
||||
//
|
||||
// Some checkers may not need the expected argument (e.g. IsNil).
|
||||
//
|
||||
// Extra arguments provided to the function are logged next to the reported
|
||||
// problem when the matching fails.
|
||||
func (c *C) Check(obtained interface{}, checker Checker, args ...interface{}) bool {
|
||||
return c.internalCheck("Check", obtained, checker, args...)
|
||||
}
|
||||
|
||||
// Assert ensures that the first value matches the expected value according
|
||||
// to the provided checker. If they do not match, an error is logged, the
|
||||
// test is marked as failed, and the test execution stops.
|
||||
//
|
||||
// Some checkers may not need the expected argument (e.g. IsNil).
|
||||
//
|
||||
// Extra arguments provided to the function are logged next to the reported
|
||||
// problem when the matching fails.
|
||||
func (c *C) Assert(obtained interface{}, checker Checker, args ...interface{}) {
|
||||
if !c.internalCheck("Assert", obtained, checker, args...) {
|
||||
c.stopNow()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *C) internalCheck(funcName string, obtained interface{}, checker Checker, args ...interface{}) bool {
|
||||
if checker == nil {
|
||||
c.logCaller(2)
|
||||
c.logString(fmt.Sprintf("%s(obtained, nil!?, ...):", funcName))
|
||||
c.logString("Oops.. you've provided a nil checker!")
|
||||
c.logNewLine()
|
||||
c.Fail()
|
||||
return false
|
||||
}
|
||||
|
||||
// If the last argument is a bug info, extract it out.
|
||||
var comment CommentInterface
|
||||
if len(args) > 0 {
|
||||
if c, ok := args[len(args)-1].(CommentInterface); ok {
|
||||
comment = c
|
||||
args = args[:len(args)-1]
|
||||
}
|
||||
}
|
||||
|
||||
params := append([]interface{}{obtained}, args...)
|
||||
info := checker.Info()
|
||||
|
||||
if len(params) != len(info.Params) {
|
||||
names := append([]string{info.Params[0], info.Name}, info.Params[1:]...)
|
||||
c.logCaller(2)
|
||||
c.logString(fmt.Sprintf("%s(%s):", funcName, strings.Join(names, ", ")))
|
||||
c.logString(fmt.Sprintf("Wrong number of parameters for %s: want %d, got %d", info.Name, len(names), len(params)+1))
|
||||
c.logNewLine()
|
||||
c.Fail()
|
||||
return false
|
||||
}
|
||||
|
||||
// Copy since it may be mutated by Check.
|
||||
names := append([]string{}, info.Params...)
|
||||
|
||||
// Do the actual check.
|
||||
result, error := checker.Check(params, names)
|
||||
if !result || error != "" {
|
||||
c.logCaller(2)
|
||||
for i := 0; i != len(params); i++ {
|
||||
c.logValue(names[i], params[i])
|
||||
}
|
||||
if comment != nil {
|
||||
c.logString(comment.CheckCommentString())
|
||||
}
|
||||
if error != "" {
|
||||
c.logString(error)
|
||||
}
|
||||
c.logNewLine()
|
||||
c.Fail()
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
519
vendor/src/github.com/go-check/check/helpers_test.go
vendored
Normal file
519
vendor/src/github.com/go-check/check/helpers_test.go
vendored
Normal file
|
@ -0,0 +1,519 @@
|
|||
// These tests verify the inner workings of the helper methods associated
|
||||
// with check.T.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"gopkg.in/check.v1"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var helpersS = check.Suite(&HelpersS{})
|
||||
|
||||
type HelpersS struct{}
|
||||
|
||||
func (s *HelpersS) TestCountSuite(c *check.C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Fake checker and bug info to verify the behavior of Assert() and Check().
|
||||
|
||||
type MyChecker struct {
|
||||
info *check.CheckerInfo
|
||||
params []interface{}
|
||||
names []string
|
||||
result bool
|
||||
error string
|
||||
}
|
||||
|
||||
func (checker *MyChecker) Info() *check.CheckerInfo {
|
||||
if checker.info == nil {
|
||||
return &check.CheckerInfo{Name: "MyChecker", Params: []string{"myobtained", "myexpected"}}
|
||||
}
|
||||
return checker.info
|
||||
}
|
||||
|
||||
func (checker *MyChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
rparams := checker.params
|
||||
rnames := checker.names
|
||||
checker.params = append([]interface{}{}, params...)
|
||||
checker.names = append([]string{}, names...)
|
||||
if rparams != nil {
|
||||
copy(params, rparams)
|
||||
}
|
||||
if rnames != nil {
|
||||
copy(names, rnames)
|
||||
}
|
||||
return checker.result, checker.error
|
||||
}
|
||||
|
||||
type myCommentType string
|
||||
|
||||
func (c myCommentType) CheckCommentString() string {
|
||||
return string(c)
|
||||
}
|
||||
|
||||
func myComment(s string) myCommentType {
|
||||
return myCommentType(s)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Ensure a real checker actually works fine.
|
||||
|
||||
func (s *HelpersS) TestCheckerInterface(c *check.C) {
|
||||
testHelperSuccess(c, "Check(1, Equals, 1)", true, func() interface{} {
|
||||
return c.Check(1, check.Equals, 1)
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Tests for Check(), mostly the same as for Assert() following these.
|
||||
|
||||
func (s *HelpersS) TestCheckSucceedWithExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true}
|
||||
testHelperSuccess(c, "Check(1, checker, 2)", true, func() interface{} {
|
||||
return c.Check(1, checker, 2)
|
||||
})
|
||||
if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) {
|
||||
c.Fatalf("Bad params for check: %#v", checker.params)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckSucceedWithoutExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
|
||||
testHelperSuccess(c, "Check(1, checker)", true, func() interface{} {
|
||||
return c.Check(1, checker)
|
||||
})
|
||||
if !reflect.DeepEqual(checker.params, []interface{}{1}) {
|
||||
c.Fatalf("Bad params for check: %#v", checker.params)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckFailWithExpected(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker, 2\\)\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, 2)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker, 2)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckFailWithExpectedAndComment(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n" +
|
||||
"\\.+ Hello world!\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker, 2, myComment("Hello world!"))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckFailWithExpectedAndStaticComment(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" // Nice leading comment\\.\n" +
|
||||
" return c\\.Check\\(1, checker, 2\\) // Hello there\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log,
|
||||
func() interface{} {
|
||||
// Nice leading comment.
|
||||
return c.Check(1, checker, 2) // Hello there
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckFailWithoutExpected(c *check.C) {
|
||||
checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker\\)\n" +
|
||||
"\\.+ myvalue int = 1\n\n"
|
||||
testHelperFailure(c, "Check(1, checker)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckFailWithoutExpectedAndMessage(c *check.C) {
|
||||
checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" +
|
||||
"\\.+ myvalue int = 1\n" +
|
||||
"\\.+ Hello world!\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, msg)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker, myComment("Hello world!"))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckWithMissingExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker\\)\n" +
|
||||
"\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" +
|
||||
"\\.+ Wrong number of parameters for MyChecker: " +
|
||||
"want 3, got 2\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, !?)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckWithTooManyExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker, 2, 3\\)\n" +
|
||||
"\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" +
|
||||
"\\.+ Wrong number of parameters for MyChecker: " +
|
||||
"want 3, got 4\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, 2, 3)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker, 2, 3)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckWithError(c *check.C) {
|
||||
checker := &MyChecker{result: false, error: "Some not so cool data provided!"}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker, 2\\)\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n" +
|
||||
"\\.+ Some not so cool data provided!\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, 2)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker, 2)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckWithNilChecker(c *check.C) {
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, nil\\)\n" +
|
||||
"\\.+ Check\\(obtained, nil!\\?, \\.\\.\\.\\):\n" +
|
||||
"\\.+ Oops\\.\\. you've provided a nil checker!\n\n"
|
||||
testHelperFailure(c, "Check(obtained, nil)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckWithParamsAndNamesMutation(c *check.C) {
|
||||
checker := &MyChecker{result: false, params: []interface{}{3, 4}, names: []string{"newobtained", "newexpected"}}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker, 2\\)\n" +
|
||||
"\\.+ newobtained int = 3\n" +
|
||||
"\\.+ newexpected int = 4\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, 2) with mutation", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker, 2)
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Tests for Assert(), mostly the same as for Check() above.
|
||||
|
||||
func (s *HelpersS) TestAssertSucceedWithExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true}
|
||||
testHelperSuccess(c, "Assert(1, checker, 2)", nil, func() interface{} {
|
||||
c.Assert(1, checker, 2)
|
||||
return nil
|
||||
})
|
||||
if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) {
|
||||
c.Fatalf("Bad params for check: %#v", checker.params)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertSucceedWithoutExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
|
||||
testHelperSuccess(c, "Assert(1, checker)", nil, func() interface{} {
|
||||
c.Assert(1, checker)
|
||||
return nil
|
||||
})
|
||||
if !reflect.DeepEqual(checker.params, []interface{}{1}) {
|
||||
c.Fatalf("Bad params for check: %#v", checker.params)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertFailWithExpected(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, checker, 2\\)\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n\n"
|
||||
testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, checker, 2)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertFailWithExpectedAndMessage(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n" +
|
||||
"\\.+ Hello world!\n\n"
|
||||
testHelperFailure(c, "Assert(1, checker, 2, msg)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, checker, 2, myComment("Hello world!"))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertFailWithoutExpected(c *check.C) {
|
||||
checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, checker\\)\n" +
|
||||
"\\.+ myvalue int = 1\n\n"
|
||||
testHelperFailure(c, "Assert(1, checker)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, checker)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertFailWithoutExpectedAndMessage(c *check.C) {
|
||||
checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" +
|
||||
"\\.+ myvalue int = 1\n" +
|
||||
"\\.+ Hello world!\n\n"
|
||||
testHelperFailure(c, "Assert(1, checker, msg)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, checker, myComment("Hello world!"))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertWithMissingExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, checker\\)\n" +
|
||||
"\\.+ Assert\\(myobtained, MyChecker, myexpected\\):\n" +
|
||||
"\\.+ Wrong number of parameters for MyChecker: " +
|
||||
"want 3, got 2\n\n"
|
||||
testHelperFailure(c, "Assert(1, checker, !?)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, checker)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertWithError(c *check.C) {
|
||||
checker := &MyChecker{result: false, error: "Some not so cool data provided!"}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, checker, 2\\)\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n" +
|
||||
"\\.+ Some not so cool data provided!\n\n"
|
||||
testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, checker, 2)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertWithNilChecker(c *check.C) {
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, nil\\)\n" +
|
||||
"\\.+ Assert\\(obtained, nil!\\?, \\.\\.\\.\\):\n" +
|
||||
"\\.+ Oops\\.\\. you've provided a nil checker!\n\n"
|
||||
testHelperFailure(c, "Assert(obtained, nil)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, nil)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Ensure that values logged work properly in some interesting cases.
|
||||
|
||||
func (s *HelpersS) TestValueLoggingWithArrays(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(\\[\\]byte{1, 2}, checker, \\[\\]byte{1, 3}\\)\n" +
|
||||
"\\.+ myobtained \\[\\]uint8 = \\[\\]byte{0x1, 0x2}\n" +
|
||||
"\\.+ myexpected \\[\\]uint8 = \\[\\]byte{0x1, 0x3}\n\n"
|
||||
testHelperFailure(c, "Check([]byte{1}, chk, []byte{3})", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check([]byte{1, 2}, checker, []byte{1, 3})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestValueLoggingWithMultiLine(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(\"a\\\\nb\\\\n\", checker, \"a\\\\nb\\\\nc\"\\)\n" +
|
||||
"\\.+ myobtained string = \"\" \\+\n" +
|
||||
"\\.+ \"a\\\\n\" \\+\n" +
|
||||
"\\.+ \"b\\\\n\"\n" +
|
||||
"\\.+ myexpected string = \"\" \\+\n" +
|
||||
"\\.+ \"a\\\\n\" \\+\n" +
|
||||
"\\.+ \"b\\\\n\" \\+\n" +
|
||||
"\\.+ \"c\"\n\n"
|
||||
testHelperFailure(c, `Check("a\nb\n", chk, "a\nb\nc")`, false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check("a\nb\n", checker, "a\nb\nc")
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestValueLoggingWithMultiLineException(c *check.C) {
|
||||
// If the newline is at the end of the string, don't log as multi-line.
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(\"a b\\\\n\", checker, \"a\\\\nb\"\\)\n" +
|
||||
"\\.+ myobtained string = \"a b\\\\n\"\n" +
|
||||
"\\.+ myexpected string = \"\" \\+\n" +
|
||||
"\\.+ \"a\\\\n\" \\+\n" +
|
||||
"\\.+ \"b\"\n\n"
|
||||
testHelperFailure(c, `Check("a b\n", chk, "a\nb")`, false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check("a b\n", checker, "a\nb")
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// MakeDir() tests.
|
||||
|
||||
type MkDirHelper struct {
|
||||
path1 string
|
||||
path2 string
|
||||
isDir1 bool
|
||||
isDir2 bool
|
||||
isDir3 bool
|
||||
isDir4 bool
|
||||
}
|
||||
|
||||
func (s *MkDirHelper) SetUpSuite(c *check.C) {
|
||||
s.path1 = c.MkDir()
|
||||
s.isDir1 = isDir(s.path1)
|
||||
}
|
||||
|
||||
func (s *MkDirHelper) Test(c *check.C) {
|
||||
s.path2 = c.MkDir()
|
||||
s.isDir2 = isDir(s.path2)
|
||||
}
|
||||
|
||||
func (s *MkDirHelper) TearDownSuite(c *check.C) {
|
||||
s.isDir3 = isDir(s.path1)
|
||||
s.isDir4 = isDir(s.path2)
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestMkDir(c *check.C) {
|
||||
helper := MkDirHelper{}
|
||||
output := String{}
|
||||
check.Run(&helper, &check.RunConf{Output: &output})
|
||||
c.Assert(output.value, check.Equals, "")
|
||||
c.Check(helper.isDir1, check.Equals, true)
|
||||
c.Check(helper.isDir2, check.Equals, true)
|
||||
c.Check(helper.isDir3, check.Equals, true)
|
||||
c.Check(helper.isDir4, check.Equals, true)
|
||||
c.Check(helper.path1, check.Not(check.Equals),
|
||||
helper.path2)
|
||||
c.Check(isDir(helper.path1), check.Equals, false)
|
||||
c.Check(isDir(helper.path2), check.Equals, false)
|
||||
}
|
||||
|
||||
func isDir(path string) bool {
|
||||
if stat, err := os.Stat(path); err == nil {
|
||||
return stat.IsDir()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Concurrent logging should not corrupt the underling buffer.
|
||||
// Use go test -race to detect the race in this test.
|
||||
func (s *HelpersS) TestConcurrentLogging(c *check.C) {
|
||||
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(runtime.NumCPU()))
|
||||
var start, stop sync.WaitGroup
|
||||
start.Add(1)
|
||||
for i, n := 0, runtime.NumCPU()*2; i < n; i++ {
|
||||
stop.Add(1)
|
||||
go func(i int) {
|
||||
start.Wait()
|
||||
for j := 0; j < 30; j++ {
|
||||
c.Logf("Worker %d: line %d", i, j)
|
||||
}
|
||||
stop.Done()
|
||||
}(i)
|
||||
}
|
||||
start.Done()
|
||||
stop.Wait()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Test the TestName function
|
||||
|
||||
type TestNameHelper struct {
|
||||
name1 string
|
||||
name2 string
|
||||
name3 string
|
||||
name4 string
|
||||
name5 string
|
||||
}
|
||||
|
||||
func (s *TestNameHelper) SetUpSuite(c *check.C) { s.name1 = c.TestName() }
|
||||
func (s *TestNameHelper) SetUpTest(c *check.C) { s.name2 = c.TestName() }
|
||||
func (s *TestNameHelper) Test(c *check.C) { s.name3 = c.TestName() }
|
||||
func (s *TestNameHelper) TearDownTest(c *check.C) { s.name4 = c.TestName() }
|
||||
func (s *TestNameHelper) TearDownSuite(c *check.C) { s.name5 = c.TestName() }
|
||||
|
||||
func (s *HelpersS) TestTestName(c *check.C) {
|
||||
helper := TestNameHelper{}
|
||||
output := String{}
|
||||
check.Run(&helper, &check.RunConf{Output: &output})
|
||||
c.Check(helper.name1, check.Equals, "")
|
||||
c.Check(helper.name2, check.Equals, "TestNameHelper.Test")
|
||||
c.Check(helper.name3, check.Equals, "TestNameHelper.Test")
|
||||
c.Check(helper.name4, check.Equals, "TestNameHelper.Test")
|
||||
c.Check(helper.name5, check.Equals, "")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// A couple of helper functions to test helper functions. :-)
|
||||
|
||||
func testHelperSuccess(c *check.C, name string, expectedResult interface{}, closure func() interface{}) {
|
||||
var result interface{}
|
||||
defer (func() {
|
||||
if err := recover(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
checkState(c, result,
|
||||
&expectedState{
|
||||
name: name,
|
||||
result: expectedResult,
|
||||
failed: false,
|
||||
log: "",
|
||||
})
|
||||
})()
|
||||
result = closure()
|
||||
}
|
||||
|
||||
func testHelperFailure(c *check.C, name string, expectedResult interface{}, shouldStop bool, log string, closure func() interface{}) {
|
||||
var result interface{}
|
||||
defer (func() {
|
||||
if err := recover(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
checkState(c, result,
|
||||
&expectedState{
|
||||
name: name,
|
||||
result: expectedResult,
|
||||
failed: true,
|
||||
log: log,
|
||||
})
|
||||
})()
|
||||
result = closure()
|
||||
if shouldStop {
|
||||
c.Logf("%s didn't stop when it should", name)
|
||||
}
|
||||
}
|
168
vendor/src/github.com/go-check/check/printer.go
vendored
Normal file
168
vendor/src/github.com/go-check/check/printer.go
vendored
Normal file
|
@ -0,0 +1,168 @@
|
|||
package check
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"os"
|
||||
)
|
||||
|
||||
func indent(s, with string) (r string) {
|
||||
eol := true
|
||||
for i := 0; i != len(s); i++ {
|
||||
c := s[i]
|
||||
switch {
|
||||
case eol && c == '\n' || c == '\r':
|
||||
case c == '\n' || c == '\r':
|
||||
eol = true
|
||||
case eol:
|
||||
eol = false
|
||||
s = s[:i] + with + s[i:]
|
||||
i += len(with)
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func printLine(filename string, line int) (string, error) {
|
||||
fset := token.NewFileSet()
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
fnode, err := parser.ParseFile(fset, filename, file, parser.ParseComments)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
config := &printer.Config{Mode: printer.UseSpaces, Tabwidth: 4}
|
||||
lp := &linePrinter{fset: fset, fnode: fnode, line: line, config: config}
|
||||
ast.Walk(lp, fnode)
|
||||
result := lp.output.Bytes()
|
||||
// Comments leave \n at the end.
|
||||
n := len(result)
|
||||
for n > 0 && result[n-1] == '\n' {
|
||||
n--
|
||||
}
|
||||
return string(result[:n]), nil
|
||||
}
|
||||
|
||||
type linePrinter struct {
|
||||
config *printer.Config
|
||||
fset *token.FileSet
|
||||
fnode *ast.File
|
||||
line int
|
||||
output bytes.Buffer
|
||||
stmt ast.Stmt
|
||||
}
|
||||
|
||||
func (lp *linePrinter) emit() bool {
|
||||
if lp.stmt != nil {
|
||||
lp.trim(lp.stmt)
|
||||
lp.printWithComments(lp.stmt)
|
||||
lp.stmt = nil
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (lp *linePrinter) printWithComments(n ast.Node) {
|
||||
nfirst := lp.fset.Position(n.Pos()).Line
|
||||
nlast := lp.fset.Position(n.End()).Line
|
||||
for _, g := range lp.fnode.Comments {
|
||||
cfirst := lp.fset.Position(g.Pos()).Line
|
||||
clast := lp.fset.Position(g.End()).Line
|
||||
if clast == nfirst-1 && lp.fset.Position(n.Pos()).Column == lp.fset.Position(g.Pos()).Column {
|
||||
for _, c := range g.List {
|
||||
lp.output.WriteString(c.Text)
|
||||
lp.output.WriteByte('\n')
|
||||
}
|
||||
}
|
||||
if cfirst >= nfirst && cfirst <= nlast && n.End() <= g.List[0].Slash {
|
||||
// The printer will not include the comment if it starts past
|
||||
// the node itself. Trick it into printing by overlapping the
|
||||
// slash with the end of the statement.
|
||||
g.List[0].Slash = n.End() - 1
|
||||
}
|
||||
}
|
||||
node := &printer.CommentedNode{n, lp.fnode.Comments}
|
||||
lp.config.Fprint(&lp.output, lp.fset, node)
|
||||
}
|
||||
|
||||
func (lp *linePrinter) Visit(n ast.Node) (w ast.Visitor) {
|
||||
if n == nil {
|
||||
if lp.output.Len() == 0 {
|
||||
lp.emit()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
first := lp.fset.Position(n.Pos()).Line
|
||||
last := lp.fset.Position(n.End()).Line
|
||||
if first <= lp.line && last >= lp.line {
|
||||
// Print the innermost statement containing the line.
|
||||
if stmt, ok := n.(ast.Stmt); ok {
|
||||
if _, ok := n.(*ast.BlockStmt); !ok {
|
||||
lp.stmt = stmt
|
||||
}
|
||||
}
|
||||
if first == lp.line && lp.emit() {
|
||||
return nil
|
||||
}
|
||||
return lp
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lp *linePrinter) trim(n ast.Node) bool {
|
||||
stmt, ok := n.(ast.Stmt)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
line := lp.fset.Position(n.Pos()).Line
|
||||
if line != lp.line {
|
||||
return false
|
||||
}
|
||||
switch stmt := stmt.(type) {
|
||||
case *ast.IfStmt:
|
||||
stmt.Body = lp.trimBlock(stmt.Body)
|
||||
case *ast.SwitchStmt:
|
||||
stmt.Body = lp.trimBlock(stmt.Body)
|
||||
case *ast.TypeSwitchStmt:
|
||||
stmt.Body = lp.trimBlock(stmt.Body)
|
||||
case *ast.CaseClause:
|
||||
stmt.Body = lp.trimList(stmt.Body)
|
||||
case *ast.CommClause:
|
||||
stmt.Body = lp.trimList(stmt.Body)
|
||||
case *ast.BlockStmt:
|
||||
stmt.List = lp.trimList(stmt.List)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (lp *linePrinter) trimBlock(stmt *ast.BlockStmt) *ast.BlockStmt {
|
||||
if !lp.trim(stmt) {
|
||||
return lp.emptyBlock(stmt)
|
||||
}
|
||||
stmt.Rbrace = stmt.Lbrace
|
||||
return stmt
|
||||
}
|
||||
|
||||
func (lp *linePrinter) trimList(stmts []ast.Stmt) []ast.Stmt {
|
||||
for i := 0; i != len(stmts); i++ {
|
||||
if !lp.trim(stmts[i]) {
|
||||
stmts[i] = lp.emptyStmt(stmts[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
return stmts
|
||||
}
|
||||
|
||||
func (lp *linePrinter) emptyStmt(n ast.Node) *ast.ExprStmt {
|
||||
return &ast.ExprStmt{&ast.Ellipsis{n.Pos(), nil}}
|
||||
}
|
||||
|
||||
func (lp *linePrinter) emptyBlock(n ast.Node) *ast.BlockStmt {
|
||||
p := n.Pos()
|
||||
return &ast.BlockStmt{p, []ast.Stmt{lp.emptyStmt(n)}, p}
|
||||
}
|
104
vendor/src/github.com/go-check/check/printer_test.go
vendored
Normal file
104
vendor/src/github.com/go-check/check/printer_test.go
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
package check_test
|
||||
|
||||
import (
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
var _ = Suite(&PrinterS{})
|
||||
|
||||
type PrinterS struct{}
|
||||
|
||||
func (s *PrinterS) TestCountSuite(c *C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
var printTestFuncLine int
|
||||
|
||||
func init() {
|
||||
printTestFuncLine = getMyLine() + 3
|
||||
}
|
||||
|
||||
func printTestFunc() {
|
||||
println(1) // Comment1
|
||||
if 2 == 2 { // Comment2
|
||||
println(3) // Comment3
|
||||
}
|
||||
switch 5 {
|
||||
case 6: println(6) // Comment6
|
||||
println(7)
|
||||
}
|
||||
switch interface{}(9).(type) {// Comment9
|
||||
case int: println(10)
|
||||
println(11)
|
||||
}
|
||||
select {
|
||||
case <-(chan bool)(nil): println(14)
|
||||
println(15)
|
||||
default: println(16)
|
||||
println(17)
|
||||
}
|
||||
println(19,
|
||||
20)
|
||||
_ = func() { println(21)
|
||||
println(22)
|
||||
}
|
||||
println(24, func() {
|
||||
println(25)
|
||||
})
|
||||
// Leading comment
|
||||
// with multiple lines.
|
||||
println(29) // Comment29
|
||||
}
|
||||
|
||||
var printLineTests = []struct {
|
||||
line int
|
||||
output string
|
||||
}{
|
||||
{1, "println(1) // Comment1"},
|
||||
{2, "if 2 == 2 { // Comment2\n ...\n}"},
|
||||
{3, "println(3) // Comment3"},
|
||||
{5, "switch 5 {\n...\n}"},
|
||||
{6, "case 6:\n println(6) // Comment6\n ..."},
|
||||
{7, "println(7)"},
|
||||
{9, "switch interface{}(9).(type) { // Comment9\n...\n}"},
|
||||
{10, "case int:\n println(10)\n ..."},
|
||||
{14, "case <-(chan bool)(nil):\n println(14)\n ..."},
|
||||
{15, "println(15)"},
|
||||
{16, "default:\n println(16)\n ..."},
|
||||
{17, "println(17)"},
|
||||
{19, "println(19,\n 20)"},
|
||||
{20, "println(19,\n 20)"},
|
||||
{21, "_ = func() {\n println(21)\n println(22)\n}"},
|
||||
{22, "println(22)"},
|
||||
{24, "println(24, func() {\n println(25)\n})"},
|
||||
{25, "println(25)"},
|
||||
{26, "println(24, func() {\n println(25)\n})"},
|
||||
{29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"},
|
||||
}
|
||||
|
||||
func (s *PrinterS) TestPrintLine(c *C) {
|
||||
for _, test := range printLineTests {
|
||||
output, err := PrintLine("printer_test.go", printTestFuncLine+test.line)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(output, Equals, test.output)
|
||||
}
|
||||
}
|
||||
|
||||
var indentTests = []struct {
|
||||
in, out string
|
||||
}{
|
||||
{"", ""},
|
||||
{"\n", "\n"},
|
||||
{"a", ">>>a"},
|
||||
{"a\n", ">>>a\n"},
|
||||
{"a\nb", ">>>a\n>>>b"},
|
||||
{" ", ">>> "},
|
||||
}
|
||||
|
||||
func (s *PrinterS) TestIndent(c *C) {
|
||||
for _, test := range indentTests {
|
||||
out := Indent(test.in, ">>>")
|
||||
c.Assert(out, Equals, test.out)
|
||||
}
|
||||
|
||||
}
|
175
vendor/src/github.com/go-check/check/run.go
vendored
Normal file
175
vendor/src/github.com/go-check/check/run.go
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
package check
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Test suite registry.
|
||||
|
||||
var allSuites []interface{}
|
||||
|
||||
// Suite registers the given value as a test suite to be run. Any methods
|
||||
// starting with the Test prefix in the given value will be considered as
|
||||
// a test method.
|
||||
func Suite(suite interface{}) interface{} {
|
||||
allSuites = append(allSuites, suite)
|
||||
return suite
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Public running interface.
|
||||
|
||||
var (
|
||||
oldFilterFlag = flag.String("gocheck.f", "", "Regular expression selecting which tests and/or suites to run")
|
||||
oldVerboseFlag = flag.Bool("gocheck.v", false, "Verbose mode")
|
||||
oldStreamFlag = flag.Bool("gocheck.vv", false, "Super verbose mode (disables output caching)")
|
||||
oldBenchFlag = flag.Bool("gocheck.b", false, "Run benchmarks")
|
||||
oldBenchTime = flag.Duration("gocheck.btime", 1*time.Second, "approximate run time for each benchmark")
|
||||
oldListFlag = flag.Bool("gocheck.list", false, "List the names of all tests that will be run")
|
||||
oldWorkFlag = flag.Bool("gocheck.work", false, "Display and do not remove the test working directory")
|
||||
|
||||
newFilterFlag = flag.String("check.f", "", "Regular expression selecting which tests and/or suites to run")
|
||||
newVerboseFlag = flag.Bool("check.v", false, "Verbose mode")
|
||||
newStreamFlag = flag.Bool("check.vv", false, "Super verbose mode (disables output caching)")
|
||||
newBenchFlag = flag.Bool("check.b", false, "Run benchmarks")
|
||||
newBenchTime = flag.Duration("check.btime", 1*time.Second, "approximate run time for each benchmark")
|
||||
newBenchMem = flag.Bool("check.bmem", false, "Report memory benchmarks")
|
||||
newListFlag = flag.Bool("check.list", false, "List the names of all tests that will be run")
|
||||
newWorkFlag = flag.Bool("check.work", false, "Display and do not remove the test working directory")
|
||||
)
|
||||
|
||||
// TestingT runs all test suites registered with the Suite function,
|
||||
// printing results to stdout, and reporting any failures back to
|
||||
// the "testing" package.
|
||||
func TestingT(testingT *testing.T) {
|
||||
benchTime := *newBenchTime
|
||||
if benchTime == 1*time.Second {
|
||||
benchTime = *oldBenchTime
|
||||
}
|
||||
conf := &RunConf{
|
||||
Filter: *oldFilterFlag + *newFilterFlag,
|
||||
Verbose: *oldVerboseFlag || *newVerboseFlag,
|
||||
Stream: *oldStreamFlag || *newStreamFlag,
|
||||
Benchmark: *oldBenchFlag || *newBenchFlag,
|
||||
BenchmarkTime: benchTime,
|
||||
BenchmarkMem: *newBenchMem,
|
||||
KeepWorkDir: *oldWorkFlag || *newWorkFlag,
|
||||
}
|
||||
if *oldListFlag || *newListFlag {
|
||||
w := bufio.NewWriter(os.Stdout)
|
||||
for _, name := range ListAll(conf) {
|
||||
fmt.Fprintln(w, name)
|
||||
}
|
||||
w.Flush()
|
||||
return
|
||||
}
|
||||
result := RunAll(conf)
|
||||
println(result.String())
|
||||
if !result.Passed() {
|
||||
testingT.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
// RunAll runs all test suites registered with the Suite function, using the
|
||||
// provided run configuration.
|
||||
func RunAll(runConf *RunConf) *Result {
|
||||
result := Result{}
|
||||
for _, suite := range allSuites {
|
||||
result.Add(Run(suite, runConf))
|
||||
}
|
||||
return &result
|
||||
}
|
||||
|
||||
// Run runs the provided test suite using the provided run configuration.
|
||||
func Run(suite interface{}, runConf *RunConf) *Result {
|
||||
runner := newSuiteRunner(suite, runConf)
|
||||
return runner.run()
|
||||
}
|
||||
|
||||
// ListAll returns the names of all the test functions registered with the
|
||||
// Suite function that will be run with the provided run configuration.
|
||||
func ListAll(runConf *RunConf) []string {
|
||||
var names []string
|
||||
for _, suite := range allSuites {
|
||||
names = append(names, List(suite, runConf)...)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// List returns the names of the test functions in the given
|
||||
// suite that will be run with the provided run configuration.
|
||||
func List(suite interface{}, runConf *RunConf) []string {
|
||||
var names []string
|
||||
runner := newSuiteRunner(suite, runConf)
|
||||
for _, t := range runner.tests {
|
||||
names = append(names, t.String())
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Result methods.
|
||||
|
||||
func (r *Result) Add(other *Result) {
|
||||
r.Succeeded += other.Succeeded
|
||||
r.Skipped += other.Skipped
|
||||
r.Failed += other.Failed
|
||||
r.Panicked += other.Panicked
|
||||
r.FixturePanicked += other.FixturePanicked
|
||||
r.ExpectedFailures += other.ExpectedFailures
|
||||
r.Missed += other.Missed
|
||||
if r.WorkDir != "" && other.WorkDir != "" {
|
||||
r.WorkDir += ":" + other.WorkDir
|
||||
} else if other.WorkDir != "" {
|
||||
r.WorkDir = other.WorkDir
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Result) Passed() bool {
|
||||
return (r.Failed == 0 && r.Panicked == 0 &&
|
||||
r.FixturePanicked == 0 && r.Missed == 0 &&
|
||||
r.RunError == nil)
|
||||
}
|
||||
|
||||
func (r *Result) String() string {
|
||||
if r.RunError != nil {
|
||||
return "ERROR: " + r.RunError.Error()
|
||||
}
|
||||
|
||||
var value string
|
||||
if r.Failed == 0 && r.Panicked == 0 && r.FixturePanicked == 0 &&
|
||||
r.Missed == 0 {
|
||||
value = "OK: "
|
||||
} else {
|
||||
value = "OOPS: "
|
||||
}
|
||||
value += fmt.Sprintf("%d passed", r.Succeeded)
|
||||
if r.Skipped != 0 {
|
||||
value += fmt.Sprintf(", %d skipped", r.Skipped)
|
||||
}
|
||||
if r.ExpectedFailures != 0 {
|
||||
value += fmt.Sprintf(", %d expected failures", r.ExpectedFailures)
|
||||
}
|
||||
if r.Failed != 0 {
|
||||
value += fmt.Sprintf(", %d FAILED", r.Failed)
|
||||
}
|
||||
if r.Panicked != 0 {
|
||||
value += fmt.Sprintf(", %d PANICKED", r.Panicked)
|
||||
}
|
||||
if r.FixturePanicked != 0 {
|
||||
value += fmt.Sprintf(", %d FIXTURE-PANICKED", r.FixturePanicked)
|
||||
}
|
||||
if r.Missed != 0 {
|
||||
value += fmt.Sprintf(", %d MISSED", r.Missed)
|
||||
}
|
||||
if r.WorkDir != "" {
|
||||
value += "\nWORK=" + r.WorkDir
|
||||
}
|
||||
return value
|
||||
}
|
419
vendor/src/github.com/go-check/check/run_test.go
vendored
Normal file
419
vendor/src/github.com/go-check/check/run_test.go
vendored
Normal file
|
@ -0,0 +1,419 @@
|
|||
// These tests verify the test running logic.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
. "gopkg.in/check.v1"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var runnerS = Suite(&RunS{})
|
||||
|
||||
type RunS struct{}
|
||||
|
||||
func (s *RunS) TestCountSuite(c *C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Tests ensuring result counting works properly.
|
||||
|
||||
func (s *RunS) TestSuccess(c *C) {
|
||||
output := String{}
|
||||
result := Run(&SuccessHelper{}, &RunConf{Output: &output})
|
||||
c.Check(result.Succeeded, Equals, 1)
|
||||
c.Check(result.Failed, Equals, 0)
|
||||
c.Check(result.Skipped, Equals, 0)
|
||||
c.Check(result.Panicked, Equals, 0)
|
||||
c.Check(result.FixturePanicked, Equals, 0)
|
||||
c.Check(result.Missed, Equals, 0)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFailure(c *C) {
|
||||
output := String{}
|
||||
result := Run(&FailHelper{}, &RunConf{Output: &output})
|
||||
c.Check(result.Succeeded, Equals, 0)
|
||||
c.Check(result.Failed, Equals, 1)
|
||||
c.Check(result.Skipped, Equals, 0)
|
||||
c.Check(result.Panicked, Equals, 0)
|
||||
c.Check(result.FixturePanicked, Equals, 0)
|
||||
c.Check(result.Missed, Equals, 0)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFixture(c *C) {
|
||||
output := String{}
|
||||
result := Run(&FixtureHelper{}, &RunConf{Output: &output})
|
||||
c.Check(result.Succeeded, Equals, 2)
|
||||
c.Check(result.Failed, Equals, 0)
|
||||
c.Check(result.Skipped, Equals, 0)
|
||||
c.Check(result.Panicked, Equals, 0)
|
||||
c.Check(result.FixturePanicked, Equals, 0)
|
||||
c.Check(result.Missed, Equals, 0)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
func (s *RunS) TestPanicOnTest(c *C) {
|
||||
output := String{}
|
||||
helper := &FixtureHelper{panicOn: "Test1"}
|
||||
result := Run(helper, &RunConf{Output: &output})
|
||||
c.Check(result.Succeeded, Equals, 1)
|
||||
c.Check(result.Failed, Equals, 0)
|
||||
c.Check(result.Skipped, Equals, 0)
|
||||
c.Check(result.Panicked, Equals, 1)
|
||||
c.Check(result.FixturePanicked, Equals, 0)
|
||||
c.Check(result.Missed, Equals, 0)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
func (s *RunS) TestPanicOnSetUpTest(c *C) {
|
||||
output := String{}
|
||||
helper := &FixtureHelper{panicOn: "SetUpTest"}
|
||||
result := Run(helper, &RunConf{Output: &output})
|
||||
c.Check(result.Succeeded, Equals, 0)
|
||||
c.Check(result.Failed, Equals, 0)
|
||||
c.Check(result.Skipped, Equals, 0)
|
||||
c.Check(result.Panicked, Equals, 0)
|
||||
c.Check(result.FixturePanicked, Equals, 1)
|
||||
c.Check(result.Missed, Equals, 2)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
func (s *RunS) TestPanicOnSetUpSuite(c *C) {
|
||||
output := String{}
|
||||
helper := &FixtureHelper{panicOn: "SetUpSuite"}
|
||||
result := Run(helper, &RunConf{Output: &output})
|
||||
c.Check(result.Succeeded, Equals, 0)
|
||||
c.Check(result.Failed, Equals, 0)
|
||||
c.Check(result.Skipped, Equals, 0)
|
||||
c.Check(result.Panicked, Equals, 0)
|
||||
c.Check(result.FixturePanicked, Equals, 1)
|
||||
c.Check(result.Missed, Equals, 2)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Check result aggregation.
|
||||
|
||||
func (s *RunS) TestAdd(c *C) {
|
||||
result := &Result{
|
||||
Succeeded: 1,
|
||||
Skipped: 2,
|
||||
Failed: 3,
|
||||
Panicked: 4,
|
||||
FixturePanicked: 5,
|
||||
Missed: 6,
|
||||
ExpectedFailures: 7,
|
||||
}
|
||||
result.Add(&Result{
|
||||
Succeeded: 10,
|
||||
Skipped: 20,
|
||||
Failed: 30,
|
||||
Panicked: 40,
|
||||
FixturePanicked: 50,
|
||||
Missed: 60,
|
||||
ExpectedFailures: 70,
|
||||
})
|
||||
c.Check(result.Succeeded, Equals, 11)
|
||||
c.Check(result.Skipped, Equals, 22)
|
||||
c.Check(result.Failed, Equals, 33)
|
||||
c.Check(result.Panicked, Equals, 44)
|
||||
c.Check(result.FixturePanicked, Equals, 55)
|
||||
c.Check(result.Missed, Equals, 66)
|
||||
c.Check(result.ExpectedFailures, Equals, 77)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Check the Passed() method.
|
||||
|
||||
func (s *RunS) TestPassed(c *C) {
|
||||
c.Assert((&Result{}).Passed(), Equals, true)
|
||||
c.Assert((&Result{Succeeded: 1}).Passed(), Equals, true)
|
||||
c.Assert((&Result{Skipped: 1}).Passed(), Equals, true)
|
||||
c.Assert((&Result{Failed: 1}).Passed(), Equals, false)
|
||||
c.Assert((&Result{Panicked: 1}).Passed(), Equals, false)
|
||||
c.Assert((&Result{FixturePanicked: 1}).Passed(), Equals, false)
|
||||
c.Assert((&Result{Missed: 1}).Passed(), Equals, false)
|
||||
c.Assert((&Result{RunError: errors.New("!")}).Passed(), Equals, false)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Check that result printing is working correctly.
|
||||
|
||||
func (s *RunS) TestPrintSuccess(c *C) {
|
||||
result := &Result{Succeeded: 5}
|
||||
c.Check(result.String(), Equals, "OK: 5 passed")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintFailure(c *C) {
|
||||
result := &Result{Failed: 5}
|
||||
c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FAILED")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintSkipped(c *C) {
|
||||
result := &Result{Skipped: 5}
|
||||
c.Check(result.String(), Equals, "OK: 0 passed, 5 skipped")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintExpectedFailures(c *C) {
|
||||
result := &Result{ExpectedFailures: 5}
|
||||
c.Check(result.String(), Equals, "OK: 0 passed, 5 expected failures")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintPanicked(c *C) {
|
||||
result := &Result{Panicked: 5}
|
||||
c.Check(result.String(), Equals, "OOPS: 0 passed, 5 PANICKED")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintFixturePanicked(c *C) {
|
||||
result := &Result{FixturePanicked: 5}
|
||||
c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FIXTURE-PANICKED")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintMissed(c *C) {
|
||||
result := &Result{Missed: 5}
|
||||
c.Check(result.String(), Equals, "OOPS: 0 passed, 5 MISSED")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintAll(c *C) {
|
||||
result := &Result{Succeeded: 1, Skipped: 2, ExpectedFailures: 3,
|
||||
Panicked: 4, FixturePanicked: 5, Missed: 6}
|
||||
c.Check(result.String(), Equals,
|
||||
"OOPS: 1 passed, 2 skipped, 3 expected failures, 4 PANICKED, "+
|
||||
"5 FIXTURE-PANICKED, 6 MISSED")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintRunError(c *C) {
|
||||
result := &Result{Succeeded: 1, Failed: 1,
|
||||
RunError: errors.New("Kaboom!")}
|
||||
c.Check(result.String(), Equals, "ERROR: Kaboom!")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify that the method pattern flag works correctly.
|
||||
|
||||
func (s *RunS) TestFilterTestName(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: "Test[91]"}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 5)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFilterTestNameWithAll(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: ".*"}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[5], Equals, "Test2")
|
||||
c.Check(helper.calls[6], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[7], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 8)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFilterSuiteName(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: "FixtureHelper"}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[5], Equals, "Test2")
|
||||
c.Check(helper.calls[6], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[7], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 8)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFilterSuiteNameAndTestName(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: "FixtureHelper\\.Test2"}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test2")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 5)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFilterAllOut(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: "NotFound"}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(len(helper.calls), Equals, 0)
|
||||
}
|
||||
|
||||
func (s *RunS) TestRequirePartialMatch(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: "est"}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(len(helper.calls), Equals, 8)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFilterError(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: "]["}
|
||||
result := Run(&helper, &runConf)
|
||||
c.Check(result.String(), Equals,
|
||||
"ERROR: Bad filter expression: error parsing regexp: missing closing ]: `[`")
|
||||
c.Check(len(helper.calls), Equals, 0)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify that List works correctly.
|
||||
|
||||
func (s *RunS) TestListFiltered(c *C) {
|
||||
names := List(&FixtureHelper{}, &RunConf{Filter: "1"})
|
||||
c.Assert(names, DeepEquals, []string{
|
||||
"FixtureHelper.Test1",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RunS) TestList(c *C) {
|
||||
names := List(&FixtureHelper{}, &RunConf{})
|
||||
c.Assert(names, DeepEquals, []string{
|
||||
"FixtureHelper.Test1",
|
||||
"FixtureHelper.Test2",
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify that verbose mode prints tests which pass as well.
|
||||
|
||||
func (s *RunS) TestVerboseMode(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Verbose: true}
|
||||
Run(&helper, &runConf)
|
||||
|
||||
expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t *[.0-9]+s\n" +
|
||||
"PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n"
|
||||
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *RunS) TestVerboseModeWithFailBeforePass(c *C) {
|
||||
helper := FixtureHelper{panicOn: "Test1"}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Verbose: true}
|
||||
Run(&helper, &runConf)
|
||||
|
||||
expected := "(?s).*PANIC.*\n-+\n" + // Should have an extra line.
|
||||
"PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n"
|
||||
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify the stream output mode. In this mode there's no output caching.
|
||||
|
||||
type StreamHelper struct {
|
||||
l2 sync.Mutex
|
||||
l3 sync.Mutex
|
||||
}
|
||||
|
||||
func (s *StreamHelper) SetUpSuite(c *C) {
|
||||
c.Log("0")
|
||||
}
|
||||
|
||||
func (s *StreamHelper) Test1(c *C) {
|
||||
c.Log("1")
|
||||
s.l2.Lock()
|
||||
s.l3.Lock()
|
||||
go func() {
|
||||
s.l2.Lock() // Wait for "2".
|
||||
c.Log("3")
|
||||
s.l3.Unlock()
|
||||
}()
|
||||
}
|
||||
|
||||
func (s *StreamHelper) Test2(c *C) {
|
||||
c.Log("2")
|
||||
s.l2.Unlock()
|
||||
s.l3.Lock() // Wait for "3".
|
||||
c.Fail()
|
||||
c.Log("4")
|
||||
}
|
||||
|
||||
func (s *RunS) TestStreamMode(c *C) {
|
||||
helper := &StreamHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Stream: true}
|
||||
Run(helper, &runConf)
|
||||
|
||||
expected := "START: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\n0\n" +
|
||||
"PASS: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\t *[.0-9]+s\n\n" +
|
||||
"START: run_test\\.go:[0-9]+: StreamHelper\\.Test1\n1\n" +
|
||||
"PASS: run_test\\.go:[0-9]+: StreamHelper\\.Test1\t *[.0-9]+s\n\n" +
|
||||
"START: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n2\n3\n4\n" +
|
||||
"FAIL: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n\n"
|
||||
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
type StreamMissHelper struct{}
|
||||
|
||||
func (s *StreamMissHelper) SetUpSuite(c *C) {
|
||||
c.Log("0")
|
||||
c.Fail()
|
||||
}
|
||||
|
||||
func (s *StreamMissHelper) Test1(c *C) {
|
||||
c.Log("1")
|
||||
}
|
||||
|
||||
func (s *RunS) TestStreamModeWithMiss(c *C) {
|
||||
helper := &StreamMissHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Stream: true}
|
||||
Run(helper, &runConf)
|
||||
|
||||
expected := "START: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n0\n" +
|
||||
"FAIL: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n\n" +
|
||||
"START: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n" +
|
||||
"MISS: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n\n"
|
||||
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify that that the keep work dir request indeed does so.
|
||||
|
||||
type WorkDirSuite struct {}
|
||||
|
||||
func (s *WorkDirSuite) Test(c *C) {
|
||||
c.MkDir()
|
||||
}
|
||||
|
||||
func (s *RunS) TestKeepWorkDir(c *C) {
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Verbose: true, KeepWorkDir: true}
|
||||
result := Run(&WorkDirSuite{}, &runConf)
|
||||
|
||||
c.Assert(result.String(), Matches, ".*\nWORK=" + result.WorkDir)
|
||||
|
||||
stat, err := os.Stat(result.WorkDir)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(stat.IsDir(), Equals, true)
|
||||
}
|
Loading…
Add table
Reference in a new issue