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