evaluator_test.go 4.4 KB

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