evaluator_test.go 4.3 KB

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