github.com/Lephar/snapd@v0.0.0-20210825215435-c7fba9cef4d2/snap/snapdir/snapdir_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2014-2015 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 snapdir_test
    21  
    22  import (
    23  	"fmt"
    24  	"io/ioutil"
    25  	"math/rand"
    26  	"os"
    27  	"path/filepath"
    28  	"testing"
    29  	"time"
    30  
    31  	. "gopkg.in/check.v1"
    32  
    33  	"github.com/snapcore/snapd/osutil"
    34  	"github.com/snapcore/snapd/snap"
    35  	"github.com/snapcore/snapd/snap/snapdir"
    36  )
    37  
    38  // Hook up check.v1 into the "go test" runner
    39  func Test(t *testing.T) { TestingT(t) }
    40  
    41  type SnapdirTestSuite struct {
    42  }
    43  
    44  var _ = Suite(&SnapdirTestSuite{})
    45  
    46  func (s *SnapdirTestSuite) TestIsSnapDir(c *C) {
    47  	d := c.MkDir()
    48  	err := os.MkdirAll(filepath.Join(d, "meta"), 0755)
    49  	c.Assert(err, IsNil)
    50  	err = ioutil.WriteFile(filepath.Join(d, "meta/snap.yaml"), nil, 0644)
    51  	c.Assert(err, IsNil)
    52  
    53  	c.Check(snapdir.IsSnapDir(d), Equals, true)
    54  }
    55  
    56  func (s *SnapdirTestSuite) TestNotIsSnapDir(c *C) {
    57  	c.Check(snapdir.IsSnapDir("/not-existent"), Equals, false)
    58  	c.Check(snapdir.IsSnapDir("/dev/null"), Equals, false)
    59  	c.Check(snapdir.IsSnapDir(c.MkDir()), Equals, false)
    60  }
    61  
    62  func (s *SnapdirTestSuite) TestReadFile(c *C) {
    63  	d := c.MkDir()
    64  	needle := []byte(`stuff`)
    65  	err := ioutil.WriteFile(filepath.Join(d, "foo"), needle, 0644)
    66  	c.Assert(err, IsNil)
    67  
    68  	sn := snapdir.New(d)
    69  	content, err := sn.ReadFile("foo")
    70  	c.Assert(err, IsNil)
    71  	c.Assert(content, DeepEquals, needle)
    72  }
    73  
    74  func (s *SnapdirTestSuite) TestRandomAccessFile(c *C) {
    75  	d := c.MkDir()
    76  	needle := []byte(`stuff`)
    77  	err := ioutil.WriteFile(filepath.Join(d, "foo"), needle, 0644)
    78  	c.Assert(err, IsNil)
    79  
    80  	sn := snapdir.New(d)
    81  	r, err := sn.RandomAccessFile("foo")
    82  	c.Assert(err, IsNil)
    83  	defer r.Close()
    84  
    85  	c.Assert(r.Size(), Equals, int64(5))
    86  
    87  	b := make([]byte, 2)
    88  	n, err := r.ReadAt(b, 2)
    89  	c.Assert(err, IsNil)
    90  	c.Assert(n, Equals, 2)
    91  	c.Check(string(b), Equals, "uf")
    92  }
    93  
    94  func (s *SnapdirTestSuite) TestListDir(c *C) {
    95  	d := c.MkDir()
    96  
    97  	err := os.MkdirAll(filepath.Join(d, "test"), 0755)
    98  	c.Assert(err, IsNil)
    99  	err = ioutil.WriteFile(filepath.Join(d, "test", "test1"), nil, 0644)
   100  	c.Assert(err, IsNil)
   101  	err = ioutil.WriteFile(filepath.Join(d, "test", "test2"), nil, 0644)
   102  	c.Assert(err, IsNil)
   103  
   104  	sn := snapdir.New(d)
   105  	fileNames, err := sn.ListDir("test")
   106  	c.Assert(err, IsNil)
   107  	c.Assert(fileNames, HasLen, 2)
   108  	c.Check(fileNames[0], Equals, "test1")
   109  	c.Check(fileNames[1], Equals, "test2")
   110  }
   111  
   112  func (s *SnapdirTestSuite) TestInstall(c *C) {
   113  	tryBaseDir := c.MkDir()
   114  	sn := snapdir.New(tryBaseDir)
   115  
   116  	varLibSnapd := c.MkDir()
   117  	targetPath := filepath.Join(varLibSnapd, "foo_1.0.snap")
   118  	didNothing, err := sn.Install(targetPath, "unused-mount-dir", nil)
   119  	c.Assert(err, IsNil)
   120  	c.Check(didNothing, Equals, false)
   121  	symlinkTarget, err := filepath.EvalSymlinks(targetPath)
   122  	c.Assert(err, IsNil)
   123  	c.Assert(symlinkTarget, Equals, tryBaseDir)
   124  }
   125  
   126  func (s *SnapdirTestSuite) TestInstallMustNotCrossDevices(c *C) {
   127  	tryBaseDir := c.MkDir()
   128  	sn := snapdir.New(tryBaseDir)
   129  
   130  	varLibSnapd := c.MkDir()
   131  	targetPath := filepath.Join(varLibSnapd, "foo_1.0.snap")
   132  	didNothing, err := sn.Install(targetPath, "unused-mount-dir", &snap.InstallOptions{MustNotCrossDevices: true})
   133  	c.Assert(err, IsNil)
   134  	c.Check(didNothing, Equals, false)
   135  	// TODO:UC20: fix this test when snapdir Install() understands/does
   136  	//            something with opts.MustNotCrossDevices
   137  	c.Check(osutil.IsSymlink(targetPath), Equals, true)
   138  }
   139  
   140  func walkEqual(tryBaseDir, sub string, c *C) {
   141  	fpw := map[string]os.FileInfo{}
   142  	filepath.Walk(filepath.Join(tryBaseDir, sub), func(path string, info os.FileInfo, err error) error {
   143  		if err != nil {
   144  			return err
   145  		}
   146  		path, err = filepath.Rel(tryBaseDir, path)
   147  		if err != nil {
   148  			return err
   149  		}
   150  		fpw[path] = info
   151  		return nil
   152  	})
   153  
   154  	sdw := map[string]os.FileInfo{}
   155  	sn := snapdir.New(tryBaseDir)
   156  	sn.Walk(sub, func(path string, info os.FileInfo, err error) error {
   157  		if err != nil {
   158  			return err
   159  		}
   160  		sdw[path] = info
   161  		return nil
   162  	})
   163  
   164  	for k, v := range fpw {
   165  		c.Check(os.SameFile(sdw[k], v), Equals, true, Commentf(k))
   166  	}
   167  
   168  	for k, v := range sdw {
   169  		c.Check(os.SameFile(fpw[k], v), Equals, true, Commentf(k))
   170  	}
   171  }
   172  
   173  func (s *SnapdirTestSuite) TestWalk(c *C) {
   174  	// probably already done elsewhere, but just in case
   175  	rand.Seed(time.Now().UTC().UnixNano())
   176  
   177  	// https://en.wikipedia.org/wiki/Metasyntactic_variable
   178  	ns := []string{
   179  		"foobar", "foo", "bar", "baz", "qux", "quux", "quuz", "corge",
   180  		"grault", "garply", "waldo", "fred", "plugh", "xyzzy", "thud",
   181  		"wibble", "wobble", "wubble", "flob", "blep", "blah", "boop",
   182  	}
   183  	p := 1.0 / float32(len(ns))
   184  
   185  	var f func(string, int)
   186  	f = func(d string, n int) {
   187  		for _, b := range ns {
   188  			d1 := filepath.Join(d, fmt.Sprintf("%s%d", b, n))
   189  			c.Assert(os.Mkdir(d1, 0755), IsNil)
   190  			if n < 20 && rand.Float32() < p {
   191  				f(d1, n+1)
   192  			}
   193  		}
   194  	}
   195  
   196  	subs := make([]string, len(ns)+3)
   197  	// three ways of saying the same thing ¯\_(ツ)_/¯
   198  	copy(subs, []string{"/", ".", ""})
   199  	copy(subs[3:], ns)
   200  	for i := 0; i < 10; i++ {
   201  		tryBaseDir := c.MkDir()
   202  		f(tryBaseDir, 1)
   203  
   204  		for _, sub := range subs {
   205  			walkEqual(tryBaseDir, sub, c)
   206  		}
   207  
   208  	}
   209  }