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