context_test.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. package builder
  2. import (
  3. "archive/tar"
  4. "bytes"
  5. "io"
  6. "io/ioutil"
  7. "path/filepath"
  8. "runtime"
  9. "strings"
  10. "testing"
  11. "github.com/docker/docker/pkg/archive"
  12. )
  13. var prepareEmpty = func(t *testing.T) (string, func()) {
  14. return "", func() {}
  15. }
  16. var prepareNoFiles = func(t *testing.T) (string, func()) {
  17. return createTestTempDir(t, "", "builder-context-test")
  18. }
  19. var prepareOneFile = func(t *testing.T) (string, func()) {
  20. contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
  21. createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
  22. return contextDir, cleanup
  23. }
  24. func testValidateContextDirectory(t *testing.T, prepare func(t *testing.T) (string, func()), excludes []string) {
  25. contextDir, cleanup := prepare(t)
  26. defer cleanup()
  27. err := ValidateContextDirectory(contextDir, excludes)
  28. if err != nil {
  29. t.Fatalf("Error should be nil, got: %s", err)
  30. }
  31. }
  32. func TestGetContextFromLocalDirNoDockerfile(t *testing.T) {
  33. contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
  34. defer cleanup()
  35. absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "")
  36. if err == nil {
  37. t.Fatalf("Error should not be nil")
  38. }
  39. if absContextDir != "" {
  40. t.Fatalf("Absolute directory path should be empty, got: %s", absContextDir)
  41. }
  42. if relDockerfile != "" {
  43. t.Fatalf("Relative path to Dockerfile should be empty, got: %s", relDockerfile)
  44. }
  45. }
  46. func TestGetContextFromLocalDirNotExistingDir(t *testing.T) {
  47. contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
  48. defer cleanup()
  49. fakePath := filepath.Join(contextDir, "fake")
  50. absContextDir, relDockerfile, err := GetContextFromLocalDir(fakePath, "")
  51. if err == nil {
  52. t.Fatalf("Error should not be nil")
  53. }
  54. if absContextDir != "" {
  55. t.Fatalf("Absolute directory path should be empty, got: %s", absContextDir)
  56. }
  57. if relDockerfile != "" {
  58. t.Fatalf("Relative path to Dockerfile should be empty, got: %s", relDockerfile)
  59. }
  60. }
  61. func TestGetContextFromLocalDirNotExistingDockerfile(t *testing.T) {
  62. contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
  63. defer cleanup()
  64. fakePath := filepath.Join(contextDir, "fake")
  65. absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, fakePath)
  66. if err == nil {
  67. t.Fatalf("Error should not be nil")
  68. }
  69. if absContextDir != "" {
  70. t.Fatalf("Absolute directory path should be empty, got: %s", absContextDir)
  71. }
  72. if relDockerfile != "" {
  73. t.Fatalf("Relative path to Dockerfile should be empty, got: %s", relDockerfile)
  74. }
  75. }
  76. func TestGetContextFromLocalDirWithNoDirectory(t *testing.T) {
  77. contextDir, dirCleanup := createTestTempDir(t, "", "builder-context-test")
  78. defer dirCleanup()
  79. createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
  80. chdirCleanup := chdir(t, contextDir)
  81. defer chdirCleanup()
  82. absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "")
  83. if err != nil {
  84. t.Fatalf("Error when getting context from local dir: %s", err)
  85. }
  86. if absContextDir != contextDir {
  87. t.Fatalf("Absolute directory path should be equal to %s, got: %s", contextDir, absContextDir)
  88. }
  89. if relDockerfile != DefaultDockerfileName {
  90. t.Fatalf("Relative path to dockerfile should be equal to %s, got: %s", DefaultDockerfileName, relDockerfile)
  91. }
  92. }
  93. func TestGetContextFromLocalDirWithDockerfile(t *testing.T) {
  94. contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
  95. defer cleanup()
  96. createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
  97. absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "")
  98. if err != nil {
  99. t.Fatalf("Error when getting context from local dir: %s", err)
  100. }
  101. if absContextDir != contextDir {
  102. t.Fatalf("Absolute directory path should be equal to %s, got: %s", contextDir, absContextDir)
  103. }
  104. if relDockerfile != DefaultDockerfileName {
  105. t.Fatalf("Relative path to dockerfile should be equal to %s, got: %s", DefaultDockerfileName, relDockerfile)
  106. }
  107. }
  108. func TestGetContextFromLocalDirLocalFile(t *testing.T) {
  109. contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
  110. defer cleanup()
  111. createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
  112. testFilename := createTestTempFile(t, contextDir, "tmpTest", "test", 0777)
  113. absContextDir, relDockerfile, err := GetContextFromLocalDir(testFilename, "")
  114. if err == nil {
  115. t.Fatalf("Error should not be nil")
  116. }
  117. if absContextDir != "" {
  118. t.Fatalf("Absolute directory path should be empty, got: %s", absContextDir)
  119. }
  120. if relDockerfile != "" {
  121. t.Fatalf("Relative path to Dockerfile should be empty, got: %s", relDockerfile)
  122. }
  123. }
  124. func TestGetContextFromLocalDirWithCustomDockerfile(t *testing.T) {
  125. contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
  126. defer cleanup()
  127. chdirCleanup := chdir(t, contextDir)
  128. defer chdirCleanup()
  129. createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
  130. absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, DefaultDockerfileName)
  131. if err != nil {
  132. t.Fatalf("Error when getting context from local dir: %s", err)
  133. }
  134. if absContextDir != contextDir {
  135. t.Fatalf("Absolute directory path should be equal to %s, got: %s", contextDir, absContextDir)
  136. }
  137. if relDockerfile != DefaultDockerfileName {
  138. t.Fatalf("Relative path to dockerfile should be equal to %s, got: %s", DefaultDockerfileName, relDockerfile)
  139. }
  140. }
  141. func TestGetContextFromReaderString(t *testing.T) {
  142. tarArchive, relDockerfile, err := GetContextFromReader(ioutil.NopCloser(strings.NewReader(dockerfileContents)), "")
  143. if err != nil {
  144. t.Fatalf("Error when executing GetContextFromReader: %s", err)
  145. }
  146. tarReader := tar.NewReader(tarArchive)
  147. _, err = tarReader.Next()
  148. if err != nil {
  149. t.Fatalf("Error when reading tar archive: %s", err)
  150. }
  151. buff := new(bytes.Buffer)
  152. buff.ReadFrom(tarReader)
  153. contents := buff.String()
  154. _, err = tarReader.Next()
  155. if err != io.EOF {
  156. t.Fatalf("Tar stream too long: %s", err)
  157. }
  158. if err = tarArchive.Close(); err != nil {
  159. t.Fatalf("Error when closing tar stream: %s", err)
  160. }
  161. if dockerfileContents != contents {
  162. t.Fatalf("Uncompressed tar archive does not equal: %s, got: %s", dockerfileContents, contents)
  163. }
  164. if relDockerfile != DefaultDockerfileName {
  165. t.Fatalf("Relative path not equals %s, got: %s", DefaultDockerfileName, relDockerfile)
  166. }
  167. }
  168. func TestGetContextFromReaderTar(t *testing.T) {
  169. contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
  170. defer cleanup()
  171. createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
  172. tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
  173. if err != nil {
  174. t.Fatalf("Error when creating tar: %s", err)
  175. }
  176. tarArchive, relDockerfile, err := GetContextFromReader(tarStream, DefaultDockerfileName)
  177. if err != nil {
  178. t.Fatalf("Error when executing GetContextFromReader: %s", err)
  179. }
  180. tarReader := tar.NewReader(tarArchive)
  181. header, err := tarReader.Next()
  182. if err != nil {
  183. t.Fatalf("Error when reading tar archive: %s", err)
  184. }
  185. if header.Name != DefaultDockerfileName {
  186. t.Fatalf("Dockerfile name should be: %s, got: %s", DefaultDockerfileName, header.Name)
  187. }
  188. buff := new(bytes.Buffer)
  189. buff.ReadFrom(tarReader)
  190. contents := buff.String()
  191. _, err = tarReader.Next()
  192. if err != io.EOF {
  193. t.Fatalf("Tar stream too long: %s", err)
  194. }
  195. if err = tarArchive.Close(); err != nil {
  196. t.Fatalf("Error when closing tar stream: %s", err)
  197. }
  198. if dockerfileContents != contents {
  199. t.Fatalf("Uncompressed tar archive does not equal: %s, got: %s", dockerfileContents, contents)
  200. }
  201. if relDockerfile != DefaultDockerfileName {
  202. t.Fatalf("Relative path not equals %s, got: %s", DefaultDockerfileName, relDockerfile)
  203. }
  204. }
  205. func TestValidateContextDirectoryEmptyContext(t *testing.T) {
  206. // This isn't a valid test on Windows. See https://play.golang.org/p/RR6z6jxR81.
  207. // The test will ultimately end up calling filepath.Abs(""). On Windows,
  208. // golang will error. On Linux, golang will return /. Due to there being
  209. // drive letters on Windows, this is probably the correct behaviour for
  210. // Windows.
  211. if runtime.GOOS == "windows" {
  212. t.Skip("Invalid test on Windows")
  213. }
  214. testValidateContextDirectory(t, prepareEmpty, []string{})
  215. }
  216. func TestValidateContextDirectoryContextWithNoFiles(t *testing.T) {
  217. testValidateContextDirectory(t, prepareNoFiles, []string{})
  218. }
  219. func TestValidateContextDirectoryWithOneFile(t *testing.T) {
  220. testValidateContextDirectory(t, prepareOneFile, []string{})
  221. }
  222. func TestValidateContextDirectoryWithOneFileExcludes(t *testing.T) {
  223. testValidateContextDirectory(t, prepareOneFile, []string{DefaultDockerfileName})
  224. }