зеркало из https://github.com/microsoft/docker.git
Merge pull request #5296 from crosbymichael/move-integration-tests
Move integration tests
This commit is contained in:
Коммит
c25704e31b
|
@ -0,0 +1,51 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestMultipleAttachRestart(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "--name", "attacher", "-d", "busybox",
|
||||
"/bin/sh", "-c", "sleep 1 && echo hello")
|
||||
|
||||
group := sync.WaitGroup{}
|
||||
group.Add(4)
|
||||
|
||||
go func() {
|
||||
defer group.Done()
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
}
|
||||
}()
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
go func() {
|
||||
defer group.Done()
|
||||
c := exec.Command(dockerBinary, "attach", "attacher")
|
||||
|
||||
out, _, err := runCommandWithOutput(c)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
}
|
||||
if actual := strings.Trim(out, "\r\n"); actual != "hello" {
|
||||
t.Fatalf("unexpected output %s expected hello", actual)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
group.Wait()
|
||||
|
||||
cmd = exec.Command(dockerBinary, "kill", "attacher")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - multiple attach")
|
||||
}
|
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -32,3 +33,32 @@ func TestCommitAfterContainerIsDone(t *testing.T) {
|
|||
|
||||
logDone("commit - echo foo and commit the image")
|
||||
}
|
||||
|
||||
func TestCommitNewFile(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "--name", "commiter", "busybox", "/bin/sh", "-c", "echo koye > /foo")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(dockerBinary, "commit", "commiter")
|
||||
imageId, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
imageId = strings.Trim(imageId, "\r\n")
|
||||
|
||||
cmd = exec.Command(dockerBinary, "run", imageId, "cat", "/foo")
|
||||
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
}
|
||||
if actual := strings.Trim(out, "\r\n"); actual != "koye" {
|
||||
t.Fatalf("expected output koye received %s", actual)
|
||||
}
|
||||
|
||||
deleteAllContainers()
|
||||
deleteImages(imageId)
|
||||
|
||||
logDone("commit - commit file and read")
|
||||
}
|
||||
|
|
|
@ -2,8 +2,12 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -384,3 +388,280 @@ func TestMultipleVolumesFrom(t *testing.T) {
|
|||
|
||||
logDone("run - multiple volumes from")
|
||||
}
|
||||
|
||||
// this tests verifies the ID format for the container
|
||||
func TestVerifyContainerID(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
|
||||
out, exit, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if exit != 0 {
|
||||
t.Fatalf("expected exit code 0 received %d", exit)
|
||||
}
|
||||
match, err := regexp.MatchString("^[0-9a-f]{64}$", strings.TrimSuffix(out, "\n"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !match {
|
||||
t.Fatalf("Invalid container ID: %s", out)
|
||||
}
|
||||
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - verify container ID")
|
||||
}
|
||||
|
||||
// Test that creating a container with a volume doesn't crash. Regression test for #995.
|
||||
func TestCreateVolume(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "-v", "/var/lib/data", "busybox", "true")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - create docker mangaed volume")
|
||||
}
|
||||
|
||||
func TestExitCode(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "busybox", "/bin/sh", "-c", "exit 72")
|
||||
|
||||
exit, err := runCommand(cmd)
|
||||
if err == nil {
|
||||
t.Fatal("should not have a non nil error")
|
||||
}
|
||||
if exit != 72 {
|
||||
t.Fatalf("expected exit code 72 received %d", exit)
|
||||
}
|
||||
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - correct exit code")
|
||||
}
|
||||
|
||||
func TestUserDefaultsToRoot(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "busybox", "id")
|
||||
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
}
|
||||
if !strings.Contains(out, "uid=0(root) gid=0(root)") {
|
||||
t.Fatalf("expected root user got %s", out)
|
||||
}
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - default user")
|
||||
}
|
||||
|
||||
func TestUserByName(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "-u", "root", "busybox", "id")
|
||||
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
}
|
||||
if !strings.Contains(out, "uid=0(root) gid=0(root)") {
|
||||
t.Fatalf("expected root user got %s", out)
|
||||
}
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - user by name")
|
||||
}
|
||||
|
||||
func TestUserByID(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "-u", "1", "busybox", "id")
|
||||
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
}
|
||||
if !strings.Contains(out, "uid=1(daemon) gid=1(daemon)") {
|
||||
t.Fatalf("expected daemon user got %s", out)
|
||||
}
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - user by id")
|
||||
}
|
||||
|
||||
func TestUserNotFound(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "-u", "notme", "busybox", "id")
|
||||
|
||||
_, err := runCommand(cmd)
|
||||
if err == nil {
|
||||
t.Fatal("unknown user should cause container to fail")
|
||||
}
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - user not found")
|
||||
}
|
||||
|
||||
func TestRunTwoConcurrentContainers(t *testing.T) {
|
||||
group := sync.WaitGroup{}
|
||||
group.Add(2)
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
go func() {
|
||||
defer group.Done()
|
||||
cmd := exec.Command(dockerBinary, "run", "busybox", "sleep", "2")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
group.Wait()
|
||||
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - two concurrent containers")
|
||||
}
|
||||
|
||||
func TestEnvironment(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "-h", "testing", "-e=FALSE=true", "-e=TRUE", "-e=TRICKY", "busybox", "env")
|
||||
cmd.Env = append(os.Environ(),
|
||||
"TRUE=false",
|
||||
"TRICKY=tri\ncky\n",
|
||||
)
|
||||
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
}
|
||||
|
||||
actualEnv := strings.Split(out, "\n")
|
||||
if actualEnv[len(actualEnv)-1] == "" {
|
||||
actualEnv = actualEnv[:len(actualEnv)-1]
|
||||
}
|
||||
sort.Strings(actualEnv)
|
||||
|
||||
goodEnv := []string{
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"HOME=/",
|
||||
"HOSTNAME=testing",
|
||||
"FALSE=true",
|
||||
"TRUE=false",
|
||||
"TRICKY=tri",
|
||||
"cky",
|
||||
"",
|
||||
}
|
||||
sort.Strings(goodEnv)
|
||||
if len(goodEnv) != len(actualEnv) {
|
||||
t.Fatalf("Wrong environment: should be %d variables, not: '%s'\n", len(goodEnv), strings.Join(actualEnv, ", "))
|
||||
}
|
||||
for i := range goodEnv {
|
||||
if actualEnv[i] != goodEnv[i] {
|
||||
t.Fatalf("Wrong environment variable: should be %s, not %s", goodEnv[i], actualEnv[i])
|
||||
}
|
||||
}
|
||||
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - verify environment")
|
||||
}
|
||||
|
||||
func TestContainerNetwork(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "busybox", "ping", "-c", "1", "127.0.0.1")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - test container network via ping")
|
||||
}
|
||||
|
||||
// Issue #4681
|
||||
func TestLoopbackWhenNetworkDisabled(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "--networking=false", "busybox", "ping", "-c", "1", "127.0.0.1")
|
||||
if _, err := runCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - test container loopback when networking disabled")
|
||||
}
|
||||
|
||||
func TestLoopbackOnlyExistsWhenNetworkingDisabled(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "--networking=false", "busybox", "ip", "a", "show", "up")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err, out)
|
||||
}
|
||||
|
||||
interfaces := regexp.MustCompile(`(?m)^[0-9]+: [a-zA-Z0-9]+`).FindAllString(out, -1)
|
||||
if len(interfaces) != 1 {
|
||||
t.Fatalf("Wrong interface count in test container: expected [*: lo], got %s", interfaces)
|
||||
}
|
||||
if !strings.HasSuffix(interfaces[0], ": lo") {
|
||||
t.Fatalf("Wrong interface in test container: expected [*: lo], got %s", interfaces)
|
||||
}
|
||||
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - test loopback only exists when networking disabled")
|
||||
}
|
||||
|
||||
func TestPrivilegedCanMknod(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "--privileged", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if actual := strings.Trim(out, "\r\n"); actual != "ok" {
|
||||
t.Fatalf("expected output ok received %s", actual)
|
||||
}
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - test privileged can mknod")
|
||||
}
|
||||
|
||||
func TestUnPrivilegedCanMknod(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if actual := strings.Trim(out, "\r\n"); actual != "ok" {
|
||||
t.Fatalf("expected output ok received %s", actual)
|
||||
}
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - test un-privileged can mknod")
|
||||
}
|
||||
|
||||
func TestPrivilegedCanMount(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "--privileged", "busybox", "sh", "-c", "mount -t tmpfs none /tmp && echo ok")
|
||||
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if actual := strings.Trim(out, "\r\n"); actual != "ok" {
|
||||
t.Fatalf("expected output ok received %s", actual)
|
||||
}
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - test privileged can mount")
|
||||
}
|
||||
|
||||
func TestUnPrivilegedCannotMount(t *testing.T) {
|
||||
cmd := exec.Command(dockerBinary, "run", "busybox", "sh", "-c", "mount -t tmpfs none /tmp && echo ok")
|
||||
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err == nil {
|
||||
t.Fatal(err, out)
|
||||
}
|
||||
|
||||
if actual := strings.Trim(out, "\r\n"); actual == "ok" {
|
||||
t.Fatalf("expected output not ok received %s", actual)
|
||||
}
|
||||
deleteAllContainers()
|
||||
|
||||
logDone("run - test un-privileged cannot mount")
|
||||
}
|
||||
|
|
|
@ -1,439 +1,17 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"github.com/dotcloud/docker/runconfig"
|
||||
"github.com/dotcloud/docker/utils"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestIDFormat(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
container1, _, err := daemon.Create(
|
||||
&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"/bin/sh", "-c", "echo hello world"},
|
||||
},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
match, err := regexp.Match("^[0-9a-f]{64}$", []byte(container1.ID))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !match {
|
||||
t.Fatalf("Invalid container ID: %s", container1.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleAttachRestart(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
container, _, _ := mkContainer(
|
||||
daemon,
|
||||
[]string{"_", "/bin/sh", "-c", "i=1; while [ $i -le 5 ]; do i=`expr $i + 1`; echo hello; done"},
|
||||
t,
|
||||
)
|
||||
defer daemon.Destroy(container)
|
||||
|
||||
// Simulate 3 client attaching to the container and stop/restart
|
||||
|
||||
stdout1, err := container.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stdout2, err := container.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stdout3, err := container.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := container.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
l1, err := bufio.NewReader(stdout1).ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Trim(l1, " \r\n") != "hello" {
|
||||
t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l1)
|
||||
}
|
||||
l2, err := bufio.NewReader(stdout2).ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Trim(l2, " \r\n") != "hello" {
|
||||
t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l2)
|
||||
}
|
||||
l3, err := bufio.NewReader(stdout3).ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Trim(l3, " \r\n") != "hello" {
|
||||
t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l3)
|
||||
}
|
||||
|
||||
if err := container.Stop(10); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
stdout1, err = container.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stdout2, err = container.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stdout3, err = container.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := container.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
setTimeout(t, "Timeout reading from the process", 3*time.Second, func() {
|
||||
l1, err = bufio.NewReader(stdout1).ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Trim(l1, " \r\n") != "hello" {
|
||||
t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l1)
|
||||
}
|
||||
l2, err = bufio.NewReader(stdout2).ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Trim(l2, " \r\n") != "hello" {
|
||||
t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l2)
|
||||
}
|
||||
l3, err = bufio.NewReader(stdout3).ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Trim(l3, " \r\n") != "hello" {
|
||||
t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l3)
|
||||
}
|
||||
})
|
||||
container.Wait()
|
||||
}
|
||||
|
||||
func TestDiff(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
daemon := mkDaemonFromEngine(eng, t)
|
||||
defer nuke(daemon)
|
||||
// Create a container and remove a file
|
||||
container1, _, _ := mkContainer(daemon, []string{"_", "/bin/rm", "/etc/passwd"}, t)
|
||||
defer daemon.Destroy(container1)
|
||||
|
||||
// The changelog should be empty and not fail before run. See #1705
|
||||
c, err := container1.Changes()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(c) != 0 {
|
||||
t.Fatalf("Changelog should be empty before run")
|
||||
}
|
||||
|
||||
if err := container1.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check the changelog
|
||||
c, err = container1.Changes()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
success := false
|
||||
for _, elem := range c {
|
||||
if elem.Path == "/etc/passwd" && elem.Kind == 2 {
|
||||
success = true
|
||||
}
|
||||
}
|
||||
if !success {
|
||||
t.Fatalf("/etc/passwd as been removed but is not present in the diff")
|
||||
}
|
||||
|
||||
// Commit the container
|
||||
img, err := daemon.Commit(container1, "", "", "unit test commited image - diff", "", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Create a new container from the commited image
|
||||
container2, _, _ := mkContainer(daemon, []string{img.ID, "cat", "/etc/passwd"}, t)
|
||||
defer daemon.Destroy(container2)
|
||||
|
||||
if err := container2.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check the changelog
|
||||
c, err = container2.Changes()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, elem := range c {
|
||||
if elem.Path == "/etc/passwd" {
|
||||
t.Fatalf("/etc/passwd should not be present in the diff after commit.")
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new container
|
||||
container3, _, _ := mkContainer(daemon, []string{"_", "rm", "/bin/httpd"}, t)
|
||||
defer daemon.Destroy(container3)
|
||||
|
||||
if err := container3.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check the changelog
|
||||
c, err = container3.Changes()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
success = false
|
||||
for _, elem := range c {
|
||||
if elem.Path == "/bin/httpd" && elem.Kind == 2 {
|
||||
success = true
|
||||
}
|
||||
}
|
||||
if !success {
|
||||
t.Fatalf("/bin/httpd should be present in the diff after commit.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitAutoRun(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
container1, _, _ := mkContainer(daemon, []string{"_", "/bin/sh", "-c", "echo hello > /world"}, t)
|
||||
defer daemon.Destroy(container1)
|
||||
|
||||
if container1.State.IsRunning() {
|
||||
t.Errorf("Container shouldn't be running")
|
||||
}
|
||||
if err := container1.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if container1.State.IsRunning() {
|
||||
t.Errorf("Container shouldn't be running")
|
||||
}
|
||||
|
||||
img, err := daemon.Commit(container1, "", "", "unit test commited image", "", &runconfig.Config{Cmd: []string{"cat", "/world"}})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// FIXME: Make a TestCommit that stops here and check docker.root/layers/img.id/world
|
||||
container2, _, _ := mkContainer(daemon, []string{img.ID}, t)
|
||||
defer daemon.Destroy(container2)
|
||||
stdout, err := container2.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stderr, err := container2.StderrPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := container2.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
container2.Wait()
|
||||
output, err := ioutil.ReadAll(stdout)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
output2, err := ioutil.ReadAll(stderr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := stdout.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := stderr.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(output) != "hello\n" {
|
||||
t.Fatalf("Unexpected output. Expected %s, received: %s (err: %s)", "hello\n", output, output2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitRun(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
|
||||
container1, _, _ := mkContainer(daemon, []string{"_", "/bin/sh", "-c", "echo hello > /world"}, t)
|
||||
defer daemon.Destroy(container1)
|
||||
|
||||
if container1.State.IsRunning() {
|
||||
t.Errorf("Container shouldn't be running")
|
||||
}
|
||||
if err := container1.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if container1.State.IsRunning() {
|
||||
t.Errorf("Container shouldn't be running")
|
||||
}
|
||||
|
||||
img, err := daemon.Commit(container1, "", "", "unit test commited image", "", nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// FIXME: Make a TestCommit that stops here and check docker.root/layers/img.id/world
|
||||
container2, _, _ := mkContainer(daemon, []string{img.ID, "cat", "/world"}, t)
|
||||
defer daemon.Destroy(container2)
|
||||
stdout, err := container2.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stderr, err := container2.StderrPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := container2.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
container2.Wait()
|
||||
output, err := ioutil.ReadAll(stdout)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
output2, err := ioutil.ReadAll(stderr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := stdout.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := stderr.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(output) != "hello\n" {
|
||||
t.Fatalf("Unexpected output. Expected %s, received: %s (err: %s)", "hello\n", output, output2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStart(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
container, _, _ := mkContainer(daemon, []string{"-i", "_", "/bin/cat"}, t)
|
||||
defer daemon.Destroy(container)
|
||||
|
||||
cStdin, err := container.StdinPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := container.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Give some time to the process to start
|
||||
container.WaitTimeout(500 * time.Millisecond)
|
||||
|
||||
if !container.State.IsRunning() {
|
||||
t.Errorf("Container should be running")
|
||||
}
|
||||
if err := container.Start(); err != nil {
|
||||
t.Fatalf("A running container should be able to be started")
|
||||
}
|
||||
|
||||
// Try to avoid the timeout in destroy. Best effort, don't check error
|
||||
cStdin.Close()
|
||||
container.WaitTimeout(2 * time.Second)
|
||||
}
|
||||
|
||||
func TestCpuShares(t *testing.T) {
|
||||
_, err1 := os.Stat("/sys/fs/cgroup/cpuacct,cpu")
|
||||
_, err2 := os.Stat("/sys/fs/cgroup/cpu,cpuacct")
|
||||
if err1 == nil || err2 == nil {
|
||||
t.Skip("Fixme. Setting cpu cgroup shares doesn't work in dind on a Fedora host. The lxc utils are confused by the cpu,cpuacct mount.")
|
||||
}
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
container, _, _ := mkContainer(daemon, []string{"-m", "33554432", "-c", "1000", "-i", "_", "/bin/cat"}, t)
|
||||
defer daemon.Destroy(container)
|
||||
|
||||
cStdin, err := container.StdinPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := container.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Give some time to the process to start
|
||||
container.WaitTimeout(500 * time.Millisecond)
|
||||
|
||||
if !container.State.IsRunning() {
|
||||
t.Errorf("Container should be running")
|
||||
}
|
||||
if err := container.Start(); err != nil {
|
||||
t.Fatalf("A running container should be able to be started")
|
||||
}
|
||||
|
||||
// Try to avoid the timeout in destroy. Best effort, don't check error
|
||||
cStdin.Close()
|
||||
container.WaitTimeout(2 * time.Second)
|
||||
}
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
container, _, _ := mkContainer(daemon, []string{"_", "ls", "-al"}, t)
|
||||
defer daemon.Destroy(container)
|
||||
|
||||
if container.State.IsRunning() {
|
||||
t.Errorf("Container shouldn't be running")
|
||||
}
|
||||
if err := container.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if container.State.IsRunning() {
|
||||
t.Errorf("Container shouldn't be running")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOutput(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
container, _, err := daemon.Create(
|
||||
&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"echo", "-n", "foobar"},
|
||||
},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container)
|
||||
output, err := container.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(output) != "foobar" {
|
||||
t.Fatalf("%s != %s", string(output), "foobar")
|
||||
}
|
||||
}
|
||||
|
||||
func TestKillDifferentUser(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
|
@ -492,119 +70,6 @@ func TestKillDifferentUser(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test that creating a container with a volume doesn't crash. Regression test for #995.
|
||||
func TestCreateVolume(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
daemon := mkDaemonFromEngine(eng, t)
|
||||
defer nuke(daemon)
|
||||
|
||||
config, hc, _, err := runconfig.Parse([]string{"-v", "/var/lib/data", unitTestImageID, "echo", "hello", "world"}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
jobCreate := eng.Job("create")
|
||||
if err := jobCreate.ImportEnv(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var id string
|
||||
jobCreate.Stdout.AddString(&id)
|
||||
if err := jobCreate.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
jobStart := eng.Job("start", id)
|
||||
if err := jobStart.ImportEnv(hc); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := jobStart.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// FIXME: this hack can be removed once Wait is a job
|
||||
c := daemon.Get(id)
|
||||
if c == nil {
|
||||
t.Fatalf("Couldn't retrieve container %s from daemon", id)
|
||||
}
|
||||
c.WaitTimeout(500 * time.Millisecond)
|
||||
c.Wait()
|
||||
}
|
||||
|
||||
func TestKill(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
container, _, err := daemon.Create(&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"sleep", "2"},
|
||||
},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container)
|
||||
|
||||
if container.State.IsRunning() {
|
||||
t.Errorf("Container shouldn't be running")
|
||||
}
|
||||
if err := container.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Give some time to lxc to spawn the process
|
||||
container.WaitTimeout(500 * time.Millisecond)
|
||||
|
||||
if !container.State.IsRunning() {
|
||||
t.Errorf("Container should be running")
|
||||
}
|
||||
if err := container.Kill(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if container.State.IsRunning() {
|
||||
t.Errorf("Container shouldn't be running")
|
||||
}
|
||||
container.Wait()
|
||||
if container.State.IsRunning() {
|
||||
t.Errorf("Container shouldn't be running")
|
||||
}
|
||||
// Try stopping twice
|
||||
if err := container.Kill(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExitCode(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
|
||||
trueContainer, _, err := daemon.Create(&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"/bin/true"},
|
||||
}, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(trueContainer)
|
||||
if err := trueContainer.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if code := trueContainer.State.GetExitCode(); code != 0 {
|
||||
t.Fatalf("Unexpected exit code %d (expected 0)", code)
|
||||
}
|
||||
|
||||
falseContainer, _, err := daemon.Create(&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"/bin/false"},
|
||||
}, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(falseContainer)
|
||||
if err := falseContainer.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if code := falseContainer.State.GetExitCode(); code != 1 {
|
||||
t.Fatalf("Unexpected exit code %d (expected 1)", code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRestart(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
|
@ -712,190 +177,6 @@ func TestRestartStdin(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestUser(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
|
||||
// Default user must be root
|
||||
container, _, err := daemon.Create(&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"id"},
|
||||
},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container)
|
||||
output, err := container.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(output), "uid=0(root) gid=0(root)") {
|
||||
t.Error(string(output))
|
||||
}
|
||||
|
||||
// Set a username
|
||||
container, _, err = daemon.Create(&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"id"},
|
||||
|
||||
User: "root",
|
||||
},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container)
|
||||
output, err = container.Output()
|
||||
if code := container.State.GetExitCode(); err != nil || code != 0 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(output), "uid=0(root) gid=0(root)") {
|
||||
t.Error(string(output))
|
||||
}
|
||||
|
||||
// Set a UID
|
||||
container, _, err = daemon.Create(&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"id"},
|
||||
|
||||
User: "0",
|
||||
},
|
||||
"",
|
||||
)
|
||||
if code := container.State.GetExitCode(); err != nil || code != 0 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container)
|
||||
output, err = container.Output()
|
||||
if code := container.State.GetExitCode(); err != nil || code != 0 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(output), "uid=0(root) gid=0(root)") {
|
||||
t.Error(string(output))
|
||||
}
|
||||
|
||||
// Set a different user by uid
|
||||
container, _, err = daemon.Create(&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"id"},
|
||||
|
||||
User: "1",
|
||||
},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container)
|
||||
output, err = container.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if code := container.State.GetExitCode(); code != 0 {
|
||||
t.Fatalf("Container exit code is invalid: %d\nOutput:\n%s\n", code, output)
|
||||
}
|
||||
if !strings.Contains(string(output), "uid=1(daemon) gid=1(daemon)") {
|
||||
t.Error(string(output))
|
||||
}
|
||||
|
||||
// Set a different user by username
|
||||
container, _, err = daemon.Create(&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"id"},
|
||||
|
||||
User: "daemon",
|
||||
},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container)
|
||||
output, err = container.Output()
|
||||
if code := container.State.GetExitCode(); err != nil || code != 0 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(output), "uid=1(daemon) gid=1(daemon)") {
|
||||
t.Error(string(output))
|
||||
}
|
||||
|
||||
// Test an wrong username
|
||||
container, _, err = daemon.Create(&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"id"},
|
||||
|
||||
User: "unknownuser",
|
||||
},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container)
|
||||
output, err = container.Output()
|
||||
if container.State.GetExitCode() == 0 {
|
||||
t.Fatal("Starting container with wrong uid should fail but it passed.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleContainers(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
|
||||
container1, _, err := daemon.Create(&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"sleep", "2"},
|
||||
},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container1)
|
||||
|
||||
container2, _, err := daemon.Create(&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"sleep", "2"},
|
||||
},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container2)
|
||||
|
||||
// Start both containers
|
||||
if err := container1.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := container2.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Make sure they are running before trying to kill them
|
||||
container1.WaitTimeout(250 * time.Millisecond)
|
||||
container2.WaitTimeout(250 * time.Millisecond)
|
||||
|
||||
// If we are here, both containers should be running
|
||||
if !container1.State.IsRunning() {
|
||||
t.Fatal("Container not running")
|
||||
}
|
||||
if !container2.State.IsRunning() {
|
||||
t.Fatal("Container not running")
|
||||
}
|
||||
|
||||
// Kill them
|
||||
if err := container1.Kill(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := container2.Kill(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStdin(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
|
@ -986,60 +267,6 @@ func TestTty(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestEnv(t *testing.T) {
|
||||
os.Setenv("TRUE", "false")
|
||||
os.Setenv("TRICKY", "tri\ncky\n")
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
config, _, _, err := runconfig.Parse([]string{"-e=FALSE=true", "-e=TRUE", "-e=TRICKY", GetTestImage(daemon).ID, "env"}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
container, _, err := daemon.Create(config, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container)
|
||||
|
||||
stdout, err := container.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer stdout.Close()
|
||||
if err := container.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
container.Wait()
|
||||
output, err := ioutil.ReadAll(stdout)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
actualEnv := strings.Split(string(output), "\n")
|
||||
if actualEnv[len(actualEnv)-1] == "" {
|
||||
actualEnv = actualEnv[:len(actualEnv)-1]
|
||||
}
|
||||
sort.Strings(actualEnv)
|
||||
goodEnv := []string{
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"HOME=/",
|
||||
"HOSTNAME=" + utils.TruncateID(container.ID),
|
||||
"FALSE=true",
|
||||
"TRUE=false",
|
||||
"TRICKY=tri",
|
||||
"cky",
|
||||
"",
|
||||
}
|
||||
sort.Strings(goodEnv)
|
||||
if len(goodEnv) != len(actualEnv) {
|
||||
t.Fatalf("Wrong environment: should be %d variables, not: '%s'\n", len(goodEnv), strings.Join(actualEnv, ", "))
|
||||
}
|
||||
for i := range goodEnv {
|
||||
if actualEnv[i] != goodEnv[i] {
|
||||
t.Fatalf("Wrong environment variable: should be %s, not %s", goodEnv[i], actualEnv[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEntrypoint(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
|
@ -1316,139 +543,3 @@ func TestRestartWithVolumes(t *testing.T) {
|
|||
t.Fatalf("Expected volume path: %s Actual path: %s", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainerNetwork(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
container, _, err := daemon.Create(
|
||||
&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
// If I change this to ping 8.8.8.8 it fails. Any idea why? - timthelion
|
||||
Cmd: []string{"ping", "-c", "1", "127.0.0.1"},
|
||||
},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container)
|
||||
if err := container.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if code := container.State.GetExitCode(); code != 0 {
|
||||
t.Fatalf("Unexpected ping 127.0.0.1 exit code %d (expected 0)", code)
|
||||
}
|
||||
}
|
||||
|
||||
// Issue #4681
|
||||
func TestLoopbackFunctionsWhenNetworkingIsDissabled(t *testing.T) {
|
||||
daemon := mkDaemon(t)
|
||||
defer nuke(daemon)
|
||||
container, _, err := daemon.Create(
|
||||
&runconfig.Config{
|
||||
Image: GetTestImage(daemon).ID,
|
||||
Cmd: []string{"ping", "-c", "1", "127.0.0.1"},
|
||||
NetworkDisabled: true,
|
||||
},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer daemon.Destroy(container)
|
||||
if err := container.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if code := container.State.GetExitCode(); code != 0 {
|
||||
t.Fatalf("Unexpected ping 127.0.0.1 exit code %d (expected 0)", code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOnlyLoopbackExistsWhenUsingDisableNetworkOption(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
daemon := mkDaemonFromEngine(eng, t)
|
||||
defer nuke(daemon)
|
||||
|
||||
config, hc, _, err := runconfig.Parse([]string{"-n=false", GetTestImage(daemon).ID, "ip", "addr", "show", "up"}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
jobCreate := eng.Job("create")
|
||||
if err := jobCreate.ImportEnv(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var id string
|
||||
jobCreate.Stdout.AddString(&id)
|
||||
if err := jobCreate.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// FIXME: this hack can be removed once Wait is a job
|
||||
c := daemon.Get(id)
|
||||
if c == nil {
|
||||
t.Fatalf("Couldn't retrieve container %s from daemon", id)
|
||||
}
|
||||
stdout, err := c.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
jobStart := eng.Job("start", id)
|
||||
if err := jobStart.ImportEnv(hc); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := jobStart.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
c.WaitTimeout(500 * time.Millisecond)
|
||||
c.Wait()
|
||||
output, err := ioutil.ReadAll(stdout)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
interfaces := regexp.MustCompile(`(?m)^[0-9]+: [a-zA-Z0-9]+`).FindAllString(string(output), -1)
|
||||
if len(interfaces) != 1 {
|
||||
t.Fatalf("Wrong interface count in test container: expected [*: lo], got %s", interfaces)
|
||||
}
|
||||
if !strings.HasSuffix(interfaces[0], ": lo") {
|
||||
t.Fatalf("Wrong interface in test container: expected [*: lo], got %s", interfaces)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrivilegedCanMknod(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
daemon := mkDaemonFromEngine(eng, t)
|
||||
defer daemon.Nuke()
|
||||
if output, err := runContainer(eng, daemon, []string{"--privileged", "_", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok"}, t); output != "ok\n" {
|
||||
t.Fatalf("Could not mknod into privileged container %s %v", output, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrivilegedCanMount(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
daemon := mkDaemonFromEngine(eng, t)
|
||||
defer daemon.Nuke()
|
||||
if output, _ := runContainer(eng, daemon, []string{"--privileged", "_", "sh", "-c", "mount -t tmpfs none /tmp && echo ok"}, t); output != "ok\n" {
|
||||
t.Fatal("Could not mount into privileged container")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnprivilegedCanMknod(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
daemon := mkDaemonFromEngine(eng, t)
|
||||
defer daemon.Nuke()
|
||||
if output, _ := runContainer(eng, daemon, []string{"_", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok"}, t); output != "ok\n" {
|
||||
t.Fatal("Couldn't mknod into secure container")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnprivilegedCannotMount(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
daemon := mkDaemonFromEngine(eng, t)
|
||||
defer daemon.Nuke()
|
||||
if output, _ := runContainer(eng, daemon, []string{"_", "sh", "-c", "mount -t tmpfs none /tmp || echo ok"}, t); output != "ok\n" {
|
||||
t.Fatal("Could mount into secure container")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
"github.com/dotcloud/docker/pkg/iptables"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// FIXME: this test should be a unit test.
|
||||
// For example by mocking os/exec to make sure iptables is not actually called.
|
||||
|
||||
func TestIptables(t *testing.T) {
|
||||
if _, err := iptables.Raw("-L"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
path := os.Getenv("PATH")
|
||||
os.Setenv("PATH", "")
|
||||
defer os.Setenv("PATH", path)
|
||||
if _, err := iptables.Raw("-L"); err == nil {
|
||||
t.Fatal("Not finding iptables in the PATH should cause an error")
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче