Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(293)

Side by Side Diff: go/src/infra/tools/cipd/builder_test.go

Issue 1129043003: cipd: Refactor client to make it more readable. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « go/src/infra/tools/cipd/builder.go ('k') | go/src/infra/tools/cipd/client.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package cipd
6
7 import (
8 "archive/zip"
9 "bytes"
10 "crypto/sha1"
11 "encoding/hex"
12 "fmt"
13 "io"
14 "io/ioutil"
15 "os"
16 "runtime"
17 "testing"
18
19 . "github.com/smartystreets/goconvey/convey"
20 )
21
22 func TestGoVersion(t *testing.T) {
23 Convey("Make sure using pinned Go version", t, func() {
24 // Change this when rolling pinned Go version. Some tests here m ay depend
25 // on zlib implementation details compiled in Go stdlib.
26 So(runtime.Version(), ShouldEqual, "go1.4")
27 })
28 }
29
30 func TestBuildInstance(t *testing.T) {
31 const goodManifest = `{
32 "format_version": "1",
33 "package_name": "testing"
34 }`
35
36 Convey("Building empty package", t, func() {
37 out := bytes.Buffer{}
38 err := BuildInstance(BuildInstanceOptions{
39 Input: []File{},
40 Output: &out,
41 PackageName: "testing",
42 })
43 So(err, ShouldBeNil)
44
45 // BuildInstance builds deterministic zip. It MUST NOT depend on
46 // the platform, or a time of day, or anything else, only on the input data.
47 So(getSHA1(&out), ShouldEqual, "23f2c4900785ac8faa2f38e473925b84 0e574ccc")
48
49 // There should be a single file: the manifest.
50 files := readZip(out.Bytes())
51 So(files, ShouldResemble, []zippedFile{
52 zippedFile{
53 // See structs.go, manifestName.
54 name: ".cipdpkg/manifest.json",
55 size: uint64(len(goodManifest)),
56 mode: 0600,
57 body: []byte(goodManifest),
58 },
59 })
60 })
61
62 Convey("Building package with a bunch of files", t, func() {
63 out := bytes.Buffer{}
64 err := BuildInstance(BuildInstanceOptions{
65 Input: []File{
66 makeTestFile("testing/qwerty", "12345", false),
67 makeTestFile("abc", "duh", true),
68 makeTestSymlink("rel_symlink", "abc"),
69 makeTestSymlink("abs_symlink", "/abc/def"),
70 },
71 Output: &out,
72 PackageName: "testing",
73 })
74 So(err, ShouldBeNil)
75
76 // The manifest and all added files.
77 files := readZip(out.Bytes())
78 So(files, ShouldResemble, []zippedFile{
79 zippedFile{
80 name: "testing/qwerty",
81 size: 5,
82 mode: 0600,
83 body: []byte("12345"),
84 },
85 zippedFile{
86 name: "abc",
87 size: 3,
88 mode: 0700,
89 body: []byte("duh"),
90 },
91 zippedFile{
92 name: "rel_symlink",
93 size: 3,
94 mode: 0600 | os.ModeSymlink,
95 body: []byte("abc"),
96 },
97 zippedFile{
98 name: "abs_symlink",
99 size: 8,
100 mode: 0600 | os.ModeSymlink,
101 body: []byte("/abc/def"),
102 },
103 zippedFile{
104 // See structs.go, manifestName.
105 name: ".cipdpkg/manifest.json",
106 size: uint64(len(goodManifest)),
107 mode: 0600,
108 body: []byte(goodManifest),
109 },
110 })
111 })
112
113 Convey("Duplicate files fail", t, func() {
114 err := BuildInstance(BuildInstanceOptions{
115 Input: []File{
116 makeTestFile("a", "12345", false),
117 makeTestFile("a", "12345", false),
118 },
119 Output: &bytes.Buffer{},
120 PackageName: "testing",
121 })
122 So(err, ShouldNotBeNil)
123 })
124
125 Convey("Writing to service dir fails", t, func() {
126 err := BuildInstance(BuildInstanceOptions{
127 Input: []File{
128 makeTestFile(".cipdpkg/stuff", "12345", false),
129 },
130 Output: &bytes.Buffer{},
131 PackageName: "testing",
132 })
133 So(err, ShouldNotBeNil)
134 })
135
136 Convey("Bad name fails", t, func() {
137 err := BuildInstance(BuildInstanceOptions{
138 Output: &bytes.Buffer{},
139 PackageName: "../../asdad",
140 })
141 So(err, ShouldNotBeNil)
142 })
143
144 }
145
146 ////////////////////////////////////////////////////////////////////////////////
147
148 // getSHA1 returns SHA1 hex digest of a byte buffer.
149 func getSHA1(buf *bytes.Buffer) string {
150 h := sha1.New()
151 h.Write(buf.Bytes())
152 return hex.EncodeToString(h.Sum(nil))
153 }
154
155 ////////////////////////////////////////////////////////////////////////////////
156
157 type zippedFile struct {
158 name string
159 size uint64
160 mode os.FileMode
161 body []byte
162 }
163
164 // readZip scans zip directory and returns files it finds.
165 func readZip(data []byte) []zippedFile {
166 z, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
167 if err != nil {
168 panic("Failed to open zip file")
169 }
170 files := make([]zippedFile, len(z.File))
171 for i, zf := range z.File {
172 reader, err := zf.Open()
173 if err != nil {
174 panic("Failed to open file inside zip")
175 }
176 body, err := ioutil.ReadAll(reader)
177 if err != nil {
178 panic("Failed to read zipped file")
179 }
180 files[i] = zippedFile{
181 name: zf.Name,
182 size: zf.FileHeader.UncompressedSize64,
183 mode: zf.Mode(),
184 body: body,
185 }
186 }
187 return files
188 }
189
190 ////////////////////////////////////////////////////////////////////////////////
191
192 type testFile struct {
193 name string
194 data string
195 executable bool
196 symlinkTarget string
197 }
198
199 func (f *testFile) Name() string { return f.name }
200 func (f *testFile) Size() uint64 { return uint64(len(f.data)) }
201 func (f *testFile) Executable() bool { return f.executable }
202 func (f *testFile) Symlink() bool { return f.symlinkTarget != "" }
203
204 func (f *testFile) SymlinkTarget() (string, error) {
205 if f.symlinkTarget == "" {
206 return "", fmt.Errorf("Not a symlink: %s", f.Name())
207 }
208 return f.symlinkTarget, nil
209 }
210
211 func (f *testFile) Open() (io.ReadCloser, error) {
212 if f.Symlink() {
213 return nil, fmt.Errorf("Can't open symlink: %s", f.Name())
214 }
215 r := bytes.NewReader([]byte(f.data))
216 return ioutil.NopCloser(r), nil
217 }
218
219 func makeTestFile(name string, data string, executable bool) File {
220 return &testFile{
221 name: name,
222 data: data,
223 executable: executable,
224 }
225 }
226
227 func makeTestSymlink(name string, target string) File {
228 return &testFile{
229 name: name,
230 symlinkTarget: target,
231 }
232 }
OLDNEW
« no previous file with comments | « go/src/infra/tools/cipd/builder.go ('k') | go/src/infra/tools/cipd/client.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698