~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/utils/file_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Canonical Ltd.
 
2
// Licensed under the LGPLv3, see LICENCE file for details.
 
3
 
 
4
package utils_test
 
5
 
 
6
import (
 
7
        "fmt"
 
8
        "io/ioutil"
 
9
        "os"
 
10
        "os/user"
 
11
        "path/filepath"
 
12
 
 
13
        "github.com/juju/testing"
 
14
        jc "github.com/juju/testing/checkers"
 
15
        gc "gopkg.in/check.v1"
 
16
 
 
17
        "github.com/juju/utils"
 
18
)
 
19
 
 
20
type fileSuite struct {
 
21
        testing.IsolationSuite
 
22
}
 
23
 
 
24
var _ = gc.Suite(&fileSuite{})
 
25
 
 
26
func (*fileSuite) TestNormalizePath(c *gc.C) {
 
27
        home := filepath.FromSlash(c.MkDir())
 
28
        err := utils.SetHome(home)
 
29
        c.Assert(err, gc.IsNil)
 
30
        // TODO (frankban) bug 1324841: improve the isolation of this suite.
 
31
        currentUser, err := user.Current()
 
32
        c.Assert(err, gc.IsNil)
 
33
        for i, test := range []struct {
 
34
                path     string
 
35
                expected string
 
36
                err      string
 
37
        }{{
 
38
                path:     filepath.FromSlash("/var/lib/juju"),
 
39
                expected: filepath.FromSlash("/var/lib/juju"),
 
40
        }, {
 
41
                path:     "~/foo",
 
42
                expected: filepath.Join(home, "foo"),
 
43
        }, {
 
44
                path:     "~/foo//../bar",
 
45
                expected: filepath.Join(home, "bar"),
 
46
        }, {
 
47
                path:     "~",
 
48
                expected: home,
 
49
        }, {
 
50
                path:     "~" + currentUser.Username,
 
51
                expected: currentUser.HomeDir,
 
52
        }, {
 
53
                path:     "~" + currentUser.Username + "/foo",
 
54
                expected: filepath.Join(currentUser.HomeDir, "foo"),
 
55
        }, {
 
56
                path:     "~" + currentUser.Username + "/foo//../bar",
 
57
                expected: filepath.Join(currentUser.HomeDir, "bar"),
 
58
        }, {
 
59
                path:     filepath.FromSlash("foo~bar/baz"),
 
60
                expected: filepath.FromSlash("foo~bar/baz"),
 
61
        }, {
 
62
                path: "~foobar/path",
 
63
                err:  ".*" + utils.NoSuchUserErrRegexp,
 
64
        }} {
 
65
                c.Logf("test %d: %s", i, test.path)
 
66
                actual, err := utils.NormalizePath(test.path)
 
67
                if test.err != "" {
 
68
                        c.Check(err, gc.ErrorMatches, test.err)
 
69
                } else {
 
70
                        c.Check(err, gc.IsNil)
 
71
                        c.Check(actual, gc.Equals, test.expected)
 
72
                }
 
73
        }
 
74
}
 
75
 
 
76
func (*fileSuite) TestCopyFile(c *gc.C) {
 
77
        dir := c.MkDir()
 
78
        f, err := ioutil.TempFile(dir, "source")
 
79
        c.Assert(err, gc.IsNil)
 
80
        defer f.Close()
 
81
        _, err = f.Write([]byte("hello world"))
 
82
        c.Assert(err, gc.IsNil)
 
83
        dest := filepath.Join(dir, "dest")
 
84
 
 
85
        err = utils.CopyFile(dest, f.Name())
 
86
        c.Assert(err, gc.IsNil)
 
87
        data, err := ioutil.ReadFile(dest)
 
88
        c.Assert(err, gc.IsNil)
 
89
        c.Assert(string(data), gc.Equals, "hello world")
 
90
}
 
