evaluator_test.go 4.1 KB

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