github.com/david-imola/snapd@v0.0.0-20210611180407-2de8ddeece6d/overlord/snapstate/backend/copydata_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2014-2016 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 backend_test
    21  
    22  import (
    23  	"fmt"
    24  	"io/ioutil"
    25  	"os"
    26  	"path/filepath"
    27  	"regexp"
    28  	"strconv"
    29  
    30  	. "gopkg.in/check.v1"
    31  
    32  	"github.com/snapcore/snapd/dirs"
    33  	"github.com/snapcore/snapd/osutil"
    34  	"github.com/snapcore/snapd/overlord/snapstate/backend"
    35  	"github.com/snapcore/snapd/progress"
    36  	"github.com/snapcore/snapd/snap"
    37  	"github.com/snapcore/snapd/snap/snaptest"
    38  	"github.com/snapcore/snapd/testutil"
    39  )
    40  
    41  type copydataSuite struct {
    42  	be      backend.Backend
    43  	tempdir string
    44  }
    45  
    46  var _ = Suite(&copydataSuite{})
    47  
    48  func (s *copydataSuite) SetUpTest(c *C) {
    49  	s.tempdir = c.MkDir()
    50  	dirs.SetRootDir(s.tempdir)
    51  }
    52  
    53  func (s *copydataSuite) TearDownTest(c *C) {
    54  	dirs.SetRootDir("")
    55  }
    56  
    57  const (
    58  	helloYaml1 = `name: hello
    59  version: 1.0
    60  `
    61  	helloYaml2 = `name: hello
    62  version: 2.0
    63  `
    64  )
    65  
    66  func (s *copydataSuite) TestCopyData(c *C) {
    67  	homedir := filepath.Join(s.tempdir, "home", "user1", "snap")
    68  	homeData := filepath.Join(homedir, "hello/10")
    69  	err := os.MkdirAll(homeData, 0755)
    70  	c.Assert(err, IsNil)
    71  	homeCommonData := filepath.Join(homedir, "hello/common")
    72  	err = os.MkdirAll(homeCommonData, 0755)
    73  	c.Assert(err, IsNil)
    74  
    75  	canaryData := []byte("ni ni ni")
    76  
    77  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
    78  	// just creates data dirs in this case
    79  	err = s.be.CopySnapData(v1, nil, progress.Null)
    80  	c.Assert(err, IsNil)
    81  
    82  	canaryDataFile := filepath.Join(v1.DataDir(), "canary.txt")
    83  	err = ioutil.WriteFile(canaryDataFile, canaryData, 0644)
    84  	c.Assert(err, IsNil)
    85  	canaryDataFile = filepath.Join(v1.CommonDataDir(), "canary.common")
    86  	err = ioutil.WriteFile(canaryDataFile, canaryData, 0644)
    87  	c.Assert(err, IsNil)
    88  	err = ioutil.WriteFile(filepath.Join(homeData, "canary.home"), canaryData, 0644)
    89  	c.Assert(err, IsNil)
    90  	err = ioutil.WriteFile(filepath.Join(homeCommonData, "canary.common_home"), canaryData, 0644)
    91  	c.Assert(err, IsNil)
    92  
    93  	v2 := snaptest.MockSnap(c, helloYaml2, &snap.SideInfo{Revision: snap.R(20)})
    94  	err = s.be.CopySnapData(v2, v1, progress.Null)
    95  	c.Assert(err, IsNil)
    96  
    97  	newCanaryDataFile := filepath.Join(dirs.SnapDataDir, "hello/20", "canary.txt")
    98  	c.Assert(newCanaryDataFile, testutil.FileEquals, canaryData)
    99  
   100  	// ensure common data file is still there (even though it didn't get copied)
   101  	newCanaryDataFile = filepath.Join(dirs.SnapDataDir, "hello", "common", "canary.common")
   102  	c.Assert(newCanaryDataFile, testutil.FileEquals, canaryData)
   103  
   104  	newCanaryDataFile = filepath.Join(homedir, "hello/20", "canary.home")
   105  	c.Assert(newCanaryDataFile, testutil.FileEquals, canaryData)
   106  
   107  	// ensure home common data file is still there (even though it didn't get copied)
   108  	newCanaryDataFile = filepath.Join(homedir, "hello", "common", "canary.common_home")
   109  	c.Assert(newCanaryDataFile, testutil.FileEquals, canaryData)
   110  }
   111  
   112  func (s *copydataSuite) TestCopyDataBails(c *C) {
   113  	oldSnapDataHomeGlob := dirs.SnapDataHomeGlob
   114  	defer func() { dirs.SnapDataHomeGlob = oldSnapDataHomeGlob }()
   115  
   116  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   117  	c.Assert(s.be.CopySnapData(v1, nil, progress.Null), IsNil)
   118  	c.Assert(os.Chmod(v1.DataDir(), 0), IsNil)
   119  
   120  	v2 := snaptest.MockSnap(c, helloYaml2, &snap.SideInfo{Revision: snap.R(20)})
   121  	err := s.be.CopySnapData(v2, v1, progress.Null)
   122  	c.Check(err, ErrorMatches, "cannot copy .*")
   123  }
   124  
   125  // ensure that even with no home dir there is no error and the
   126  // system data gets copied
   127  func (s *copydataSuite) TestCopyDataNoUserHomes(c *C) {
   128  	// this home dir path does not exist
   129  	oldSnapDataHomeGlob := dirs.SnapDataHomeGlob
   130  	defer func() { dirs.SnapDataHomeGlob = oldSnapDataHomeGlob }()
   131  	dirs.SnapDataHomeGlob = filepath.Join(s.tempdir, "no-such-home", "*", "snap")
   132  
   133  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   134  	err := s.be.CopySnapData(v1, nil, progress.Null)
   135  	c.Assert(err, IsNil)
   136  
   137  	canaryDataFile := filepath.Join(v1.DataDir(), "canary.txt")
   138  	err = ioutil.WriteFile(canaryDataFile, []byte(""), 0644)
   139  	c.Assert(err, IsNil)
   140  	canaryDataFile = filepath.Join(v1.CommonDataDir(), "canary.common")
   141  	err = ioutil.WriteFile(canaryDataFile, []byte(""), 0644)
   142  	c.Assert(err, IsNil)
   143  
   144  	v2 := snaptest.MockSnap(c, helloYaml2, &snap.SideInfo{Revision: snap.R(20)})
   145  	err = s.be.CopySnapData(v2, v1, progress.Null)
   146  	c.Assert(err, IsNil)
   147  
   148  	_, err = os.Stat(filepath.Join(v2.DataDir(), "canary.txt"))
   149  	c.Assert(err, IsNil)
   150  	_, err = os.Stat(filepath.Join(v2.CommonDataDir(), "canary.common"))
   151  	c.Assert(err, IsNil)
   152  
   153  	// sanity atm
   154  	c.Check(v1.DataDir(), Not(Equals), v2.DataDir())
   155  	c.Check(v1.CommonDataDir(), Equals, v2.CommonDataDir())
   156  }
   157  
   158  func (s *copydataSuite) populateData(c *C, revision snap.Revision) {
   159  	datadir := filepath.Join(dirs.SnapDataDir, "hello", revision.String())
   160  	subdir := filepath.Join(datadir, "random-subdir")
   161  	err := os.MkdirAll(subdir, 0755)
   162  	c.Assert(err, IsNil)
   163  	err = ioutil.WriteFile(filepath.Join(subdir, "canary"), []byte(fmt.Sprintln(revision)), 0644)
   164  	c.Assert(err, IsNil)
   165  }
   166  
   167  func (s *copydataSuite) populatedData(d string) string {
   168  	bs, err := ioutil.ReadFile(filepath.Join(dirs.SnapDataDir, "hello", d, "random-subdir", "canary"))
   169  	if err == nil {
   170  		return string(bs)
   171  	}
   172  	if os.IsNotExist(err) {
   173  		return ""
   174  	}
   175  	panic(err)
   176  }
   177  
   178  func (s copydataSuite) populateHomeData(c *C, user string, revision snap.Revision) (homedir string) {
   179  	homedir = filepath.Join(s.tempdir, "home", user, "snap")
   180  	homeData := filepath.Join(homedir, "hello", revision.String())
   181  	err := os.MkdirAll(homeData, 0755)
   182  	c.Assert(err, IsNil)
   183  	err = ioutil.WriteFile(filepath.Join(homeData, "canary.home"), []byte(fmt.Sprintln(revision)), 0644)
   184  	c.Assert(err, IsNil)
   185  
   186  	return homedir
   187  }
   188  
   189  func (s *copydataSuite) TestCopyDataDoUndo(c *C) {
   190  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   191  	s.populateData(c, snap.R(10))
   192  	homedir := s.populateHomeData(c, "user1", snap.R(10))
   193  
   194  	// pretend we install a new version
   195  	v2 := snaptest.MockSnap(c, helloYaml2, &snap.SideInfo{Revision: snap.R(20)})
   196  
   197  	// copy data
   198  	err := s.be.CopySnapData(v2, v1, progress.Null)
   199  	c.Assert(err, IsNil)
   200  	v2data := filepath.Join(dirs.SnapDataDir, "hello/20")
   201  	l, err := filepath.Glob(filepath.Join(v2data, "*"))
   202  	c.Assert(err, IsNil)
   203  	c.Assert(l, HasLen, 1)
   204  	v2HomeData := filepath.Join(homedir, "hello/20")
   205  	l, err = filepath.Glob(filepath.Join(v2HomeData, "*"))
   206  	c.Assert(err, IsNil)
   207  	c.Assert(l, HasLen, 1)
   208  
   209  	err = s.be.UndoCopySnapData(v2, v1, progress.Null)
   210  	c.Assert(err, IsNil)
   211  
   212  	// now removed
   213  	_, err = os.Stat(v2data)
   214  	c.Assert(os.IsNotExist(err), Equals, true)
   215  	_, err = os.Stat(v2HomeData)
   216  	c.Assert(os.IsNotExist(err), Equals, true)
   217  }
   218  
   219  func (s *copydataSuite) TestCopyDataDoUndoNoUserHomes(c *C) {
   220  	// this home dir path does not exist
   221  	oldSnapDataHomeGlob := dirs.SnapDataHomeGlob
   222  	defer func() { dirs.SnapDataHomeGlob = oldSnapDataHomeGlob }()
   223  	dirs.SnapDataHomeGlob = filepath.Join(s.tempdir, "no-such-home", "*", "snap")
   224  
   225  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   226  	s.populateData(c, snap.R(10))
   227  
   228  	// pretend we install a new version
   229  	v2 := snaptest.MockSnap(c, helloYaml2, &snap.SideInfo{Revision: snap.R(20)})
   230  
   231  	// copy data
   232  	err := s.be.CopySnapData(v2, v1, progress.Null)
   233  	c.Assert(err, IsNil)
   234  	v2data := filepath.Join(dirs.SnapDataDir, "hello/20")
   235  	l, err := filepath.Glob(filepath.Join(v2data, "*"))
   236  	c.Assert(err, IsNil)
   237  	c.Assert(l, HasLen, 1)
   238  
   239  	err = s.be.UndoCopySnapData(v2, v1, progress.Null)
   240  	c.Assert(err, IsNil)
   241  
   242  	// now removed
   243  	_, err = os.Stat(v2data)
   244  	c.Assert(os.IsNotExist(err), Equals, true)
   245  }
   246  
   247  func (s *copydataSuite) TestCopyDataDoUndoFirstInstall(c *C) {
   248  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   249  
   250  	// first install
   251  	err := s.be.CopySnapData(v1, nil, progress.Null)
   252  	c.Assert(err, IsNil)
   253  	_, err = os.Stat(v1.DataDir())
   254  	c.Assert(err, IsNil)
   255  	_, err = os.Stat(v1.CommonDataDir())
   256  	c.Assert(err, IsNil)
   257  
   258  	err = s.be.UndoCopySnapData(v1, nil, progress.Null)
   259  	c.Assert(err, IsNil)
   260  	_, err = os.Stat(v1.DataDir())
   261  	c.Check(os.IsNotExist(err), Equals, true)
   262  	_, err = os.Stat(v1.CommonDataDir())
   263  	c.Check(os.IsNotExist(err), Equals, true)
   264  }
   265  
   266  func (s *copydataSuite) TestCopyDataDoABA(c *C) {
   267  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   268  	s.populateData(c, snap.R(10))
   269  	c.Check(s.populatedData("10"), Equals, "10\n")
   270  
   271  	// pretend we install a new version
   272  	v2 := snaptest.MockSnap(c, helloYaml2, &snap.SideInfo{Revision: snap.R(20)})
   273  	// and write our own data to it
   274  	s.populateData(c, snap.R(20))
   275  	c.Check(s.populatedData("20"), Equals, "20\n")
   276  
   277  	// and now we pretend to refresh back to v1 (r10)
   278  	c.Check(s.be.CopySnapData(v1, v2, progress.Null), IsNil)
   279  
   280  	// so 10 now has 20's data
   281  	c.Check(s.populatedData("10"), Equals, "20\n")
   282  
   283  	// but we still have the trash
   284  	c.Check(s.populatedData("10.old"), Equals, "10\n")
   285  
   286  	// but cleanup cleans it up, huzzah
   287  	s.be.ClearTrashedData(v1)
   288  	c.Check(s.populatedData("10.old"), Equals, "")
   289  }
   290  
   291  func (s *copydataSuite) TestCopyDataDoUndoABA(c *C) {
   292  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   293  	s.populateData(c, snap.R(10))
   294  	c.Check(s.populatedData("10"), Equals, "10\n")
   295  
   296  	// pretend we install a new version
   297  	v2 := snaptest.MockSnap(c, helloYaml2, &snap.SideInfo{Revision: snap.R(20)})
   298  	// and write our own data to it
   299  	s.populateData(c, snap.R(20))
   300  	c.Check(s.populatedData("20"), Equals, "20\n")
   301  
   302  	// and now we pretend to refresh back to v1 (r10)
   303  	c.Check(s.be.CopySnapData(v1, v2, progress.Null), IsNil)
   304  
   305  	// so v1 (r10) now has v2 (r20)'s data and we have trash
   306  	c.Check(s.populatedData("10"), Equals, "20\n")
   307  	c.Check(s.populatedData("10.old"), Equals, "10\n")
   308  
   309  	// but oh no! we have to undo it!
   310  	c.Check(s.be.UndoCopySnapData(v1, v2, progress.Null), IsNil)
   311  
   312  	// so now v1 (r10) has v1 (r10)'s data and v2 (r20) has v2 (r20)'s data and we have no trash
   313  	c.Check(s.populatedData("10"), Equals, "10\n")
   314  	c.Check(s.populatedData("20"), Equals, "20\n")
   315  	c.Check(s.populatedData("10.old"), Equals, "")
   316  }
   317  
   318  func (s *copydataSuite) TestCopyDataDoIdempotent(c *C) {
   319  	// make sure that a retry wouldn't stumble on partial work
   320  
   321  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   322  
   323  	s.populateData(c, snap.R(10))
   324  	homedir := s.populateHomeData(c, "user1", snap.R(10))
   325  
   326  	// pretend we install a new version
   327  	v2 := snaptest.MockSnap(c, helloYaml2, &snap.SideInfo{Revision: snap.R(20)})
   328  
   329  	// copy data
   330  	err := s.be.CopySnapData(v2, v1, progress.Null)
   331  	c.Assert(err, IsNil)
   332  
   333  	err = s.be.CopySnapData(v2, v1, progress.Null)
   334  	c.Assert(err, IsNil)
   335  
   336  	v2data := filepath.Join(dirs.SnapDataDir, "hello/20")
   337  	l, err := filepath.Glob(filepath.Join(v2data, "*"))
   338  	c.Assert(err, IsNil)
   339  	c.Assert(l, HasLen, 1)
   340  	v2HomeData := filepath.Join(homedir, "hello/20")
   341  	l, err = filepath.Glob(filepath.Join(v2HomeData, "*"))
   342  	c.Assert(err, IsNil)
   343  	c.Assert(l, HasLen, 1)
   344  }
   345  
   346  func (s *copydataSuite) TestCopyDataUndoIdempotent(c *C) {
   347  	// make sure that a retry wouldn't stumble on partial work
   348  
   349  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   350  	s.populateData(c, snap.R(10))
   351  	homedir := s.populateHomeData(c, "user1", snap.R(10))
   352  
   353  	// pretend we install a new version
   354  	v2 := snaptest.MockSnap(c, helloYaml2, &snap.SideInfo{Revision: snap.R(20)})
   355  
   356  	// copy data
   357  	err := s.be.CopySnapData(v2, v1, progress.Null)
   358  	c.Assert(err, IsNil)
   359  
   360  	v2data := filepath.Join(dirs.SnapDataDir, "hello/20")
   361  
   362  	err = s.be.UndoCopySnapData(v2, v1, progress.Null)
   363  	c.Assert(err, IsNil)
   364  
   365  	err = s.be.UndoCopySnapData(v2, v1, progress.Null)
   366  	c.Assert(err, IsNil)
   367  
   368  	// now removed
   369  	_, err = os.Stat(v2data)
   370  	c.Assert(os.IsNotExist(err), Equals, true)
   371  	v2HomeData := filepath.Join(homedir, "hello/20")
   372  	_, err = os.Stat(v2HomeData)
   373  	c.Assert(os.IsNotExist(err), Equals, true)
   374  }
   375  
   376  func (s *copydataSuite) TestCopyDataDoFirstInstallIdempotent(c *C) {
   377  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   378  
   379  	// first install
   380  	err := s.be.CopySnapData(v1, nil, progress.Null)
   381  	c.Assert(err, IsNil)
   382  
   383  	err = s.be.CopySnapData(v1, nil, progress.Null)
   384  	c.Assert(err, IsNil)
   385  
   386  	_, err = os.Stat(v1.DataDir())
   387  	c.Assert(err, IsNil)
   388  	_, err = os.Stat(v1.CommonDataDir())
   389  	c.Assert(err, IsNil)
   390  
   391  	err = s.be.UndoCopySnapData(v1, nil, progress.Null)
   392  	c.Assert(err, IsNil)
   393  	_, err = os.Stat(v1.DataDir())
   394  	c.Check(os.IsNotExist(err), Equals, true)
   395  	_, err = os.Stat(v1.CommonDataDir())
   396  	c.Check(os.IsNotExist(err), Equals, true)
   397  }
   398  
   399  func (s *copydataSuite) TestCopyDataUndoFirstInstallIdempotent(c *C) {
   400  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   401  
   402  	// first install
   403  	err := s.be.CopySnapData(v1, nil, progress.Null)
   404  	c.Assert(err, IsNil)
   405  	_, err = os.Stat(v1.DataDir())
   406  	c.Assert(err, IsNil)
   407  	_, err = os.Stat(v1.CommonDataDir())
   408  	c.Assert(err, IsNil)
   409  
   410  	err = s.be.UndoCopySnapData(v1, nil, progress.Null)
   411  	c.Assert(err, IsNil)
   412  
   413  	err = s.be.UndoCopySnapData(v1, nil, progress.Null)
   414  	c.Assert(err, IsNil)
   415  
   416  	_, err = os.Stat(v1.DataDir())
   417  	c.Check(os.IsNotExist(err), Equals, true)
   418  	_, err = os.Stat(v1.CommonDataDir())
   419  	c.Check(os.IsNotExist(err), Equals, true)
   420  }
   421  
   422  func (s *copydataSuite) TestCopyDataCopyFailure(c *C) {
   423  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   424  	s.populateData(c, snap.R(10))
   425  
   426  	// pretend we install a new version
   427  	v2 := snaptest.MockSnap(c, helloYaml2, &snap.SideInfo{Revision: snap.R(20)})
   428  
   429  	defer testutil.MockCommand(c, "cp", "echo cp: boom; exit 3").Restore()
   430  
   431  	q := func(s string) string {
   432  		return regexp.QuoteMeta(strconv.Quote(s))
   433  	}
   434  
   435  	// copy data will fail
   436  	err := s.be.CopySnapData(v2, v1, progress.Null)
   437  	c.Assert(err, ErrorMatches, fmt.Sprintf(`cannot copy %s to %s: .*: "cp: boom" \(3\)`, q(v1.DataDir()), q(v2.DataDir())))
   438  }
   439  
   440  func (s *copydataSuite) TestCopyDataPartialFailure(c *C) {
   441  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   442  
   443  	s.populateData(c, snap.R(10))
   444  	homedir1 := s.populateHomeData(c, "user1", snap.R(10))
   445  	homedir2 := s.populateHomeData(c, "user2", snap.R(10))
   446  
   447  	// pretend we install a new version
   448  	v2 := snaptest.MockSnap(c, helloYaml2, &snap.SideInfo{Revision: snap.R(20)})
   449  
   450  	// sanity check: the 20 dirs don't exist yet (but 10 do)
   451  	for _, dir := range []string{dirs.SnapDataDir, homedir1, homedir2} {
   452  		c.Assert(osutil.FileExists(filepath.Join(dir, "hello", "20")), Equals, false, Commentf(dir))
   453  		c.Assert(osutil.FileExists(filepath.Join(dir, "hello", "10")), Equals, true, Commentf(dir))
   454  	}
   455  
   456  	c.Assert(os.Chmod(filepath.Join(homedir2, "hello", "10", "canary.home"), 0), IsNil)
   457  
   458  	// try to copy data
   459  	err := s.be.CopySnapData(v2, v1, progress.Null)
   460  	c.Assert(err, NotNil)
   461  
   462  	// the copy data failed, so check it cleaned up after itself (but not too much!)
   463  	for _, dir := range []string{dirs.SnapDataDir, homedir1, homedir2} {
   464  		c.Check(osutil.FileExists(filepath.Join(dir, "hello", "20")), Equals, false, Commentf(dir))
   465  		c.Check(osutil.FileExists(filepath.Join(dir, "hello", "10")), Equals, true, Commentf(dir))
   466  	}
   467  }
   468  
   469  func (s *copydataSuite) TestCopyDataSameRevision(c *C) {
   470  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   471  
   472  	homedir1 := s.populateHomeData(c, "user1", snap.R(10))
   473  	homedir2 := s.populateHomeData(c, "user2", snap.R(10))
   474  	c.Assert(os.MkdirAll(v1.DataDir(), 0755), IsNil)
   475  	c.Assert(os.MkdirAll(v1.CommonDataDir(), 0755), IsNil)
   476  	c.Assert(ioutil.WriteFile(filepath.Join(v1.DataDir(), "canary.txt"), nil, 0644), IsNil)
   477  	c.Assert(ioutil.WriteFile(filepath.Join(v1.CommonDataDir(), "canary.common"), nil, 0644), IsNil)
   478  
   479  	// the data is there
   480  	for _, fn := range []string{
   481  		filepath.Join(v1.DataDir(), "canary.txt"),
   482  		filepath.Join(v1.CommonDataDir(), "canary.common"),
   483  		filepath.Join(homedir1, "hello", "10", "canary.home"),
   484  		filepath.Join(homedir2, "hello", "10", "canary.home"),
   485  	} {
   486  		c.Assert(osutil.FileExists(fn), Equals, true, Commentf(fn))
   487  	}
   488  
   489  	// copy data works
   490  	err := s.be.CopySnapData(v1, v1, progress.Null)
   491  	c.Assert(err, IsNil)
   492  
   493  	// the data is still there :-)
   494  	for _, fn := range []string{
   495  		filepath.Join(v1.DataDir(), "canary.txt"),
   496  		filepath.Join(v1.CommonDataDir(), "canary.common"),
   497  		filepath.Join(homedir1, "hello", "10", "canary.home"),
   498  		filepath.Join(homedir2, "hello", "10", "canary.home"),
   499  	} {
   500  		c.Check(osutil.FileExists(fn), Equals, true, Commentf(fn))
   501  	}
   502  
   503  }
   504  
   505  func (s *copydataSuite) TestUndoCopyDataSameRevision(c *C) {
   506  	v1 := snaptest.MockSnap(c, helloYaml1, &snap.SideInfo{Revision: snap.R(10)})
   507  
   508  	homedir1 := s.populateHomeData(c, "user1", snap.R(10))
   509  	homedir2 := s.populateHomeData(c, "user2", snap.R(10))
   510  	c.Assert(os.MkdirAll(v1.DataDir(), 0755), IsNil)
   511  	c.Assert(os.MkdirAll(v1.CommonDataDir(), 0755), IsNil)
   512  	c.Assert(ioutil.WriteFile(filepath.Join(v1.DataDir(), "canary.txt"), nil, 0644), IsNil)
   513  	c.Assert(ioutil.WriteFile(filepath.Join(v1.CommonDataDir(), "canary.common"), nil, 0644), IsNil)
   514  
   515  	// the data is there
   516  	for _, fn := range []string{
   517  		filepath.Join(v1.DataDir(), "canary.txt"),
   518  		filepath.Join(v1.CommonDataDir(), "canary.common"),
   519  		filepath.Join(homedir1, "hello", "10", "canary.home"),
   520  		filepath.Join(homedir2, "hello", "10", "canary.home"),
   521  	} {
   522  		c.Assert(osutil.FileExists(fn), Equals, true, Commentf(fn))
   523  	}
   524  
   525  	// undo copy data works
   526  	err := s.be.UndoCopySnapData(v1, v1, progress.Null)
   527  	c.Assert(err, IsNil)
   528  
   529  	// the data is still there :-)
   530  	for _, fn := range []string{
   531  		filepath.Join(v1.DataDir(), "canary.txt"),
   532  		filepath.Join(v1.CommonDataDir(), "canary.common"),
   533  		filepath.Join(homedir1, "hello", "10", "canary.home"),
   534  		filepath.Join(homedir2, "hello", "10", "canary.home"),
   535  	} {
   536  		c.Check(osutil.FileExists(fn), Equals, true, Commentf(fn))
   537  	}
   538  
   539  }