~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/agent/tools/tools_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 AGPLv3, see LICENCE file for details.
 
3
 
 
4
package tools_test
 
5
 
 
6
import (
 
7
        "bytes"
 
8
        "encoding/json"
 
9
        "io/ioutil"
 
10
        "os"
 
11
        "path/filepath"
 
12
        "sort"
 
13
 
 
14
        "github.com/juju/errors"
 
15
        jc "github.com/juju/testing/checkers"
 
16
        "github.com/juju/version"
 
17
        gc "gopkg.in/check.v1"
 
18
 
 
19
        agenttools "github.com/juju/juju/agent/tools"
 
20
        "github.com/juju/juju/testing"
 
21
        coretest "github.com/juju/juju/tools"
 
22
)
 
23
 
 
24
type ToolsSuite struct {
 
25
        testing.BaseSuite
 
26
        dataDir string
 
27
}
 
28
 
 
29
var _ = gc.Suite(&ToolsSuite{})
 
30
 
 
31
func (t *ToolsSuite) SetUpTest(c *gc.C) {
 
32
        t.BaseSuite.SetUpTest(c)
 
33
        t.dataDir = c.MkDir()
 
34
}
 
35
 
 
36
func (t *ToolsSuite) TestPackageDependencies(c *gc.C) {
 
37
        // This test is to ensure we don't bring in dependencies on state, environ
 
38
        // or any of the other bigger packages that'll drag in yet more dependencies.
 
39
        // Only imports that start with "github.com/juju/juju" are checked, and the
 
40
        // resulting slice has that prefix removed to keep the output short.
 
41
        c.Assert(testing.FindJujuCoreImports(c, "github.com/juju/juju/agent/tools"),
 
42
                gc.DeepEquals,
 
43
                []string{"tools"})
 
44
}
 
45
 
 
46
// gzyesses holds the result of running:
 
47
// yes | head -17000 | gzip
 
48
var gzyesses = []byte{
 
49
        0x1f, 0x8b, 0x08, 0x00, 0x29, 0xae, 0x1a, 0x50,
 
50
        0x00, 0x03, 0xed, 0xc2, 0x31, 0x0d, 0x00, 0x00,
 
51
        0x00, 0x02, 0xa0, 0xdf, 0xc6, 0xb6, 0xb7, 0x87,
 
52
        0x63, 0xd0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
 
53
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
54
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
55
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
56
        0x00, 0x00, 0x00, 0x38, 0x31, 0x53, 0xad, 0x03,
 
57
        0x8d, 0xd0, 0x84, 0x00, 0x00,
 
58
}
 
59
 
 
60
type badDataTest struct {
 
61
        data     []byte
 
62
        checksum string
 
63
        err      string
 
64
}
 
65
 
 
66
func initBadDataTest(name string, mode os.FileMode, contents string, err string) badDataTest {
 
67
        var result badDataTest
 
68
        result.data, result.checksum = testing.TarGz(testing.NewTarFile(name, mode, contents))
 
69
        result.err = err
 
70
        return result
 
71
}
 
72
 
 
73
var unpackToolsBadDataTests = []badDataTest{
 
74
        initBadDataTest("bar", os.ModeDir, "", "bad file type.*"),
 
75
        initBadDataTest("../../etc/passwd", agenttools.DirPerm, "", "bad name.*"),
 
76
        initBadDataTest(`\ini.sys`, agenttools.DirPerm, "", "bad name.*"),
 
77
        {[]byte("x"), "2d711642b726b04401627ca9fbac32f5c8530fb1903cc4db02258717921a4881", "unexpected EOF"},
 
78
        {gzyesses, "8d900c68a1a847aae4e95edcb29fcecd142c9b88ca4fe63209c216edbed546e1", "archive/tar: invalid tar header"},
 
79
}
 
80
 
 
81
func (t *ToolsSuite) TestUnpackToolsBadData(c *gc.C) {
 
82
        for i, test := range unpackToolsBadDataTests {
 
83
                c.Logf("test %d", i)
 
84
                testTools := &coretest.Tools{
 
85
                        URL:     "http://foo/bar",
 
86
                        Version: version.MustParseBinary("1.2.3-quantal-amd64"),
 
87
                        Size:    int64(len(test.data)),
 
88
                        SHA256:  test.checksum,
 
89
                }
 
90
                err := agenttools.UnpackTools(t.dataDir, testTools, bytes.NewReader(test.data))
 
91
                c.Assert(err, gc.ErrorMatches, test.err)
 
92
                assertDirNames(c, t.toolsDir(), []string{})
 
93
        }
 
94
}
 
