10
"github.com/containers/storage/pkg/idtools"
11
stypes "github.com/containers/storage/types"
12
ruser "github.com/moby/sys/user"
13
"github.com/opencontainers/runtime-spec/specs-go"
14
"github.com/stretchr/testify/assert"
17
func BreakInsert(mapping []idtools.IDMap, extension idtools.IDMap) (result []idtools.IDMap) {
18
result = breakInsert(mapping, extension)
19
result = sortAndMergeConsecutiveMappings(result)
25
func TestBreakInsert1(t *testing.T) {
27
mapping := []idtools.IDMap{
34
extension := idtools.IDMap{
39
expectedResult := []idtools.IDMap{
51
result := BreakInsert(mapping, extension)
52
assert.Equal(t, result, expectedResult)
55
func TestBreakInsert2(t *testing.T) {
57
mapping := []idtools.IDMap{
64
extension := idtools.IDMap{
69
expectedResult := []idtools.IDMap{
81
result := BreakInsert(mapping, extension)
82
assert.Equal(t, expectedResult, result)
85
func TestBreakInsert3(t *testing.T) {
87
mapping := []idtools.IDMap{
94
extension := idtools.IDMap{
99
expectedResult := []idtools.IDMap{
111
result := BreakInsert(mapping, extension)
112
assert.Equal(t, expectedResult, result)
115
func TestBreakInsert4(t *testing.T) {
117
mapping := []idtools.IDMap{
124
extension := idtools.IDMap{
129
expectedResult := []idtools.IDMap{
141
result := BreakInsert(mapping, extension)
142
assert.Equal(t, expectedResult, result)
145
func TestSortAndMergeConsecutiveMappings(t *testing.T) {
147
mapping := []idtools.IDMap{
159
expectedResult := []idtools.IDMap{
166
result := sortAndMergeConsecutiveMappings(mapping)
167
assert.Equal(t, expectedResult, result)
172
func TestParseIDMap(t *testing.T) {
173
mapSpec := []string{"+100000:@1002:1"}
175
parentMapping := []ruser.IDMap{
178
ParentID: int64(1002),
182
expectedResult := []idtools.IDMap{
189
result, err := ParseIDMap(
194
assert.Equal(t, nil, err)
195
assert.Equal(t, expectedResult, result)
198
func TestParseIDMapSizeMissing(t *testing.T) {
200
mapSpec := []string{"+100000:@1002"}
202
parentMapping := []ruser.IDMap{
205
ParentID: int64(1002),
209
expectedResult := []idtools.IDMap{
216
result, err := ParseIDMap(
221
assert.Equal(t, nil, err)
222
assert.Equal(t, expectedResult, result)
225
func TestParseIDMap2(t *testing.T) {
226
mapSpec := []string{"0:2000:100000", "+1:100:1"}
227
parentMapping := []ruser.IDMap(nil)
228
expectedResult := []idtools.IDMap{
245
result, err := ParseIDMap(
250
assert.Equal(t, nil, err)
251
assert.Equal(t, expectedResult, result)
254
func TestParseIDMap3(t *testing.T) {
255
mapSpec := []string{"0:0:20", "24:24:6", "+7:1000:2", "+12:2000:3", "+18:3000:7"}
256
parentMapping := []ruser.IDMap(nil)
257
expectedResult := []idtools.IDMap{
294
result, err := ParseIDMap(
299
assert.Equal(t, nil, err)
300
assert.Equal(t, expectedResult, result)
303
func TestParseIDMap4(t *testing.T) {
304
mapSpec := []string{"0:0:20", "+10:1:1"}
305
parentMapping := []ruser.IDMap(nil)
306
expectedResult := []idtools.IDMap{
328
result, err := ParseIDMap(
333
assert.Equal(t, nil, err)
334
assert.Equal(t, expectedResult, result)
337
func TestParseIDMap5(t *testing.T) {
338
mapSpec := []string{"0:20:10", "15:35:10", "+8:23:16"}
339
parentMapping := []ruser.IDMap(nil)
340
expectedResult := []idtools.IDMap{
357
result, err := ParseIDMap(
362
assert.Equal(t, nil, err)
363
assert.Equal(t, expectedResult, result)
366
func TestParseIDMapUserGroupFlags(t *testing.T) {
367
mapSpec := []string{"u1:3:1", "g2:4:2"}
368
parentMapping := []ruser.IDMap(nil)
369
expectedResultUser := []idtools.IDMap{
376
expectedResultGroup := []idtools.IDMap{
383
result, err := ParseIDMap(mapSpec, "UID", parentMapping)
384
assert.Equal(t, nil, err)
385
assert.Equal(t, expectedResultUser, result)
386
result, err = ParseIDMap(mapSpec, "GID", parentMapping)
387
assert.Equal(t, err, nil)
388
assert.Equal(t, expectedResultGroup, result)
391
func TestParseAutoIDMap(t *testing.T) {
392
result, err := parseAutoIDMap("3:4:5", "UID", []ruser.IDMap{})
393
assert.Equal(t, err, nil)
394
assert.Equal(t, result, []idtools.IDMap{
403
func TestParseAutoIDMapRelative(t *testing.T) {
404
parentMapping := []ruser.IDMap{
416
result, err := parseAutoIDMap("100:@100000:1", "UID", parentMapping)
417
assert.Equal(t, err, nil)
418
assert.Equal(t, result, []idtools.IDMap{
427
func TestFillIDMap(t *testing.T) {
428
availableRanges := [][2]int{{0, 10}, {10000, 20000}}
429
idmap := []idtools.IDMap{
441
expectedResult := []idtools.IDMap{
473
result := fillIDMap(idmap, availableRanges)
474
assert.Equal(t, expectedResult, result)
477
func TestGetAvailableIDRanges(t *testing.T) {
478
all := [][2]int{{0, 30}, {50, 70}}
479
used := [][2]int{{2, 4}, {25, 55}}
480
expectedResult := [][2]int{{0, 2}, {4, 25}, {55, 70}}
481
result := getAvailableIDRanges(all, used)
482
assert.Equal(t, expectedResult, result)
485
func TestValidateSysctls(t *testing.T) {
486
strSlice := []string{"net.core.test1=4", "kernel.msgmax=2"}
487
result, _ := ValidateSysctls(strSlice)
488
assert.Equal(t, result["net.core.test1"], "4")
491
func TestValidateSysctlBadSysctl(t *testing.T) {
492
strSlice := []string{"BLAU=BLUE", "GELB^YELLOW"}
493
_, err := ValidateSysctls(strSlice)
497
func TestValidateSysctlBadSysctlWithExtraSpaces(t *testing.T) {
498
expectedError := "'%s' is invalid, extra spaces found"
501
strSlice1 := []string{
502
"net.ipv4.ping_group_range = 0 0",
503
"net.ipv4.ping_group_range=0 0 ",
505
_, err := ValidateSysctls(strSlice1)
507
assert.Equal(t, err.Error(), fmt.Sprintf(expectedError, strSlice1[0]))
510
strSlice2 := []string{
511
"net.ipv4.ping_group_range=0 0",
512
"net.ipv4.ping_group_range=0 0 ",
514
_, err = ValidateSysctls(strSlice2)
516
assert.Equal(t, err.Error(), fmt.Sprintf(expectedError, strSlice2[1]))
519
func TestCoresToPeriodAndQuota(t *testing.T) {
521
expectedPeriod := DefaultCPUPeriod
522
expectedQuota := int64(DefaultCPUPeriod)
524
actualPeriod, actualQuota := CoresToPeriodAndQuota(cores)
525
assert.Equal(t, actualPeriod, expectedPeriod, "Period does not match")
526
assert.Equal(t, actualQuota, expectedQuota, "Quota does not match")
529
func TestPeriodAndQuotaToCores(t *testing.T) {
531
period uint64 = 100000
536
assert.Equal(t, PeriodAndQuotaToCores(period, quota), expectedCores)
539
func TestParseInputTime(t *testing.T) {
540
tm, err := ParseInputTime("1.5", true)
542
t.Errorf("expected error to be nil but was: %v", err)
545
expected, err := time.ParseInLocation(time.RFC3339Nano, "1970-01-01T00:00:01.500000000Z", time.UTC)
550
assert.Equal(t, expected, tm)
553
func TestConvertMappings(t *testing.T) {
554
start := []specs.LinuxIDMapping{
567
converted := RuntimeSpecToIDtools(start)
569
convertedBack := IDtoolsToRuntimeSpec(converted)
571
assert.Equal(t, len(start), len(convertedBack))
573
for i := range start {
574
assert.Equal(t, start[i].ContainerID, convertedBack[i].ContainerID)
575
assert.Equal(t, start[i].HostID, convertedBack[i].HostID)
576
assert.Equal(t, start[i].Size, convertedBack[i].Size)
580
func TestConvertTimeout(t *testing.T) {
581
timeout := ConvertTimeout(0)
582
assert.Equal(t, uint(0), timeout)
584
timeout = ConvertTimeout(100)
585
assert.Equal(t, uint(100), timeout)
587
timeout = ConvertTimeout(-1)
588
assert.Equal(t, uint(math.MaxUint32), timeout)
590
timeout = ConvertTimeout(-100)
591
assert.Equal(t, uint(math.MaxUint32), timeout)
594
func TestGetRootlessKeepIDMapping(t *testing.T) {
597
uids, gids []idtools.IDMap
598
expectedOptions *stypes.IDMappingOptions
599
expectedUID, expectedGID int
605
uids: []idtools.IDMap{},
606
gids: []idtools.IDMap{},
607
expectedOptions: &stypes.IDMappingOptions{
608
HostUIDMapping: false,
609
HostGIDMapping: false,
610
UIDMap: []idtools.IDMap{{ContainerID: 1000, HostID: 0, Size: 1}},
611
GIDMap: []idtools.IDMap{{ContainerID: 1000, HostID: 0, Size: 1}},
619
uids: []idtools.IDMap{{ContainerID: 0, HostID: 100000, Size: 65536}},
620
gids: []idtools.IDMap{{ContainerID: 0, HostID: 100000, Size: 65536}},
621
expectedOptions: &stypes.IDMappingOptions{
622
HostUIDMapping: false,
623
HostGIDMapping: false,
624
UIDMap: []idtools.IDMap{{ContainerID: 0, HostID: 0, Size: 1}, {ContainerID: 1, HostID: 1, Size: 65536}},
625
GIDMap: []idtools.IDMap{{ContainerID: 0, HostID: 0, Size: 1}, {ContainerID: 1, HostID: 1, Size: 65536}},
632
for _, test := range tests {
633
options, uid, gid, err := getRootlessKeepIDMapping(test.uid, test.gid, test.uids, test.gids)
635
assert.Equal(t, test.expectedOptions, options)
636
assert.Equal(t, test.expectedUID, uid)
637
assert.Equal(t, test.expectedGID, gid)
641
func getDefaultMountOptionsNoStat(path string) (defaultMountOptions, error) {
642
return defaultMountOptions{false, true, true}, nil
645
func TestProcessOptions(t *testing.T) {
656
options: []string{"rw", "size=512m"},
659
expected: []string{"nodev", "nosuid", "rprivate", "rw", "size=512m", "tmpcopyup"},
662
name: "duplicate idmap option",
663
sourcePath: "/path/to/source",
664
options: []string{"idmap", "idmap"},
668
name: "mode allowed only with tmpfs",
669
sourcePath: "/path/to/source",
670
options: []string{"rw", "rbind", "mode=0123"},
674
name: "noswap allowed only with tmpfs",
675
sourcePath: "/path/to/source",
676
options: []string{"noswap"},
680
name: "tmpcopyup allowed only with tmpfs",
681
sourcePath: "/path/to/source",
682
options: []string{"tmpcopyup"},
686
name: "notmpcopyup allowed only with tmpfs",
687
sourcePath: "/path/to/source",
688
options: []string{"notmpcopyup"},
692
name: "z not allowed with tmpfs",
694
sourcePath: "/path/to/source",
695
options: []string{"z"},
699
name: "size allowed only with tmpfs",
700
sourcePath: "/path/to/source",
701
options: []string{"size=123456"},
705
name: "conflicting option dev/nodev",
706
sourcePath: "/path/to/source",
707
options: []string{"dev", "nodev"},
711
name: "conflicting option suid/nosuid",
712
sourcePath: "/path/to/source",
713
options: []string{"suid", "nosuid"},
717
name: "conflicting option exec/noexec",
718
sourcePath: "/path/to/source",
719
options: []string{"noexec", "exec"},
723
name: "conflicting option ro/rw",
724
sourcePath: "/path/to/source",
725
options: []string{"ro", "rw"},
729
name: "conflicting option bind/rbind",
730
sourcePath: "/path/to/source",
731
options: []string{"bind", "rbind"},
735
name: "conflicting option bind/rbind",
736
sourcePath: "/path/to/source",
737
options: []string{"bind", "rbind"},
741
name: "default bind mount",
742
sourcePath: "/path/to/source",
743
expected: []string{"nodev", "nosuid", "rbind", "rprivate", "rw"},
746
name: "default bind mount with bind",
747
sourcePath: "/path/to/source",
748
options: []string{"bind"},
749
expected: []string{"nodev", "nosuid", "bind", "private", "rw"},
753
for _, tt := range tests {
754
t.Run(tt.name, func(t *testing.T) {
755
opts, err := processOptionsInternal(tt.options, tt.isTmpfs, tt.sourcePath, getDefaultMountOptionsNoStat)
757
assert.NotNil(t, err)
761
sort.Strings(tt.expected)
762
assert.Equal(t, opts, tt.expected)