github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/builder/dockerfile/internals_linux_test.go (about) 1 package dockerfile // import "github.com/Prakhar-Agarwal-byte/moby/builder/dockerfile" 2 3 import ( 4 "context" 5 "os" 6 "path/filepath" 7 "testing" 8 9 "github.com/Prakhar-Agarwal-byte/moby/api/types" 10 "github.com/Prakhar-Agarwal-byte/moby/pkg/idtools" 11 "gotest.tools/v3/assert" 12 is "gotest.tools/v3/assert/cmp" 13 ) 14 15 func TestChownFlagParsing(t *testing.T) { 16 testFiles := map[string]string{ 17 "passwd": `root:x:0:0::/bin:/bin/false 18 bin:x:1:1::/bin:/bin/false 19 wwwwww:x:21:33::/bin:/bin/false 20 unicorn:x:1001:1002::/bin:/bin/false 21 `, 22 "group": `root:x:0: 23 bin:x:1: 24 wwwwww:x:33: 25 unicorn:x:1002: 26 somegrp:x:5555: 27 othergrp:x:6666: 28 `, 29 } 30 // test mappings for validating use of maps 31 idMaps := []idtools.IDMap{ 32 { 33 ContainerID: 0, 34 HostID: 100000, 35 Size: 65536, 36 }, 37 } 38 remapped := idtools.IdentityMapping{UIDMaps: idMaps, GIDMaps: idMaps} 39 unmapped := idtools.IdentityMapping{} 40 41 contextDir, cleanup := createTestTempDir(t, "", "builder-chown-parse-test") 42 defer cleanup() 43 44 if err := os.Mkdir(filepath.Join(contextDir, "etc"), 0o755); err != nil { 45 t.Fatalf("error creating test directory: %v", err) 46 } 47 48 for filename, content := range testFiles { 49 createTestTempFile(t, filepath.Join(contextDir, "etc"), filename, content, 0o644) 50 } 51 52 // positive tests 53 for _, testcase := range []struct { 54 builder *Builder 55 name string 56 chownStr string 57 idMapping idtools.IdentityMapping 58 state *dispatchState 59 expected idtools.Identity 60 }{ 61 { 62 builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}}, 63 name: "UIDNoMap", 64 chownStr: "1", 65 idMapping: unmapped, 66 state: &dispatchState{}, 67 expected: idtools.Identity{UID: 1, GID: 1}, 68 }, 69 { 70 builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}}, 71 name: "UIDGIDNoMap", 72 chownStr: "0:1", 73 idMapping: unmapped, 74 state: &dispatchState{}, 75 expected: idtools.Identity{UID: 0, GID: 1}, 76 }, 77 { 78 builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}}, 79 name: "UIDWithMap", 80 chownStr: "0", 81 idMapping: remapped, 82 state: &dispatchState{}, 83 expected: idtools.Identity{UID: 100000, GID: 100000}, 84 }, 85 { 86 builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}}, 87 name: "UIDGIDWithMap", 88 chownStr: "1:33", 89 idMapping: remapped, 90 state: &dispatchState{}, 91 expected: idtools.Identity{UID: 100001, GID: 100033}, 92 }, 93 { 94 builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}}, 95 name: "UserNoMap", 96 chownStr: "bin:5555", 97 idMapping: unmapped, 98 state: &dispatchState{}, 99 expected: idtools.Identity{UID: 1, GID: 5555}, 100 }, 101 { 102 builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}}, 103 name: "GroupWithMap", 104 chownStr: "0:unicorn", 105 idMapping: remapped, 106 state: &dispatchState{}, 107 expected: idtools.Identity{UID: 100000, GID: 101002}, 108 }, 109 { 110 builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}}, 111 name: "UserOnlyWithMap", 112 chownStr: "unicorn", 113 idMapping: remapped, 114 state: &dispatchState{}, 115 expected: idtools.Identity{UID: 101001, GID: 101002}, 116 }, 117 } { 118 t.Run(testcase.name, func(t *testing.T) { 119 idPair, err := parseChownFlag(context.TODO(), testcase.builder, testcase.state, testcase.chownStr, contextDir, testcase.idMapping) 120 assert.NilError(t, err, "Failed to parse chown flag: %q", testcase.chownStr) 121 assert.Check(t, is.DeepEqual(testcase.expected, idPair), "chown flag mapping failure") 122 }) 123 } 124 125 // error tests 126 for _, testcase := range []struct { 127 builder *Builder 128 name string 129 chownStr string 130 idMapping idtools.IdentityMapping 131 state *dispatchState 132 descr string 133 }{ 134 { 135 builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}}, 136 name: "BadChownFlagFormat", 137 chownStr: "bob:1:555", 138 idMapping: unmapped, 139 state: &dispatchState{}, 140 descr: "invalid chown string format: bob:1:555", 141 }, 142 { 143 builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}}, 144 name: "UserNoExist", 145 chownStr: "bob", 146 idMapping: unmapped, 147 state: &dispatchState{}, 148 descr: "can't find uid for user bob: no such user: bob", 149 }, 150 { 151 builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}}, 152 name: "GroupNoExist", 153 chownStr: "root:bob", 154 idMapping: unmapped, 155 state: &dispatchState{}, 156 descr: "can't find gid for group bob: no such group: bob", 157 }, 158 } { 159 t.Run(testcase.name, func(t *testing.T) { 160 _, err := parseChownFlag(context.TODO(), testcase.builder, testcase.state, testcase.chownStr, contextDir, testcase.idMapping) 161 assert.Check(t, is.Error(err, testcase.descr), "Expected error string doesn't match") 162 }) 163 } 164 }