95
 
 
96
func (t *ToolsSuite) TestUnpackToolsBadChecksum(c *gc.C) {
 
97
        data, _ := testing.TarGz(testing.NewTarFile("tools", agenttools.DirPerm, "some data"))
 
98
        testTools := &coretest.Tools{
 
99
                URL:     "http://foo/bar",
 
100
                Version: version.MustParseBinary("1.2.3-quantal-amd64"),
 
101
                Size:    int64(len(data)),
 
102
                SHA256:  "1234",
 
103
        }
 
104
        err := agenttools.UnpackTools(t.dataDir, testTools, bytes.NewReader(data))
 
105
        c.Assert(err, gc.ErrorMatches, "tarball sha256 mismatch, expected 1234, got .*")
 
106
        _, err = os.Stat(t.toolsDir())
 
107
        c.Assert(err, gc.FitsTypeOf, &os.PathError{})
 
108
}
 
109
 
 
110
func (t *ToolsSuite) toolsDir() string {
 
111
        return filepath.Join(t.dataDir, "tools")
 
112
}
 
113
 
 
114
func (t *ToolsSuite) TestUnpackToolsContents(c *gc.C) {
 
115
        files := []*testing.TarFile{
 
116
                testing.NewTarFile("bar", agenttools.DirPerm, "bar contents"),
 
117
                testing.NewTarFile("foo", agenttools.DirPerm, "foo contents"),
 
118
        }
 
119
        data, checksum := testing.TarGz(files...)
 
120
        testTools := &coretest.Tools{
 
121
                URL:     "http://foo/bar",
 
122
                Version: version.MustParseBinary("1.2.3-quantal-amd64"),
 
123
                Size:    int64(len(data)),
 
124
                SHA256:  checksum,
 
125
        }
 
126
 
 
127
        err := agenttools.UnpackTools(t.dataDir, testTools, bytes.NewReader(data))
 
128
        c.Assert(err, jc.ErrorIsNil)
 
129
        assertDirNames(c, t.toolsDir(), []string{"1.2.3-quantal-amd64"})
 
130
        t.assertToolsContents(c, testTools, files)
 
131
 
 
132
        // Try to unpack the same version of tools again - it should succeed,
 
133
        // leaving the original version around.
 
134
        files2 := []*testing.TarFile{
 
135
                testing.NewTarFile("bar", agenttools.DirPerm, "bar2 contents"),
 
136
                testing.NewTarFile("x", agenttools.DirPerm, "x contents"),
 
137
        }
 
138
        data2, checksum2 := testing.TarGz(files2...)
 
139
        tools2 := &coretest.Tools{
 
140
                URL:     "http://arble",
 
141
                Version: version.MustParseBinary("1.2.3-quantal-amd64"),
 
142
                Size:    int64(len(data2)),
 
143
                SHA256:  checksum2,
 
144
        }
 
145
        err = agenttools.UnpackTools(t.dataDir, tools2, bytes.NewReader(data2))
 
146
        c.Assert(err, jc.ErrorIsNil)
 
147
        assertDirNames(c, t.toolsDir(), []string{"1.2.3-quantal-amd64"})
 
148
        t.assertToolsContents(c, testTools, files)
 
149
}
 
150
 
 
151
func (t *ToolsSuite) TestReadToolsErrors(c *gc.C) {
 
152
        vers := version.MustParseBinary("1.2.3-precise-amd64")
 
153
        testTools, err := agenttools.ReadTools(t.dataDir, vers)
 
154
        c.Assert(testTools, gc.IsNil)
 
155
        c.Assert(err, gc.ErrorMatches, "cannot read tools metadata in tools directory: .*")
 
156
 
 
157
        dir := agenttools.SharedToolsDir(t.dataDir, vers)
 
158
        err = os.MkdirAll(dir, agenttools.DirPerm)
 
159
        c.Assert(err, jc.ErrorIsNil)
 
160
 
 
161
        err = ioutil.WriteFile(filepath.Join(dir, agenttools.ToolsFile), []byte(" \t\n"), 0644)
 
162
        c.Assert(err, jc.ErrorIsNil)
 
163
 
 
164
        testTools, err = agenttools.ReadTools(t.dataDir, vers)
 
165
        c.Assert(testTools, gc.IsNil)
 
166
        c.Assert(err, gc.ErrorMatches, "invalid tools metadata in tools directory .*")
 
167
}
 
