github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/builder/dockerfile/evaluator_test.go (about) 1 package dockerfile // import "github.com/Prakhar-Agarwal-byte/moby/builder/dockerfile" 2 3 import ( 4 "context" 5 "os" 6 "runtime" 7 "testing" 8 9 "github.com/Prakhar-Agarwal-byte/moby/builder/remotecontext" 10 "github.com/Prakhar-Agarwal-byte/moby/pkg/archive" 11 "github.com/Prakhar-Agarwal-byte/moby/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, 0o777) 108 } 109 110 tarStream, err := archive.Tar(contextDir, archive.Uncompressed) 111 if err != nil { 112 t.Fatalf("Error when creating tar stream: %s", err) 113 } 114 115 defer func() { 116 if err = tarStream.Close(); err != nil { 117 t.Fatalf("Error when closing tar stream: %s", err) 118 } 119 }() 120 121 buildContext, err := remotecontext.FromArchive(tarStream) 122 if err != nil { 123 t.Fatalf("Error when creating tar context: %s", err) 124 } 125 126 defer func() { 127 if err = buildContext.Close(); err != nil { 128 t.Fatalf("Error when closing tar context: %s", err) 129 } 130 }() 131 132 b := newBuilderWithMockBackend(t) 133 sb := newDispatchRequest(b, '`', buildContext, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) 134 err = dispatch(context.TODO(), sb, tc.cmd) 135 assert.Check(t, is.ErrorContains(err, tc.expectedError)) 136 }) 137 } 138 }