util.SortMounts(): make the returned order more stable

Use sort.Stable() instead of sort.Sort() to sort mounts, and have the
comparison function compare the cleaned paths directly if they have the
same number of components, so that there's a defined ordering between
"/a" and "/b".

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
Nalin Dahyabhai 2022-11-30 15:27:57 -05:00
parent cf661299d1
commit 025a8df513
2 changed files with 22 additions and 39 deletions

View File

@ -441,7 +441,14 @@ func (m byDestination) Len() int {
}
func (m byDestination) Less(i, j int) bool {
return m.parts(i) < m.parts(j)
iparts, jparts := m.parts(i), m.parts(j)
switch {
case iparts < jparts:
return true
case iparts > jparts:
return false
}
return filepath.Clean(m[i].Destination) < filepath.Clean(m[j].Destination)
}
func (m byDestination) Swap(i, j int) {
@ -453,7 +460,7 @@ func (m byDestination) parts(i int) int {
}
func SortMounts(m []specs.Mount) []specs.Mount {
sort.Sort(byDestination(m))
sort.Stable(byDestination(m))
return m
}

View File

@ -7,6 +7,7 @@ import (
"github.com/containers/common/pkg/config"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
)
func TestMergeEnv(t *testing.T) {
@ -93,45 +94,20 @@ func TestMountsSort(t *testing.T) {
Destination: "/aa/b/c",
},
}
mounts1b := []specs.Mount{
{
Source: "/xyz",
Destination: "/",
},
{
Source: "/a",
Destination: "/a",
},
{
Source: "/b",
Destination: "/b",
},
{
Source: "/a/b",
Destination: "/a/b",
},
{
Source: "/d/e",
Destination: "/a/c",
},
{
Source: "/a/b/c",
Destination: "/a/b/c",
},
{
Source: "/a/bb/c",
Destination: "/a/bb/c",
},
{
Source: "/a/b/c",
Destination: "/aa/b/c",
},
mounts1b := []string{
"/",
"/a",
"/b",
"/a/b",
"/a/c",
"/a/b/c",
"/a/bb/c",
"/aa/b/c",
}
sorted := SortMounts(mounts1a)
sortedDests := make([]string, len(mounts1a))
for i := range sorted {
if sorted[i].Destination != mounts1b[i].Destination {
t.Fatalf("failed sort \n%+v\n%+v", mounts1b, sorted)
sortedDests[i] = sorted[i].Destination
}
}
assert.Equalf(t, mounts1b, sortedDests, "sort returned results in unexpected by-destination order")
}