168
 
 
169
func (t *ToolsSuite) TestReadGUIArchiveErrorNotFound(c *gc.C) {
 
170
        gui, err := agenttools.ReadGUIArchive(t.dataDir)
 
171
        c.Assert(err, gc.ErrorMatches, "GUI metadata not found")
 
172
        c.Assert(err, jc.Satisfies, errors.IsNotFound)
 
173
        c.Assert(gui, gc.IsNil)
 
174
}
 
175
 
 
176
func (t *ToolsSuite) TestReadGUIArchiveErrorNotValid(c *gc.C) {
 
177
        dir := agenttools.SharedGUIDir(t.dataDir)
 
178
        err := os.MkdirAll(dir, agenttools.DirPerm)
 
179
        c.Assert(err, jc.ErrorIsNil)
 
180
 
 
181
        err = ioutil.WriteFile(filepath.Join(dir, agenttools.GUIArchiveFile), []byte(" \t\n"), 0644)
 
182
        c.Assert(err, jc.ErrorIsNil)
 
183
 
 
184
        gui, err := agenttools.ReadGUIArchive(t.dataDir)
 
185
        c.Assert(err, gc.ErrorMatches, "invalid GUI metadata in tools directory .*")
 
186
        c.Assert(gui, gc.IsNil)
 
187
}
 
188
 
 
189
func (t *ToolsSuite) TestReadGUIArchiveSuccess(c *gc.C) {
 
190
        dir := agenttools.SharedGUIDir(t.dataDir)
 
191
        err := os.MkdirAll(dir, agenttools.DirPerm)
 
192
        c.Assert(err, jc.ErrorIsNil)
 
193
 
 
194
        expectGUI := coretest.GUIArchive{
 
195
                Version: version.MustParse("2.0.42"),
 
196
                URL:     "file:///path/to/gui",
 
197
                SHA256:  "hash",
 
198
                Size:    47,
 
199
        }
 
200
        b, err := json.Marshal(expectGUI)
 
201
        c.Assert(err, jc.ErrorIsNil)
 
202
        err = ioutil.WriteFile(filepath.Join(dir, agenttools.GUIArchiveFile), b, 0644)
 
203
        c.Assert(err, jc.ErrorIsNil)
 
204
 
 
205
        gui, err := agenttools.ReadGUIArchive(t.dataDir)
 
206
        c.Assert(err, jc.ErrorIsNil)
 
207
        c.Assert(*gui, gc.Equals, expectGUI)
 
208
}
 
209
 
 
210
func (t *ToolsSuite) TestChangeAgentTools(c *gc.C) {
 
211
        files := []*testing.TarFile{
 
212
                testing.NewTarFile("jujuc", agenttools.DirPerm, "juju executable"),
 
213
                testing.NewTarFile("jujud", agenttools.DirPerm, "jujuc executable"),
 
214
        }
 
215
        data, checksum := testing.TarGz(files...)
 
216
        testTools := &coretest.Tools{
 
217
                URL:     "http://foo/bar1",
 
218
                Version: version.MustParseBinary("1.2.3-quantal-amd64"),
 
219
                Size:    int64(len(data)),
 
220
                SHA256:  checksum,
 
221
        }
 
222
        err := agenttools.UnpackTools(t.dataDir, testTools, bytes.NewReader(data))
 
223
        c.Assert(err, jc.ErrorIsNil)
 
224
 
 
225
        gotTools, err := agenttools.ChangeAgentTools(t.dataDir, "testagent", testTools.Version)
 
226
        c.Assert(err, jc.ErrorIsNil)
 
227
        c.Assert(*gotTools, gc.Equals, *testTools)
 
228
 
 
229
        assertDirNames(c, t.toolsDir(), []string{"1.2.3-quantal-amd64", "testagent"})
 
230
        assertDirNames(c, agenttools.ToolsDir(t.dataDir, "testagent"), []string{"jujuc", "jujud", agenttools.ToolsFile})
 
231
 
 
232
        // Upgrade again to check that the link replacement logic works ok.
 
233
        files2 := []*testing.TarFile{
 
234
                testing.NewTarFile("quantal", agenttools.DirPerm, "foo content"),
 
235
                testing.NewTarFile("amd64", agenttools.DirPerm, "bar content"),
 
236
        }
 
237
        data2, checksum2 := testing.TarGz(files2...)
 
238
        tools2 := &coretest.Tools{
 
239
                URL:     "http://foo/bar2",
 
240
                Version: version.MustParseBinary("1.2.4-quantal-amd64"),
 
241
                Size:    int64(len(data2)),
 
242
                SHA256:  checksum2,
 
243
        }
 
244
        err = agenttools.UnpackTools(t.dataDir, tools2, bytes.NewReader(data2))
 
245
        c.Assert(err, jc.ErrorIsNil)
 
246
 
 
247
        gotTools, err = agenttools.ChangeAgentTools(t.dataDir, "testagent", tools2.Version)
 
248
        c.Assert(err, jc.ErrorIsNil)
 
249
        c.Assert(*gotTools, gc.Equals, *tools2)
 
250
 
 
251
        assertDirNames(c, t.toolsDir(), []string{"1.2.3-quantal-amd64", "1.2.4-quantal-amd64", "testagent"})
 
252
        assertDirNames(c, agenttools.ToolsDir(t.dataDir, "testagent"), []string{"quantal", "amd64", agenttools.ToolsFile})
 
253
}
 