91
 
 
92
var atomicWriteFileTests = []struct {
 
93
        summary   string
 
94
        change    func(filename string, contents []byte) error
 
95
        check     func(c *gc.C, fileInfo os.FileInfo)
 
96
        expectErr string
 
97
}{{
 
98
        summary: "atomic file write and chmod 0644",
 
99
        change: func(filename string, contents []byte) error {
 
100
                return utils.AtomicWriteFile(filename, contents, 0765)
 
101
        },
 
102
        check: func(c *gc.C, fi os.FileInfo) {
 
103
                c.Assert(fi.Mode(), gc.Equals, 0765)
 
104
        },
 
105
}, {
 
106
        summary: "atomic file write and change",
 
107
        change: func(filename string, contents []byte) error {
 
108
                chmodChange := func(f *os.File) error {
 
109
                        // FileMod.Chmod() is not implemented on Windows, however, os.Chmod() is
 
110
                        return os.Chmod(f.Name(), 0700)
 
111
                }
 
112
                return utils.AtomicWriteFileAndChange(filename, contents, chmodChange)
 
113
        },
 
114
        check: func(c *gc.C, fi os.FileInfo) {
 
115
                c.Assert(fi.Mode(), gc.Equals, 0700)
 
116
        },
 
117
}, {
 
118
        summary: "atomic file write empty contents",
 
119
        change: func(filename string, contents []byte) error {
 
120
                nopChange := func(*os.File) error {
 
121
                        return nil
 
122
                }
 
123
                return utils.AtomicWriteFileAndChange(filename, contents, nopChange)
 
124
        },
 
125
}, {
 
126
        summary: "atomic file write and failing change func",
 
127
        change: func(filename string, contents []byte) error {
 
128
                errChange := func(*os.File) error {
 
129
                        return fmt.Errorf("pow!")
 
130
                }
 
131
                return utils.AtomicWriteFileAndChange(filename, contents, errChange)
 
132
        },
 
133
        expectErr: "pow!",
 
134
}}
 
135
 
 
136
func (*fileSuite) TestAtomicWriteFile(c *gc.C) {
 
137
        dir := c.MkDir()
 
138
        name := "test.file"
 
139
        path := filepath.Join(dir, name)
 
140
        assertDirContents := func(names ...string) {
 
141
                fis, err := ioutil.ReadDir(dir)
 
142
                c.Assert(err, gc.IsNil)
 
143
                c.Assert(fis, gc.HasLen, len(names))
 
144
                for i, name := range names {
 
145
                        c.Assert(fis[i].Name(), gc.Equals, name)
 
146
                }
 
147
        }
 
148
        assertNotExist := func(path string) {
 
149
                _, err := os.Lstat(path)
 
150
                c.Assert(err, jc.Satisfies, os.IsNotExist)
 
151
        }
 
152
 
 
153
        for i, test := range atomicWriteFileTests {
 
154
                c.Logf("test %d: %s", i, test.summary)
 
155
                // First - test with file not already there.
 
156
                assertDirContents()
 
157
                assertNotExist(path)
 
158
                contents := []byte("some\ncontents")
 
159
 
 
160
                err := test.change(path, contents)
 
161
                if test.expectErr == "" {
 
162
                        c.Assert(err, gc.IsNil)
 
163
                        data, err := ioutil.ReadFile(path)
 
164
                        c.Assert(err, gc.IsNil)
 
165
                        c.Assert(data, jc.DeepEquals, contents)
 
166
                        assertDirContents(name)
 
167
                } else {
 
168
                        c.Assert(err, gc.ErrorMatches, test.expectErr)
 
169
                        assertDirContents()
 
170
                        continue
 
171
                }
 
172
 
 
173
                // Second - test with a file already there.
 
174
                contents = []byte("new\ncontents")
 
175
                err = test.change(path, contents)
 
176
                c.Assert(err, gc.IsNil)
 
177
                data, err := ioutil.ReadFile(path)
 
178
                c.Assert(err, gc.IsNil)
 
179
                c.Assert(data, jc.DeepEquals, contents)
 
180
                assertDirContents(name)
 
181
 
 
182
                // Remove the file to reset scenario.
 
183
                c.Assert(os.Remove(path), gc.IsNil)
 
184
        }
 
185
}
 
186
 
 
187
func (*fileSuite) TestMoveFile(c *gc.C) {
 
188
        d := c.MkDir()
 
189
        dest := filepath.Join(d, "foo")
 
190
        f1Name := filepath.Join(d, ".foo1")
 
191
        f2Name := filepath.Join(d, ".foo2")
 
192
        err := ioutil.WriteFile(f1Name, []byte("macaroni"), 0644)
 
193
        c.Assert(err, gc.IsNil)
 
194
        err = ioutil.WriteFile(f2Name, []byte("cheese"), 0644)
 
195
        c.Assert(err, gc.IsNil)
 
196
 
 
197
        ok, err := utils.MoveFile(f1Name, dest)
 
198
        c.Assert(ok, gc.Equals, true)
 
199
        c.Assert(err, gc.IsNil)
 
200
 
 
201
        ok, err = utils.MoveFile(f2Name, dest)
 
202
        c.Assert(ok, gc.Equals, false)
 
203
        c.Assert(err, gc.NotNil)
 
204
 
 
205
        contents, err := ioutil.ReadFile(dest)
 
206
        c.Assert(err, gc.IsNil)
 
207
        c.Assert(contents, gc.DeepEquals, []byte("macaroni"))
 
208
}