evaluator_test.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package dockerfile // import "github.com/docker/docker/builder/dockerfile"
  2. import (
  3. "os"
  4. "testing"
  5. "github.com/docker/docker/builder/dockerfile/instructions"
  6. "github.com/docker/docker/builder/remotecontext"
  7. "github.com/docker/docker/pkg/archive"
  8. "github.com/docker/docker/pkg/reexec"
  9. "github.com/gotestyourself/gotestyourself/assert"
  10. is "github.com/gotestyourself/gotestyourself/assert/cmp"
  11. "github.com/gotestyourself/gotestyourself/skip"
  12. )
  13. type dispatchTestCase struct {
  14. name, expectedError string
  15. cmd instructions.Command
  16. files map[string]string
  17. }
  18. func init() {
  19. reexec.Init()
  20. }
  21. func initDispatchTestCases() []dispatchTestCase {
  22. dispatchTestCases := []dispatchTestCase{
  23. {
  24. name: "ADD multiple files to file",
  25. cmd: &instructions.AddCommand{SourcesAndDest: instructions.SourcesAndDest{
  26. "file1.txt",
  27. "file2.txt",
  28. "test",
  29. }},
  30. expectedError: "When using ADD with more than one source file, the destination must be a directory and end with a /",
  31. files: map[string]string{"file1.txt": "test1", "file2.txt": "test2"},
  32. },
  33. {
  34. name: "Wildcard ADD multiple files to file",
  35. cmd: &instructions.AddCommand{SourcesAndDest: instructions.SourcesAndDest{
  36. "file*.txt",
  37. "test",
  38. }},
  39. expectedError: "When using ADD with more than one source file, the destination must be a directory and end with a /",
  40. files: map[string]string{"file1.txt": "test1", "file2.txt": "test2"},
  41. },
  42. {
  43. name: "COPY multiple files to file",
  44. cmd: &instructions.CopyCommand{SourcesAndDest: instructions.SourcesAndDest{
  45. "file1.txt",
  46. "file2.txt",
  47. "test",
  48. }},
  49. expectedError: "When using COPY with more than one source file, the destination must be a directory and end with a /",
  50. files: map[string]string{"file1.txt": "test1", "file2.txt": "test2"},
  51. },
  52. {
  53. name: "ADD multiple files to file with whitespace",
  54. cmd: &instructions.AddCommand{SourcesAndDest: instructions.SourcesAndDest{
  55. "test file1.txt",
  56. "test file2.txt",
  57. "test",
  58. }},
  59. expectedError: "When using ADD with more than one source file, the destination must be a directory and end with a /",
  60. files: map[string]string{"test file1.txt": "test1", "test file2.txt": "test2"},
  61. },
  62. {
  63. name: "COPY multiple files to file with whitespace",
  64. cmd: &instructions.CopyCommand{SourcesAndDest: instructions.SourcesAndDest{
  65. "test file1.txt",
  66. "test file2.txt",
  67. "test",
  68. }},
  69. expectedError: "When using COPY with more than one source file, the destination must be a directory and end with a /",
  70. files: map[string]string{"test file1.txt": "test1", "test file2.txt": "test2"},
  71. },
  72. {
  73. name: "COPY wildcard no files",
  74. cmd: &instructions.CopyCommand{SourcesAndDest: instructions.SourcesAndDest{
  75. "file*.txt",
  76. "/tmp/",
  77. }},
  78. expectedError: "COPY failed: no source files were specified",
  79. files: nil,
  80. },
  81. {
  82. name: "COPY url",
  83. cmd: &instructions.CopyCommand{SourcesAndDest: instructions.SourcesAndDest{
  84. "https://index.docker.io/robots.txt",
  85. "/",
  86. }},
  87. expectedError: "source can't be a URL for COPY",
  88. files: nil,
  89. }}
  90. return dispatchTestCases
  91. }
  92. func TestDispatch(t *testing.T) {
  93. skip.IfCondition(t, os.Getuid() != 0, "skipping test that requires root")
  94. testCases := initDispatchTestCases()
  95. for _, testCase := range testCases {
  96. executeTestCase(t, testCase)
  97. }
  98. }
  99. func executeTestCase(t *testing.T, testCase dispatchTestCase) {
  100. contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test")
  101. defer cleanup()
  102. for filename, content := range testCase.files {
  103. createTestTempFile(t, contextDir, filename, content, 0777)
  104. }
  105. tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
  106. if err != nil {
  107. t.Fatalf("Error when creating tar stream: %s", err)
  108. }
  109. defer func() {
  110. if err = tarStream.Close(); err != nil {
  111. t.Fatalf("Error when closing tar stream: %s", err)
  112. }
  113. }()
  114. context, err := remotecontext.FromArchive(tarStream)
  115. if err != nil {
  116. t.Fatalf("Error when creating tar context: %s", err)
  117. }
  118. defer func() {
  119. if err = context.Close(); err != nil {
  120. t.Fatalf("Error when closing tar context: %s", err)
  121. }
  122. }()
  123. b := newBuilderWithMockBackend()
  124. sb := newDispatchRequest(b, '`', context, NewBuildArgs(make(map[string]*string)), newStagesBuildResults())
  125. err = dispatch(sb, testCase.cmd)
  126. assert.Check(t, is.ErrorContains(err, testCase.expectedError))
  127. }