builder/dockerfile/internals_linux_test.go
d1c34831
 package dockerfile
 
 import (
 	"os"
 	"path/filepath"
 	"testing"
 
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 func TestChownFlagParsing(t *testing.T) {
 	testFiles := map[string]string{
 		"passwd": `root:x:0:0::/bin:/bin/false
 bin:x:1:1::/bin:/bin/false
 wwwwww:x:21:33::/bin:/bin/false
 unicorn:x:1001:1002::/bin:/bin/false
 		`,
 		"group": `root:x:0:
 bin:x:1:
 wwwwww:x:33:
 unicorn:x:1002:
 somegrp:x:5555:
 othergrp:x:6666:
 		`,
 	}
 	// test mappings for validating use of maps
 	idMaps := []idtools.IDMap{
 		{
 			ContainerID: 0,
 			HostID:      100000,
 			Size:        65536,
 		},
 	}
 	remapped := idtools.NewIDMappingsFromMaps(idMaps, idMaps)
 	unmapped := &idtools.IDMappings{}
 
 	contextDir, cleanup := createTestTempDir(t, "", "builder-chown-parse-test")
 	defer cleanup()
 
 	if err := os.Mkdir(filepath.Join(contextDir, "etc"), 0755); err != nil {
 		t.Fatalf("error creating test directory: %v", err)
 	}
 
 	for filename, content := range testFiles {
 		createTestTempFile(t, filepath.Join(contextDir, "etc"), filename, content, 0644)
 	}
 
 	// positive tests
 	for _, testcase := range []struct {
 		name      string
 		chownStr  string
 		idMapping *idtools.IDMappings
 		expected  idtools.IDPair
 	}{
 		{
 			name:      "UIDNoMap",
 			chownStr:  "1",
 			idMapping: unmapped,
 			expected:  idtools.IDPair{UID: 1, GID: 1},
 		},
 		{
 			name:      "UIDGIDNoMap",
 			chownStr:  "0:1",
 			idMapping: unmapped,
 			expected:  idtools.IDPair{UID: 0, GID: 1},
 		},
 		{
 			name:      "UIDWithMap",
 			chownStr:  "0",
 			idMapping: remapped,
 			expected:  idtools.IDPair{UID: 100000, GID: 100000},
 		},
 		{
 			name:      "UIDGIDWithMap",
 			chownStr:  "1:33",
 			idMapping: remapped,
 			expected:  idtools.IDPair{UID: 100001, GID: 100033},
 		},
 		{
 			name:      "UserNoMap",
 			chownStr:  "bin:5555",
 			idMapping: unmapped,
 			expected:  idtools.IDPair{UID: 1, GID: 5555},
 		},
 		{
 			name:      "GroupWithMap",
 			chownStr:  "0:unicorn",
 			idMapping: remapped,
 			expected:  idtools.IDPair{UID: 100000, GID: 101002},
 		},
 		{
 			name:      "UserOnlyWithMap",
 			chownStr:  "unicorn",
 			idMapping: remapped,
 			expected:  idtools.IDPair{UID: 101001, GID: 101002},
 		},
 	} {
 		t.Run(testcase.name, func(t *testing.T) {
 			idPair, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping)
 			require.NoError(t, err, "Failed to parse chown flag: %q", testcase.chownStr)
 			assert.Equal(t, testcase.expected, idPair, "chown flag mapping failure")
 		})
 	}
 
 	// error tests
 	for _, testcase := range []struct {
 		name      string
 		chownStr  string
 		idMapping *idtools.IDMappings
 		descr     string
 	}{
 		{
 			name:      "BadChownFlagFormat",
 			chownStr:  "bob:1:555",
 			idMapping: unmapped,
 			descr:     "invalid chown string format: bob:1:555",
 		},
 		{
 			name:      "UserNoExist",
 			chownStr:  "bob",
 			idMapping: unmapped,
 			descr:     "can't find uid for user bob: no such user: bob",
 		},
 		{
 			name:      "GroupNoExist",
 			chownStr:  "root:bob",
 			idMapping: unmapped,
 			descr:     "can't find gid for group bob: no such group: bob",
 		},
 	} {
 		t.Run(testcase.name, func(t *testing.T) {
 			_, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping)
 			assert.EqualError(t, err, testcase.descr, "Expected error string doesn't match")
 		})
 	}
 }