gitee.com/mysnapcore/mysnapd@v0.1.0/cmd/snap-update-ns/sorting_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2022 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package main
    21  
    22  import (
    23  	"sort"
    24  
    25  	. "gopkg.in/check.v1"
    26  
    27  	"gitee.com/mysnapcore/mysnapd/osutil"
    28  )
    29  
    30  type sortSuite struct {
    31  	sort        func([]osutil.MountEntry)
    32  	layoutsLast bool
    33  }
    34  
    35  type byOriginAndMountPointSuite struct {
    36  	sortSuite
    37  }
    38  
    39  type byOvernameAndMountPointSuite struct {
    40  	sortSuite
    41  }
    42  
    43  var (
    44  	_ = Suite(&byOriginAndMountPointSuite{sortSuite{
    45  		sort:        func(entries []osutil.MountEntry) { sort.Sort(byOriginAndMountPoint(entries)) },
    46  		layoutsLast: true,
    47  	}})
    48  	_ = Suite(&byOvernameAndMountPointSuite{sortSuite{
    49  		sort: func(entries []osutil.MountEntry) { sort.Sort(byOvernameAndMountPoint(entries)) },
    50  	}})
    51  )
    52  
    53  func (s *sortSuite) TestTrailingSlashesComparison(c *C) {
    54  	// Naively sorted entries.
    55  	entries := []osutil.MountEntry{
    56  		{Dir: "/a/b"},
    57  		{Dir: "/a/b-1"},
    58  		{Dir: "/a/b-1/3"},
    59  		{Dir: "/a/b/c"},
    60  	}
    61  	s.sort(entries)
    62  	// Entries sorted as if they had a trailing slash.
    63  	c.Assert(entries, DeepEquals, []osutil.MountEntry{
    64  		{Dir: "/a/b-1"},
    65  		{Dir: "/a/b-1/3"},
    66  		{Dir: "/a/b"},
    67  		{Dir: "/a/b/c"},
    68  	})
    69  }
    70  
    71  func (s *sortSuite) TestParallelInstancesAndSimple(c *C) {
    72  	// Naively sorted entries.
    73  	entries := []osutil.MountEntry{
    74  		{Dir: "/a/b-1"},
    75  		{Dir: "/a/b", Options: []string{osutil.XSnapdOriginLayout()}},
    76  		{Dir: "/snap/bar/baz", Options: []string{osutil.XSnapdOriginLayout()}},
    77  		{Dir: "/snap/bar", Options: []string{osutil.XSnapdOriginOvername()}},
    78  		{Dir: "/a/b-1/3"},
    79  		{Dir: "/var/snap/bar", Options: []string{osutil.XSnapdOriginOvername()}},
    80  		{Dir: "/a/b/c"},
    81  	}
    82  	s.sort(entries)
    83  	// Entries sorted as if they had a trailing slash.
    84  	expected := []osutil.MountEntry{
    85  		{Dir: "/snap/bar", Options: []string{osutil.XSnapdOriginOvername()}},
    86  		{Dir: "/var/snap/bar", Options: []string{osutil.XSnapdOriginOvername()}},
    87  		{Dir: "/a/b-1"},
    88  		{Dir: "/a/b-1/3"},
    89  	}
    90  	if s.layoutsLast {
    91  		expected = append(expected, []osutil.MountEntry{
    92  			// implicit content before layouts
    93  			{Dir: "/a/b/c"},
    94  			// layouts
    95  			{Dir: "/a/b", Options: []string{osutil.XSnapdOriginLayout()}},
    96  			{Dir: "/snap/bar/baz", Options: []string{osutil.XSnapdOriginLayout()}},
    97  		}...)
    98  	} else {
    99  		expected = append(expected, []osutil.MountEntry{
   100  			// just lexicographic
   101  			{Dir: "/a/b", Options: []string{osutil.XSnapdOriginLayout()}},
   102  			{Dir: "/a/b/c"},
   103  			{Dir: "/snap/bar/baz", Options: []string{osutil.XSnapdOriginLayout()}},
   104  		}...)
   105  
   106  	}
   107  	c.Assert(entries, DeepEquals, expected)
   108  }
   109  
   110  func (s *sortSuite) TestOvernameOrder(c *C) {
   111  	expected := []osutil.MountEntry{
   112  		{Dir: "/a/b/2", Options: []string{osutil.XSnapdOriginOvername()}},
   113  		{Dir: "/a/b"},
   114  	}
   115  	entries := []osutil.MountEntry{
   116  		{Dir: "/a/b"},
   117  		{Dir: "/a/b/2", Options: []string{osutil.XSnapdOriginOvername()}},
   118  	}
   119  	entriesRev := []osutil.MountEntry{
   120  		{Dir: "/a/b/2", Options: []string{osutil.XSnapdOriginOvername()}},
   121  		{Dir: "/a/b"},
   122  	}
   123  	s.sort(entries)
   124  	c.Assert(entries, DeepEquals, expected)
   125  	s.sort(entriesRev)
   126  	c.Assert(entriesRev, DeepEquals, expected)
   127  }
   128  
   129  func (s *sortSuite) TestParallelInstancesAlmostSorted(c *C) {
   130  	// use a mount profile that was seen to be broken in the wild
   131  	entries := []osutil.MountEntry{
   132  		{Dir: "/snap/foo", Options: []string{osutil.XSnapdOriginOvername()}},
   133  		{Dir: "/var/snap/foo", Options: []string{osutil.XSnapdOriginOvername()}},
   134  		{Dir: "/snap/foo/44/foo/certs", Options: []string{osutil.XSnapdOriginLayout()}},
   135  		{Dir: "/snap/foo/44/foo/config", Options: []string{osutil.XSnapdOriginLayout()}},
   136  		{Dir: "/snap/foo/44/usr/bin/python", Options: []string{osutil.XSnapdOriginLayout()}},
   137  		{Dir: "/snap/foo/44/usr/bin/python3", Options: []string{osutil.XSnapdOriginLayout()}},
   138  		{Dir: "/usr/bin/java", Options: []string{osutil.XSnapdOriginLayout()}},
   139  		{Dir: "/usr/bin/java8", Options: []string{osutil.XSnapdOriginLayout()}},
   140  		{Dir: "/usr/bin/node", Options: []string{osutil.XSnapdOriginLayout()}},
   141  		{Dir: "/usr/bin/nodejs12x", Options: []string{osutil.XSnapdOriginLayout()}},
   142  		{Dir: "/usr/bin/python2.7", Options: []string{osutil.XSnapdOriginLayout()}},
   143  		{Dir: "/usr/bin/python3.7", Options: []string{osutil.XSnapdOriginLayout()}},
   144  		{Dir: "/usr/bin/python3.8", Options: []string{osutil.XSnapdOriginLayout()}},
   145  	}
   146  	s.sort(entries)
   147  	// overname entries are always first
   148  	c.Assert(entries, DeepEquals, []osutil.MountEntry{
   149  		{Dir: "/snap/foo", Options: []string{osutil.XSnapdOriginOvername()}},
   150  		{Dir: "/var/snap/foo", Options: []string{osutil.XSnapdOriginOvername()}},
   151  		{Dir: "/snap/foo/44/foo/certs", Options: []string{osutil.XSnapdOriginLayout()}},
   152  		{Dir: "/snap/foo/44/foo/config", Options: []string{osutil.XSnapdOriginLayout()}},
   153  		{Dir: "/snap/foo/44/usr/bin/python", Options: []string{osutil.XSnapdOriginLayout()}},
   154  		{Dir: "/snap/foo/44/usr/bin/python3", Options: []string{osutil.XSnapdOriginLayout()}},
   155  		{Dir: "/usr/bin/java", Options: []string{osutil.XSnapdOriginLayout()}},
   156  		{Dir: "/usr/bin/java8", Options: []string{osutil.XSnapdOriginLayout()}},
   157  		{Dir: "/usr/bin/node", Options: []string{osutil.XSnapdOriginLayout()}},
   158  		{Dir: "/usr/bin/nodejs12x", Options: []string{osutil.XSnapdOriginLayout()}},
   159  		{Dir: "/usr/bin/python2.7", Options: []string{osutil.XSnapdOriginLayout()}},
   160  		{Dir: "/usr/bin/python3.7", Options: []string{osutil.XSnapdOriginLayout()}},
   161  		{Dir: "/usr/bin/python3.8", Options: []string{osutil.XSnapdOriginLayout()}},
   162  	})
   163  }