evaluator_test.go 4.3 KB

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