254
 
 
255
func (t *ToolsSuite) TestSharedToolsDir(c *gc.C) {
 
256
        dir := agenttools.SharedToolsDir("/var/lib/juju", version.MustParseBinary("1.2.3-precise-amd64"))
 
257
        c.Assert(dir, gc.Equals, "/var/lib/juju/tools/1.2.3-precise-amd64")
 
258
}
 
259
 
 
260
func (t *ToolsSuite) TestSharedGUIDir(c *gc.C) {
 
261
        dir := agenttools.SharedGUIDir("/var/lib/juju")
 
262
        c.Assert(dir, gc.Equals, "/var/lib/juju/gui")
 
263
}
 
264
 
 
265
// assertToolsContents asserts that the directory for the tools
 
266
// has the given contents.
 
267
func (t *ToolsSuite) assertToolsContents(c *gc.C, testTools *coretest.Tools, files []*testing.TarFile) {
 
268
        var wantNames []string
 
269
        for _, f := range files {
 
270
                wantNames = append(wantNames, f.Header.Name)
 
271
        }
 
272
        wantNames = append(wantNames, agenttools.ToolsFile)
 
273
        dir := agenttools.SharedToolsDir(t.dataDir, testTools.Version)
 
274
        assertDirNames(c, dir, wantNames)
 
275
        expectedURLFileContents, err := json.Marshal(testTools)
 
276
        c.Assert(err, jc.ErrorIsNil)
 
277
        assertFileContents(c, dir, agenttools.ToolsFile, string(expectedURLFileContents), 0200)
 
278
        for _, f := range files {
 
279
                assertFileContents(c, dir, f.Header.Name, f.Contents, 0400)
 
280
        }
 
281
        gotTools, err := agenttools.ReadTools(t.dataDir, testTools.Version)
 
282
        c.Assert(err, jc.ErrorIsNil)
 
283
        c.Assert(*gotTools, gc.Equals, *testTools)
 
284
}
 
285
 
 
286
// assertFileContents asserts that the given file in the
 
287
// given directory has the given contents.
 
288
func assertFileContents(c *gc.C, dir, file, contents string, mode os.FileMode) {
 
289
        file = filepath.Join(dir, file)
 
290
        info, err := os.Stat(file)
 
291
        c.Assert(err, jc.ErrorIsNil)
 
292
        c.Assert(info.Mode()&(os.ModeType|mode), gc.Equals, mode)
 
293
        data, err := ioutil.ReadFile(file)
 
294
        c.Assert(err, jc.ErrorIsNil)
 
295
        c.Assert(string(data), gc.Equals, contents)
 
296
}
 
297
 
 
298
// assertDirNames asserts that the given directory
 
299
// holds the given file or directory names.
 
300
func assertDirNames(c *gc.C, dir string, names []string) {
 
301
        f, err := os.Open(dir)
 
302
        c.Assert(err, jc.ErrorIsNil)
 
303
        defer f.Close()
 
304
        dnames, err := f.Readdirnames(0)
 
305
        c.Assert(err, jc.ErrorIsNil)
 
306
        sort.Strings(dnames)
 
307
        sort.Strings(names)
 
308
        c.Assert(dnames, gc.DeepEquals, names)
 
309
}