Signed-off-by: Victor Vieux <vieux@docker.com>
| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
"io/ioutil" |
| 7 | 7 |
"os" |
| 8 | 8 |
"os/exec" |
| 9 |
+ "path" |
|
| 9 | 10 |
"path/filepath" |
| 10 | 11 |
"reflect" |
| 11 | 12 |
"regexp" |
| ... | ... |
@@ -1644,3 +1645,64 @@ func TestRunWithBadDevice(t *testing.T) {
|
| 1644 | 1644 |
} |
| 1645 | 1645 |
logDone("run - error with bad device")
|
| 1646 | 1646 |
} |
| 1647 |
+ |
|
| 1648 |
+func TestEntrypoint(t *testing.T) {
|
|
| 1649 |
+ name := "entrypoint" |
|
| 1650 |
+ cmd := exec.Command(dockerBinary, "run", "--name", name, "--entrypoint", "/bin/echo", "busybox", "-n", "foobar") |
|
| 1651 |
+ out, _, err := runCommandWithOutput(cmd) |
|
| 1652 |
+ if err != nil {
|
|
| 1653 |
+ t.Fatal(err, out) |
|
| 1654 |
+ } |
|
| 1655 |
+ expected := "foobar" |
|
| 1656 |
+ if out != expected {
|
|
| 1657 |
+ t.Fatalf("Output should be %q, actual out: %q", expected, out)
|
|
| 1658 |
+ } |
|
| 1659 |
+ logDone("run - entrypoint")
|
|
| 1660 |
+} |
|
| 1661 |
+ |
|
| 1662 |
+func TestBindMounts(t *testing.T) {
|
|
| 1663 |
+ tmpDir, err := ioutil.TempDir("", "docker-test-container")
|
|
| 1664 |
+ if err != nil {
|
|
| 1665 |
+ t.Fatal(err) |
|
| 1666 |
+ } |
|
| 1667 |
+ |
|
| 1668 |
+ defer os.RemoveAll(tmpDir) |
|
| 1669 |
+ writeFile(path.Join(tmpDir, "touch-me"), "", t) |
|
| 1670 |
+ |
|
| 1671 |
+ // Test reading from a read-only bind mount |
|
| 1672 |
+ cmd := exec.Command(dockerBinary, "run", "-v", fmt.Sprintf("%s:/tmp:ro", tmpDir), "busybox", "ls", "/tmp")
|
|
| 1673 |
+ out, _, err := runCommandWithOutput(cmd) |
|
| 1674 |
+ if err != nil {
|
|
| 1675 |
+ t.Fatal(err, out) |
|
| 1676 |
+ } |
|
| 1677 |
+ if !strings.Contains(out, "touch-me") {
|
|
| 1678 |
+ t.Fatal("Container failed to read from bind mount")
|
|
| 1679 |
+ } |
|
| 1680 |
+ |
|
| 1681 |
+ // test writing to bind mount |
|
| 1682 |
+ cmd = exec.Command(dockerBinary, "run", "-v", fmt.Sprintf("%s:/tmp:rw", tmpDir), "busybox", "touch", "/tmp/holla")
|
|
| 1683 |
+ out, _, err = runCommandWithOutput(cmd) |
|
| 1684 |
+ if err != nil {
|
|
| 1685 |
+ t.Fatal(err, out) |
|
| 1686 |
+ } |
|
| 1687 |
+ readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist |
|
| 1688 |
+ |
|
| 1689 |
+ // test mounting to an illegal destination directory |
|
| 1690 |
+ cmd = exec.Command(dockerBinary, "run", "-v", fmt.Sprintf("%s:.", tmpDir), "busybox", "ls", ".")
|
|
| 1691 |
+ _, err = runCommand(cmd) |
|
| 1692 |
+ if err == nil {
|
|
| 1693 |
+ t.Fatal("Container bind mounted illegal directory")
|
|
| 1694 |
+ } |
|
| 1695 |
+ |
|
| 1696 |
+ // test mount a file |
|
| 1697 |
+ cmd = exec.Command(dockerBinary, "run", "-v", fmt.Sprintf("%s/holla:/tmp/holla:rw", tmpDir), "busybox", "sh", "-c", "echo -n 'yotta' > /tmp/holla")
|
|
| 1698 |
+ _, err = runCommand(cmd) |
|
| 1699 |
+ if err != nil {
|
|
| 1700 |
+ t.Fatal(err, out) |
|
| 1701 |
+ } |
|
| 1702 |
+ content := readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist |
|
| 1703 |
+ expected := "yotta" |
|
| 1704 |
+ if content != expected {
|
|
| 1705 |
+ t.Fatalf("Output should be %q, actual out: %q", expected, content)
|
|
| 1706 |
+ } |
|
| 1707 |
+} |
| ... | ... |
@@ -2,6 +2,7 @@ package main |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
+ "io" |
|
| 5 | 6 |
"io/ioutil" |
| 6 | 7 |
"net/http" |
| 7 | 8 |
"net/http/httptest" |
| ... | ... |
@@ -368,3 +369,36 @@ func fakeGIT(name string, files map[string]string) (*FakeGIT, error) {
|
| 368 | 368 |
RepoURL: fmt.Sprintf("%s/%s.git", server.URL, name),
|
| 369 | 369 |
}, nil |
| 370 | 370 |
} |
| 371 |
+ |
|
| 372 |
+// Write `content` to the file at path `dst`, creating it if necessary, |
|
| 373 |
+// as well as any missing directories. |
|
| 374 |
+// The file is truncated if it already exists. |
|
| 375 |
+// Call t.Fatal() at the first error. |
|
| 376 |
+func writeFile(dst, content string, t *testing.T) {
|
|
| 377 |
+ // Create subdirectories if necessary |
|
| 378 |
+ if err := os.MkdirAll(path.Dir(dst), 0700); err != nil && !os.IsExist(err) {
|
|
| 379 |
+ t.Fatal(err) |
|
| 380 |
+ } |
|
| 381 |
+ f, err := os.OpenFile(dst, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0700) |
|
| 382 |
+ if err != nil {
|
|
| 383 |
+ t.Fatal(err) |
|
| 384 |
+ } |
|
| 385 |
+ // Write content (truncate if it exists) |
|
| 386 |
+ if _, err := io.Copy(f, strings.NewReader(content)); err != nil {
|
|
| 387 |
+ t.Fatal(err) |
|
| 388 |
+ } |
|
| 389 |
+} |
|
| 390 |
+ |
|
| 391 |
+// Return the contents of file at path `src`. |
|
| 392 |
+// Call t.Fatal() at the first error (including if the file doesn't exist) |
|
| 393 |
+func readFile(src string, t *testing.T) (content string) {
|
|
| 394 |
+ f, err := os.Open(src) |
|
| 395 |
+ if err != nil {
|
|
| 396 |
+ t.Fatal(err) |
|
| 397 |
+ } |
|
| 398 |
+ data, err := ioutil.ReadAll(f) |
|
| 399 |
+ if err != nil {
|
|
| 400 |
+ t.Fatal(err) |
|
| 401 |
+ } |
|
| 402 |
+ return string(data) |
|
| 403 |
+} |
| ... | ... |
@@ -1,12 +1,8 @@ |
| 1 | 1 |
package docker |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "fmt" |
|
| 5 | 4 |
"io" |
| 6 | 5 |
"io/ioutil" |
| 7 |
- "os" |
|
| 8 |
- "path" |
|
| 9 |
- "strings" |
|
| 10 | 6 |
"testing" |
| 11 | 7 |
"time" |
| 12 | 8 |
|
| ... | ... |
@@ -179,53 +175,6 @@ func TestTty(t *testing.T) {
|
| 179 | 179 |
} |
| 180 | 180 |
} |
| 181 | 181 |
|
| 182 |
-func TestEntrypoint(t *testing.T) {
|
|
| 183 |
- daemon := mkDaemon(t) |
|
| 184 |
- defer nuke(daemon) |
|
| 185 |
- container, _, err := daemon.Create( |
|
| 186 |
- &runconfig.Config{
|
|
| 187 |
- Image: GetTestImage(daemon).ID, |
|
| 188 |
- Entrypoint: []string{"/bin/echo"},
|
|
| 189 |
- Cmd: []string{"-n", "foobar"},
|
|
| 190 |
- }, |
|
| 191 |
- "", |
|
| 192 |
- ) |
|
| 193 |
- if err != nil {
|
|
| 194 |
- t.Fatal(err) |
|
| 195 |
- } |
|
| 196 |
- defer daemon.Destroy(container) |
|
| 197 |
- output, err := container.Output() |
|
| 198 |
- if err != nil {
|
|
| 199 |
- t.Fatal(err) |
|
| 200 |
- } |
|
| 201 |
- if string(output) != "foobar" {
|
|
| 202 |
- t.Error(string(output)) |
|
| 203 |
- } |
|
| 204 |
-} |
|
| 205 |
- |
|
| 206 |
-func TestEntrypointNoCmd(t *testing.T) {
|
|
| 207 |
- daemon := mkDaemon(t) |
|
| 208 |
- defer nuke(daemon) |
|
| 209 |
- container, _, err := daemon.Create( |
|
| 210 |
- &runconfig.Config{
|
|
| 211 |
- Image: GetTestImage(daemon).ID, |
|
| 212 |
- Entrypoint: []string{"/bin/echo", "foobar"},
|
|
| 213 |
- }, |
|
| 214 |
- "", |
|
| 215 |
- ) |
|
| 216 |
- if err != nil {
|
|
| 217 |
- t.Fatal(err) |
|
| 218 |
- } |
|
| 219 |
- defer daemon.Destroy(container) |
|
| 220 |
- output, err := container.Output() |
|
| 221 |
- if err != nil {
|
|
| 222 |
- t.Fatal(err) |
|
| 223 |
- } |
|
| 224 |
- if strings.Trim(string(output), "\r\n") != "foobar" {
|
|
| 225 |
- t.Error(string(output)) |
|
| 226 |
- } |
|
| 227 |
-} |
|
| 228 |
- |
|
| 229 | 182 |
func BenchmarkRunSequential(b *testing.B) {
|
| 230 | 183 |
daemon := mkDaemon(b) |
| 231 | 184 |
defer nuke(daemon) |
| ... | ... |
@@ -303,43 +252,3 @@ func BenchmarkRunParallel(b *testing.B) {
|
| 303 | 303 |
b.Fatal(errors) |
| 304 | 304 |
} |
| 305 | 305 |
} |
| 306 |
- |
|
| 307 |
-func tempDir(t *testing.T) string {
|
|
| 308 |
- tmpDir, err := ioutil.TempDir("", "docker-test-container")
|
|
| 309 |
- if err != nil {
|
|
| 310 |
- t.Fatal(err) |
|
| 311 |
- } |
|
| 312 |
- return tmpDir |
|
| 313 |
-} |
|
| 314 |
- |
|
| 315 |
-func TestBindMounts(t *testing.T) {
|
|
| 316 |
- eng := NewTestEngine(t) |
|
| 317 |
- r := mkDaemonFromEngine(eng, t) |
|
| 318 |
- defer r.Nuke() |
|
| 319 |
- |
|
| 320 |
- tmpDir := tempDir(t) |
|
| 321 |
- defer os.RemoveAll(tmpDir) |
|
| 322 |
- writeFile(path.Join(tmpDir, "touch-me"), "", t) |
|
| 323 |
- |
|
| 324 |
- // Test reading from a read-only bind mount |
|
| 325 |
- stdout, _ := runContainer(eng, r, []string{"-v", fmt.Sprintf("%s:/tmp:ro", tmpDir), "_", "ls", "/tmp"}, t)
|
|
| 326 |
- if !strings.Contains(stdout, "touch-me") {
|
|
| 327 |
- t.Fatal("Container failed to read from bind mount")
|
|
| 328 |
- } |
|
| 329 |
- |
|
| 330 |
- // test writing to bind mount |
|
| 331 |
- runContainer(eng, r, []string{"-v", fmt.Sprintf("%s:/tmp:rw", tmpDir), "_", "touch", "/tmp/holla"}, t)
|
|
| 332 |
- readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist |
|
| 333 |
- |
|
| 334 |
- // test mounting to an illegal destination directory |
|
| 335 |
- if _, err := runContainer(eng, r, []string{"-v", fmt.Sprintf("%s:.", tmpDir), "_", "ls", "."}, nil); err == nil {
|
|
| 336 |
- t.Fatal("Container bind mounted illegal directory")
|
|
| 337 |
- } |
|
| 338 |
- |
|
| 339 |
- // test mount a file |
|
| 340 |
- runContainer(eng, r, []string{"-v", fmt.Sprintf("%s/holla:/tmp/holla:rw", tmpDir), "_", "sh", "-c", "echo -n 'yotta' > /tmp/holla"}, t)
|
|
| 341 |
- content := readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist |
|
| 342 |
- if content != "yotta" {
|
|
| 343 |
- t.Fatal("Container failed to write to bind mount file")
|
|
| 344 |
- } |
|
| 345 |
-} |