github.com/rawahars/moby@v24.0.4+incompatible/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 TestMain(m *testing.M) { 25 if reexec.Init() { 26 return 27 } 28 os.Exit(m.Run()) 29 } 30 31 func TestDispatch(t *testing.T) { 32 if runtime.GOOS != "windows" { 33 skip.If(t, os.Getuid() != 0, "skipping test that requires root") 34 } 35 testCases := []dispatchTestCase{ 36 { 37 name: "ADD multiple files to file", 38 cmd: &instructions.AddCommand{SourcesAndDest: instructions.SourcesAndDest{ 39 SourcePaths: []string{"file1.txt", "file2.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: "Wildcard ADD multiple files to file", 47 cmd: &instructions.AddCommand{SourcesAndDest: instructions.SourcesAndDest{ 48 SourcePaths: []string{"file*.txt"}, 49 DestPath: "test", 50 }}, 51 expectedError: "When using ADD 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: "COPY multiple files to file", 56 cmd: &instructions.CopyCommand{SourcesAndDest: instructions.SourcesAndDest{ 57 SourcePaths: []string{"file1.txt", "file2.txt"}, 58 DestPath: "test", 59 }}, 60 expectedError: "When using COPY with more than one source file, the destination must be a directory and end with a /", 61 files: map[string]string{"file1.txt": "test1", "file2.txt": "test2"}, 62 }, 63 { 64 name: "ADD multiple files to file with whitespace", 65 cmd: &instructions.AddCommand{SourcesAndDest: instructions.SourcesAndDest{ 66 SourcePaths: []string{"test file1.txt", "test file2.txt"}, 67 DestPath: "test", 68 }}, 69 expectedError: "When using ADD 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 multiple files to file with whitespace", 74 cmd: &instructions.CopyCommand{SourcesAndDest: instructions.SourcesAndDest{ 75 SourcePaths: []string{"test file1.txt", "test file2.txt"}, 76 DestPath: "test", 77 }}, 78 expectedError: "When using COPY with more than one source file, the destination must be a directory and end with a /", 79 files: map[string]string{"test file1.txt": "test1", "test file2.txt": "test2"}, 80 }, 81 { 82 name: "COPY wildcard no files", 83 cmd: &instructions.CopyCommand{SourcesAndDest: instructions.SourcesAndDest{ 84 SourcePaths: []string{"file*.txt"}, 85 DestPath: "/tmp/", 86 }}, 87 expectedError: "COPY failed: no source files were specified", 88 files: nil, 89 }, 90 { 91 name: "COPY url", 92 cmd: &instructions.CopyCommand{SourcesAndDest: instructions.SourcesAndDest{ 93 SourcePaths: []string{"https://example.com/index.html"}, 94 DestPath: "/", 95 }}, 96 expectedError: "source can't be a URL for COPY", 97 files: nil, 98 }, 99 } 100 101 for _, tc := range testCases { 102 t.Run(tc.name, func(t *testing.T) { 103 contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test") 104 defer cleanup() 105 106 for filename, content := range tc.files { 107 createTestTempFile(t, contextDir, filename, content, 0777) 108 } 109 110 tarStream, err := archive.Tar(contextDir, archive.Uncompressed) 111 112 if err != nil { 113 t.Fatalf("Error when creating tar stream: %s", err) 114 } 115 116 defer func() { 117 if err = tarStream.Close(); err != nil { 118 t.Fatalf("Error when closing tar stream: %s", err) 119 } 120 }() 121 122 buildContext, err := remotecontext.FromArchive(tarStream) 123 124 if err != nil { 125 t.Fatalf("Error when creating tar context: %s", err) 126 } 127 128 defer func() { 129 if err = buildContext.Close(); err != nil { 130 t.Fatalf("Error when closing tar context: %s", err) 131 } 132 }() 133 134 b := newBuilderWithMockBackend(t) 135 sb := newDispatchRequest(b, '`', buildContext, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) 136 err = dispatch(context.TODO(), sb, tc.cmd) 137 assert.Check(t, is.ErrorContains(err, tc.expectedError)) 138 }) 139 } 140 }