~mvo/snappy/snappy-os-snap-support

« back to all changes in this revision

Viewing changes to helpers/cp_test.go

  • Committer: Snappy Tarmac
  • Author(s): John R. Lenton
  • Date: 2015-05-05 22:32:10 UTC
  • mfrom: (435.1.5 copyfile)
  • Revision ID: snappy_tarmac-20150505223210-w7oz8tnd8y2xokwj
Moved two implementations of Copy into helpers with the linux implementation being based on sendfile. by chipaca approved by sergiusens

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2014-2015 Canonical Ltd
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License version 3 as
 
6
 * published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 */
 
17
 
 
18
package helpers
 
19
 
 
20
import (
 
21
        "errors"
 
22
        "io/ioutil"
 
23
        "os"
 
24
        "path/filepath"
 
25
        "strings"
 
26
        "time"
 
27
 
 
28
        . "launchpad.net/gocheck"
 
29
)
 
30
 
 
31
type cpSuite struct {
 
32
        dir  string
 
33
        f1   string
 
34
        f2   string
 
35
        data []byte
 
36
        log  []string
 
37
        errs []error
 
38
        idx  int
 
39
}
 
40
 
 
41
var _ = Suite(&cpSuite{})
 
42
 
 
43
func (s *cpSuite) mockCopyFile(fin, fout fileish, fi os.FileInfo) error {
 
44
        return s.µ("copyfile")
 
45
}
 
46
 
 
47
func (s *cpSuite) mockOpenFile(name string, flag int, perm os.FileMode) (fileish, error) {
 
48
        return &mockfile{s}, s.µ("open")
 
49
}
 
50
 
 
51
func (s *cpSuite) µ(msg string) (err error) {
 
52
        s.log = append(s.log, msg)
 
53
        if len(s.errs) > 0 {
 
54
                err = s.errs[0]
 
55
                if len(s.errs) > 1 {
 
56
                        s.errs = s.errs[1:]
 
57
                }
 
58
        }
 
59
 
 
60
        return
 
61
}
 
62
 
 
63
func (s *cpSuite) SetUpTest(c *C) {
 
64
        s.errs = nil
 
65
        s.log = nil
 
66
        s.dir = c.MkDir()
 
67
        s.f1 = filepath.Join(s.dir, "f1")
 
68
        s.f2 = filepath.Join(s.dir, "f2")
 
69
        s.data = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
 
70
        c.Assert(ioutil.WriteFile(s.f1, s.data, 0644), IsNil)
 
71
}
 
72
 
 
73
func (s *cpSuite) mock() {
 
74
        copyfile = s.mockCopyFile
 
75
        openfile = s.mockOpenFile
 
76
}
 
77
 
 
78
func (s *cpSuite) TearDownTest(c *C) {
 
79
        copyfile = doCopyFile
 
80
        openfile = doOpenFile
 
81
}
 
82
 
 
83
func (s *cpSuite) TestCp(c *C) {
 
84
        c.Check(CopyFile(s.f1, s.f2, CopyFlagDefault), IsNil)
 
85
        bs, err := ioutil.ReadFile(s.f2)
 
86
        c.Check(err, IsNil)
 
87
        c.Check(bs, DeepEquals, s.data)
 
88
}
 
89
 
 
90
func (s *cpSuite) TestCpSync(c *C) {
 
91
        s.mock()
 
92
        c.Check(CopyFile(s.f1, s.f2, CopyFlagDefault), IsNil)
 
93
        c.Check(strings.Join(s.log, ":"), Not(Matches), `.*:sync(:.*)?`)
 
94
 
 
95
        s.log = nil
 
96
        c.Check(CopyFile(s.f1, s.f2, CopyFlagSync), IsNil)
 
97
        c.Check(strings.Join(s.log, ":"), Matches, `(.*:)?sync(:.*)?`)
 
98
}
 
