docker_cli_build_test.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "os/exec"
  6. "path/filepath"
  7. "strings"
  8. "testing"
  9. )
  10. func TestBuildSixtySteps(t *testing.T) {
  11. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildSixtySteps")
  12. buildCmd := exec.Command(dockerBinary, "build", "-t", "foobuildsixtysteps", ".")
  13. buildCmd.Dir = buildDirectory
  14. out, exitCode, err := runCommandWithOutput(buildCmd)
  15. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  16. if err != nil || exitCode != 0 {
  17. t.Fatal("failed to build the image")
  18. }
  19. deleteImages("foobuildsixtysteps")
  20. logDone("build - build an image with sixty build steps")
  21. }
  22. func TestAddSingleFileToRoot(t *testing.T) {
  23. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd")
  24. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", "SingleFileToRoot")
  25. buildCmd.Dir = buildDirectory
  26. out, exitCode, err := runCommandWithOutput(buildCmd)
  27. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  28. if err != nil || exitCode != 0 {
  29. t.Fatal("failed to build the image")
  30. }
  31. deleteImages("testaddimg")
  32. logDone("build - add single file to root")
  33. }
  34. func TestAddSingleFileToExistDir(t *testing.T) {
  35. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd")
  36. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", "SingleFileToExistDir")
  37. buildCmd.Dir = buildDirectory
  38. out, exitCode, err := runCommandWithOutput(buildCmd)
  39. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  40. if err != nil || exitCode != 0 {
  41. t.Fatal("failed to build the image")
  42. }
  43. deleteImages("testaddimg")
  44. logDone("build - add single file to existing dir")
  45. }
  46. func TestAddSingleFileToNonExistDir(t *testing.T) {
  47. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd")
  48. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", "SingleFileToNonExistDir")
  49. buildCmd.Dir = buildDirectory
  50. out, exitCode, err := runCommandWithOutput(buildCmd)
  51. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  52. if err != nil || exitCode != 0 {
  53. t.Fatal("failed to build the image")
  54. }
  55. deleteImages("testaddimg")
  56. logDone("build - add single file to non-existing dir")
  57. }
  58. func TestAddDirContentToRoot(t *testing.T) {
  59. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd")
  60. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", "DirContentToRoot")
  61. buildCmd.Dir = buildDirectory
  62. out, exitCode, err := runCommandWithOutput(buildCmd)
  63. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  64. if err != nil || exitCode != 0 {
  65. t.Fatal("failed to build the image")
  66. }
  67. deleteImages("testaddimg")
  68. logDone("build - add directory contents to root")
  69. }
  70. func TestAddDirContentToExistDir(t *testing.T) {
  71. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd")
  72. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", "DirContentToExistDir")
  73. buildCmd.Dir = buildDirectory
  74. out, exitCode, err := runCommandWithOutput(buildCmd)
  75. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  76. if err != nil || exitCode != 0 {
  77. t.Fatal("failed to build the image")
  78. }
  79. deleteImages("testaddimg")
  80. logDone("build - add directory contents to existing dir")
  81. }
  82. func TestAddWholeDirToRoot(t *testing.T) {
  83. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd")
  84. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", "WholeDirToRoot")
  85. buildCmd.Dir = buildDirectory
  86. out, exitCode, err := runCommandWithOutput(buildCmd)
  87. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  88. if err != nil || exitCode != 0 {
  89. t.Fatal("failed to build the image")
  90. }
  91. deleteImages("testaddimg")
  92. logDone("build - add whole directory to root")
  93. }
  94. // Issue #5270 - ensure we throw a better error than "unexpected EOF"
  95. // when we can't access files in the context.
  96. func TestBuildWithInaccessibleFilesInContext(t *testing.T) {
  97. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildWithInaccessibleFilesInContext")
  98. {
  99. // This is used to ensure we detect inaccessible files early during build in the cli client
  100. pathToInaccessibleFileBuildDirectory := filepath.Join(buildDirectory, "inaccessiblefile")
  101. pathToFileWithoutReadAccess := filepath.Join(pathToInaccessibleFileBuildDirectory, "fileWithoutReadAccess")
  102. err := os.Chown(pathToFileWithoutReadAccess, 0, 0)
  103. errorOut(err, t, fmt.Sprintf("failed to chown file to root: %s", err))
  104. err = os.Chmod(pathToFileWithoutReadAccess, 0700)
  105. errorOut(err, t, fmt.Sprintf("failed to chmod file to 700: %s", err))
  106. buildCommandStatement := fmt.Sprintf("%s build -t inaccessiblefiles .", dockerBinary)
  107. buildCmd := exec.Command("su", "unprivilegeduser", "-c", buildCommandStatement)
  108. buildCmd.Dir = pathToInaccessibleFileBuildDirectory
  109. out, exitCode, err := runCommandWithOutput(buildCmd)
  110. if err == nil || exitCode == 0 {
  111. t.Fatalf("build should have failed: %s %s", err, out)
  112. }
  113. // check if we've detected the failure before we started building
  114. if !strings.Contains(out, "no permission to read from ") {
  115. t.Fatalf("output should've contained the string: no permission to read from ")
  116. }
  117. if !strings.Contains(out, "Error checking context is accessible") {
  118. t.Fatalf("output should've contained the string: Error checking context is accessible")
  119. }
  120. }
  121. {
  122. // This is used to ensure we detect inaccessible directories early during build in the cli client
  123. pathToInaccessibleDirectoryBuildDirectory := filepath.Join(buildDirectory, "inaccessibledirectory")
  124. pathToDirectoryWithoutReadAccess := filepath.Join(pathToInaccessibleDirectoryBuildDirectory, "directoryWeCantStat")
  125. pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar")
  126. err := os.Chown(pathToDirectoryWithoutReadAccess, 0, 0)
  127. errorOut(err, t, fmt.Sprintf("failed to chown directory to root: %s", err))
  128. err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444)
  129. errorOut(err, t, fmt.Sprintf("failed to chmod directory to 755: %s", err))
  130. err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700)
  131. errorOut(err, t, fmt.Sprintf("failed to chmod file to 444: %s", err))
  132. buildCommandStatement := fmt.Sprintf("%s build -t inaccessiblefiles .", dockerBinary)
  133. buildCmd := exec.Command("su", "unprivilegeduser", "-c", buildCommandStatement)
  134. buildCmd.Dir = pathToInaccessibleDirectoryBuildDirectory
  135. out, exitCode, err := runCommandWithOutput(buildCmd)
  136. if err == nil || exitCode == 0 {
  137. t.Fatalf("build should have failed: %s %s", err, out)
  138. }
  139. // check if we've detected the failure before we started building
  140. if !strings.Contains(out, "can't stat") {
  141. t.Fatalf("output should've contained the string: can't access %s", out)
  142. }
  143. if !strings.Contains(out, "Error checking context is accessible") {
  144. t.Fatalf("output should've contained the string: Error checking context is accessible")
  145. }
  146. }
  147. {
  148. // This is used to ensure we don't follow links when checking if everything in the context is accessible
  149. // This test doesn't require that we run commands as an unprivileged user
  150. pathToDirectoryWhichContainsLinks := filepath.Join(buildDirectory, "linksdirectory")
  151. buildCmd := exec.Command(dockerBinary, "build", "-t", "testlinksok", ".")
  152. buildCmd.Dir = pathToDirectoryWhichContainsLinks
  153. out, exitCode, err := runCommandWithOutput(buildCmd)
  154. if err != nil || exitCode != 0 {
  155. t.Fatalf("build should have worked: %s %s", err, out)
  156. }
  157. deleteImages("testlinksok")
  158. }
  159. deleteImages("inaccessiblefiles")
  160. logDone("build - ADD from context with inaccessible files must fail")
  161. logDone("build - ADD from context with accessible links must work")
  162. }
  163. // TODO: TestCaching
  164. // TODO: TestADDCacheInvalidation