context_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. package builder
  2. import (
  3. "archive/tar"
  4. "bytes"
  5. "io"
  6. "io/ioutil"
  7. "os"
  8. "path/filepath"
  9. "strings"
  10. "testing"
  11. "github.com/docker/docker/pkg/archive"
  12. )
  13. const (
  14. dockerfileTestName = "Dockerfile-test"
  15. dockerfileContent = "FROM busybox"
  16. )
  17. var prepareEmpty = func(t *testing.T) string {
  18. return ""
  19. }
  20. var prepareNoFiles = func(t *testing.T) string {
  21. contextDir, err := ioutil.TempDir("", "builder-context-test")
  22. if err != nil {
  23. t.Fatalf("Error when creating temporary directory: %s", err)
  24. }
  25. return contextDir
  26. }
  27. var prepareOneFile = func(t *testing.T) string {
  28. contextDir, err := ioutil.TempDir("", "builder-context-test")
  29. if err != nil {
  30. t.Fatalf("Error when creating temporary directory: %s", err)
  31. }
  32. dockerfileFilename := filepath.Join(contextDir, dockerfileTestName)
  33. err = ioutil.WriteFile(dockerfileFilename, []byte(dockerfileContent), 0777)
  34. if err != nil {
  35. t.Fatalf("Error with writing to file: %s", err)
  36. }
  37. return contextDir
  38. }
  39. func testValidateContextDirectory(t *testing.T, prepare func(t *testing.T) string, excludes []string) {
  40. contextDir := prepare(t)
  41. defer os.RemoveAll(contextDir)
  42. err := ValidateContextDirectory(contextDir, excludes)
  43. if err != nil {
  44. t.Fatalf("Error should be nil, got: %s", err)
  45. }
  46. }
  47. func TestGetContextFromLocalDirNoDockerfile(t *testing.T) {
  48. contextDir, err := ioutil.TempDir("", "builder-context-test")
  49. defer os.RemoveAll(contextDir)
  50. if err != nil {
  51. t.Fatalf("Error with creating temporary directory: %s", err)
  52. }
  53. absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "")
  54. if err == nil {
  55. t.Fatalf("Error should not be nil")
  56. }
  57. if absContextDir != "" {
  58. t.Fatalf("Absolute directory path should be empty, got: %s", absContextDir)
  59. }
  60. if relDockerfile != "" {
  61. t.Fatalf("Relative path to Dockerfile should be empty, got: %s", relDockerfile)
  62. }
  63. }
  64. func TestGetContextFromLocalDirNotExistingDir(t *testing.T) {
  65. contextDir, err := ioutil.TempDir("", "builder-context-test")
  66. if err != nil {
  67. t.Fatalf("Error with creating temporary directory: %s", err)
  68. }
  69. defer os.RemoveAll(contextDir)
  70. fakePath := filepath.Join(contextDir, "fake")
  71. absContextDir, relDockerfile, err := GetContextFromLocalDir(fakePath, "")
  72. if err == nil {
  73. t.Fatalf("Error should not be nil")
  74. }
  75. if absContextDir != "" {
  76. t.Fatalf("Absolute directory path should be empty, got: %s", absContextDir)
  77. }
  78. if relDockerfile != "" {
  79. t.Fatalf("Relative path to Dockerfile should be empty, got: %s", relDockerfile)
  80. }
  81. }
  82. func TestGetContextFromLocalDirNotExistingDockerfile(t *testing.T) {
  83. contextDir, err := ioutil.TempDir("", "builder-context-test")
  84. if err != nil {
  85. t.Fatalf("Error with creating temporary directory: %s", err)
  86. }
  87. defer os.RemoveAll(contextDir)
  88. fakePath := filepath.Join(contextDir, "fake")
  89. absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, fakePath)
  90. if err == nil {
  91. t.Fatalf("Error should not be nil")
  92. }
  93. if absContextDir != "" {
  94. t.Fatalf("Absolute directory path should be empty, got: %s", absContextDir)
  95. }
  96. if relDockerfile != "" {
  97. t.Fatalf("Relative path to Dockerfile should be empty, got: %s", relDockerfile)
  98. }
  99. }
  100. func TestGetContextFromLocalDirWithNoDirectory(t *testing.T) {
  101. contextDir, err := ioutil.TempDir("", "builder-context-test")
  102. if err != nil {
  103. t.Fatalf("Error with creating temporary directory: %s", err)
  104. }
  105. defer os.RemoveAll(contextDir)
  106. dockerfileFilename := filepath.Join(contextDir, DefaultDockerfileName)
  107. err = ioutil.WriteFile(dockerfileFilename, []byte(dockerfileContent), 0777)
  108. if err != nil {
  109. t.Fatalf("Error when writing file (%s) contents: %s", dockerfileFilename, err)
  110. }
  111. workingDirectory, err := os.Getwd()
  112. if err != nil {
  113. t.Fatalf("Error when retrieving working directory: %s", err)
  114. }
  115. defer os.Chdir(workingDirectory)
  116. err = os.Chdir(contextDir)
  117. if err != nil {
  118. t.Fatalf("Error when changing directory to %s: %s", contextDir, err)
  119. }
  120. absContextDir, relDockerfile, err := GetContextFromLocalDir("", "")
  121. if err != nil {
  122. t.Fatalf("Error when getting context from local dir: %s", err)
  123. }
  124. if absContextDir != contextDir {
  125. t.Fatalf("Absolute directory path should be equal to %s, got: %s", contextDir, absContextDir)
  126. }
  127. if relDockerfile != DefaultDockerfileName {
  128. t.Fatalf("Relative path to dockerfile should be equal to %s, got: %s", DefaultDockerfileName, relDockerfile)
  129. }
  130. }
  131. func TestGetContextFromLocalDirWithDockerfile(t *testing.T) {
  132. contextDir, err := ioutil.TempDir("", "builder-context-test")
  133. if err != nil {
  134. t.Fatalf("Error with creating temporary directory: %s", err)
  135. }
  136. defer os.RemoveAll(contextDir)
  137. dockerfileFilename := filepath.Join(contextDir, DefaultDockerfileName)
  138. err = ioutil.WriteFile(dockerfileFilename, []byte(dockerfileContent), 0777)
  139. if err != nil {
  140. t.Fatalf("Error when writing file (%s) contents: %s", dockerfileFilename, err)
  141. }
  142. absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "")
  143. if err != nil {
  144. t.Fatalf("Error when getting context from local dir: %s", err)
  145. }
  146. if absContextDir != contextDir {
  147. t.Fatalf("Absolute directory path should be equal to %s, got: %s", contextDir, absContextDir)
  148. }
  149. if relDockerfile != DefaultDockerfileName {
  150. t.Fatalf("Relative path to dockerfile should be equal to %s, got: %s", DefaultDockerfileName, relDockerfile)
  151. }
  152. }
  153. func TestGetContextFromLocalDirLocalFile(t *testing.T) {
  154. contextDir, err := ioutil.TempDir("", "builder-context-test")
  155. if err != nil {
  156. t.Fatalf("Error with creating temporary directory: %s", err)
  157. }
  158. defer os.RemoveAll(contextDir)
  159. dockerfileFilename := filepath.Join(contextDir, DefaultDockerfileName)
  160. err = ioutil.WriteFile(dockerfileFilename, []byte(dockerfileContent), 0777)
  161. if err != nil {
  162. t.Fatalf("Error when writing file (%s) contents: %s", dockerfileFilename, err)
  163. }
  164. testFilename := filepath.Join(contextDir, "tmpTest")
  165. testContent := "test"
  166. err = ioutil.WriteFile(testFilename, []byte(testContent), 0777)
  167. if err != nil {
  168. t.Fatalf("Error when writing file (%s) contents: %s", testFilename, err)
  169. }
  170. absContextDir, relDockerfile, err := GetContextFromLocalDir(testFilename, "")
  171. if err == nil {
  172. t.Fatalf("Error should not be nil")
  173. }
  174. if absContextDir != "" {
  175. t.Fatalf("Absolute directory path should be empty, got: %s", absContextDir)
  176. }
  177. if relDockerfile != "" {
  178. t.Fatalf("Relative path to Dockerfile should be empty, got: %s", relDockerfile)
  179. }
  180. }
  181. func TestGetContextFromLocalDirWithCustomDockerfile(t *testing.T) {
  182. contextDir, err := ioutil.TempDir("", "builder-context-test")
  183. if err != nil {
  184. t.Fatalf("Error with creating temporary directory: %s", err)
  185. }
  186. defer os.RemoveAll(contextDir)
  187. workingDirectory, err := os.Getwd()
  188. if err != nil {
  189. t.Fatalf("Error when retrieving working directory: %s", err)
  190. }
  191. defer os.Chdir(workingDirectory)
  192. err = os.Chdir(contextDir)
  193. if err != nil {
  194. t.Fatalf("Error when changing directory to %s: %s", contextDir, err)
  195. }
  196. dockerfileFilename := filepath.Join(contextDir, dockerfileTestName)
  197. err = ioutil.WriteFile(dockerfileFilename, []byte(dockerfileContent), 0777)
  198. if err != nil {
  199. t.Fatalf("Error when writing file (%s) contents: %s", dockerfileFilename, err)
  200. }
  201. absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, dockerfileTestName)
  202. if err != nil {
  203. t.Fatalf("Error when getting context from local dir: %s", err)
  204. }
  205. if absContextDir != contextDir {
  206. t.Fatalf("Absolute directory path should be equal to %s, got: %s", contextDir, absContextDir)
  207. }
  208. if relDockerfile != dockerfileTestName {
  209. t.Fatalf("Relative path to dockerfile should be equal to %s, got: %s", dockerfileTestName, relDockerfile)
  210. }
  211. }
  212. func TestGetContextFromReaderString(t *testing.T) {
  213. tarArchive, relDockerfile, err := GetContextFromReader(ioutil.NopCloser(strings.NewReader(dockerfileContent)), "")
  214. if err != nil {
  215. t.Fatalf("Error when executing GetContextFromReader: %s", err)
  216. }
  217. tarReader := tar.NewReader(tarArchive)
  218. _, err = tarReader.Next()
  219. if err != nil {
  220. t.Fatalf("Error when reading tar archive: %s", err)
  221. }
  222. buff := new(bytes.Buffer)
  223. buff.ReadFrom(tarReader)
  224. contents := buff.String()
  225. _, err = tarReader.Next()
  226. if err != io.EOF {
  227. t.Fatalf("Tar stream too long: %s", err)
  228. }
  229. if err = tarArchive.Close(); err != nil {
  230. t.Fatalf("Error when closing tar stream: %s", err)
  231. }
  232. if dockerfileContent != contents {
  233. t.Fatalf("Uncompressed tar archive does not equal: %s, got: %s", dockerfileContent, contents)
  234. }
  235. if relDockerfile != DefaultDockerfileName {
  236. t.Fatalf("Relative path not equals %s, got: %s", DefaultDockerfileName, relDockerfile)
  237. }
  238. }
  239. func TestGetContextFromReaderTar(t *testing.T) {
  240. contextDir, err := ioutil.TempDir("", "builder-context-test")
  241. if err != nil {
  242. t.Fatalf("Error with creating temporary directory: %s", err)
  243. }
  244. defer os.RemoveAll(contextDir)
  245. dockerfileFilename := filepath.Join(contextDir, dockerfileTestName)
  246. err = ioutil.WriteFile(dockerfileFilename, []byte(dockerfileContent), 0777)
  247. if err != nil {
  248. t.Fatalf("Error when writing file (%s) contents: %s", dockerfileFilename, err)
  249. }
  250. tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
  251. if err != nil {
  252. t.Fatalf("Error when creating tar: %s", err)
  253. }
  254. tarArchive, relDockerfile, err := GetContextFromReader(tarStream, dockerfileTestName)
  255. if err != nil {
  256. t.Fatalf("Error when executing GetContextFromReader: %s", err)
  257. }
  258. tarReader := tar.NewReader(tarArchive)
  259. header, err := tarReader.Next()
  260. if err != nil {
  261. t.Fatalf("Error when reading tar archive: %s", err)
  262. }
  263. if header.Name != dockerfileTestName {
  264. t.Fatalf("Dockerfile name should be: %s, got: %s", dockerfileTestName, header.Name)
  265. }
  266. buff := new(bytes.Buffer)
  267. buff.ReadFrom(tarReader)
  268. contents := buff.String()
  269. _, err = tarReader.Next()
  270. if err != io.EOF {
  271. t.Fatalf("Tar stream too long: %s", err)
  272. }
  273. if err = tarArchive.Close(); err != nil {
  274. t.Fatalf("Error when closing tar stream: %s", err)
  275. }
  276. if dockerfileContent != contents {
  277. t.Fatalf("Uncompressed tar archive does not equal: %s, got: %s", dockerfileContent, contents)
  278. }
  279. if relDockerfile != dockerfileTestName {
  280. t.Fatalf("Relative path not equals %s, got: %s", dockerfileTestName, relDockerfile)
  281. }
  282. }
  283. func TestValidateContextDirectoryEmptyContext(t *testing.T) {
  284. testValidateContextDirectory(t, prepareEmpty, []string{})
  285. }
  286. func TestValidateContextDirectoryContextWithNoFiles(t *testing.T) {
  287. testValidateContextDirectory(t, prepareNoFiles, []string{})
  288. }
  289. func TestValidateContextDirectoryWithOneFile(t *testing.T) {
  290. testValidateContextDirectory(t, prepareOneFile, []string{})
  291. }
  292. func TestValidateContextDirectoryWithOneFileExcludes(t *testing.T) {
  293. testValidateContextDirectory(t, prepareOneFile, []string{dockerfileTestName})
  294. }