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