99
 
 
100
func (s *cpSuite) TestCpCantOpen(c *C) {
 
101
        s.mock()
 
102
        s.errs = []error{errors.New("xyzzy"), nil}
 
103
 
 
104
        c.Check(CopyFile(s.f1, s.f2, CopyFlagSync), ErrorMatches, `unable to open \S+/f1: xyzzy`)
 
105
}
 
106
 
 
107
func (s *cpSuite) TestCpCantStat(c *C) {
 
108
        s.mock()
 
109
        s.errs = []error{nil, errors.New("xyzzy"), nil}
 
110
 
 
111
        c.Check(CopyFile(s.f1, s.f2, CopyFlagSync), ErrorMatches, `unable to stat \S+/f1: xyzzy`)
 
112
}
 
113
 
 
114
func (s *cpSuite) TestCpCantCreate(c *C) {
 
115
        s.mock()
 
116
        s.errs = []error{nil, nil, errors.New("xyzzy"), nil}
 
117
 
 
118
        c.Check(CopyFile(s.f1, s.f2, CopyFlagSync), ErrorMatches, `unable to create \S+/f2: xyzzy`)
 
119
}
 
120
 
 
121
func (s *cpSuite) TestCpCantCopy(c *C) {
 
122
        s.mock()
 
123
        s.errs = []error{nil, nil, nil, errors.New("xyzzy"), nil}
 
124
 
 
125
        c.Check(CopyFile(s.f1, s.f2, CopyFlagSync), ErrorMatches, `unable to copy \S+/f1 to \S+/f2: xyzzy`)
 
126
}
 
127
 
 
128
func (s *cpSuite) TestCpCantSync(c *C) {
 
129
        s.mock()
 
130
        s.errs = []error{nil, nil, nil, nil, errors.New("xyzzy"), nil}
 
131
 
 
132
        c.Check(CopyFile(s.f1, s.f2, CopyFlagSync), ErrorMatches, `unable to sync \S+/f2: xyzzy`)
 
133
}
 
134
 
 
135
func (s *cpSuite) TestCpCantStop2(c *C) {
 
136
        s.mock()
 
137
        s.errs = []error{nil, nil, nil, nil, nil, errors.New("xyzzy"), nil}
 
138
 
 
139
        c.Check(CopyFile(s.f1, s.f2, CopyFlagSync), ErrorMatches, `when closing \S+/f2: xyzzy`)
 
140
}
 
141
 
 
142
func (s *cpSuite) TestCpCantStop1(c *C) {
 
143
        s.mock()
 
144
        s.errs = []error{nil, nil, nil, nil, nil, nil, errors.New("xyzzy"), nil}
 
145
 
 
146
        c.Check(CopyFile(s.f1, s.f2, CopyFlagSync), ErrorMatches, `when closing \S+/f1: xyzzy`)
 
147
}
 
148
 
 
149
type mockfile struct {
 
150
        s *cpSuite
 
151
}
 
152
 
 
153
var mockst = mockstat{}
 
154
 
 
155
func (f *mockfile) Close() error               { return f.s.µ("close") }
 
156
func (f *mockfile) Sync() error                { return f.s.µ("sync") }
 
157
func (f *mockfile) Fd() uintptr                { f.s.µ("fd"); return 42 }
 
158
func (f *mockfile) Read([]byte) (int, error)   { return 0, f.s.µ("read") }
 
159
func (f *mockfile) Write([]byte) (int, error)  { return 0, f.s.µ("write") }
 
160
func (f *mockfile) Stat() (os.FileInfo, error) { return mockst, f.s.µ("stat") }
 
161
 
 
162
type mockstat struct{}
 
163
 
 
164
func (mockstat) Name() string       { return "mockstat" }
 
165
func (mockstat) Size() int64        { return 42 }
 
166
func (mockstat) Mode() os.FileMode  { return 0644 }
 
167
func (mockstat) ModTime() time.Time { return time.Now() }
 
168
func (mockstat) IsDir() bool        { return false }
 
169
func (mockstat) Sys() interface{}   { return nil }