OLD | NEW |
| (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 "bytes" | |
9 "io/ioutil" | |
10 "net/url" | |
11 "os" | |
12 "path/filepath" | |
13 "testing" | |
14 "time" | |
15 | |
16 . "github.com/smartystreets/goconvey/convey" | |
17 ) | |
18 | |
19 func TestFetchInstance(t *testing.T) { | |
20 Convey("Mocking remote service", t, func() { | |
21 tempDir, err := ioutil.TempDir("", "cipd_test") | |
22 So(err, ShouldBeNil) | |
23 Reset(func() { os.RemoveAll(tempDir) }) | |
24 tempFile := filepath.Join(tempDir, "pkg") | |
25 | |
26 mockClock(time.Now()) | |
27 mockResumableUpload() | |
28 | |
29 Convey("FetchInstance full flow", func() { | |
30 inst := buildInstanceInMemory("pkgname", nil) | |
31 defer inst.Close() | |
32 service := mockFetchBackend([]PackageInstance{inst}) | |
33 | |
34 out, err := os.OpenFile(tempFile, os.O_WRONLY|os.O_CREAT
E, 0666) | |
35 So(err, ShouldBeNil) | |
36 closed := false | |
37 defer func() { | |
38 if !closed { | |
39 out.Close() | |
40 } | |
41 }() | |
42 | |
43 err = FetchInstance(FetchInstanceOptions{ | |
44 Client: service.client, | |
45 Output: out, | |
46 PackageName: inst.PackageName(), | |
47 InstanceID: inst.InstanceID(), | |
48 }) | |
49 So(err, ShouldBeNil) | |
50 out.Close() | |
51 closed = true | |
52 | |
53 fetched, err := OpenInstanceFile(tempFile, "") | |
54 So(err, ShouldBeNil) | |
55 So(fetched.PackageName(), ShouldEqual, inst.PackageName(
)) | |
56 So(fetched.InstanceID(), ShouldEqual, inst.InstanceID()) | |
57 }) | |
58 }) | |
59 } | |
60 | |
61 func TestFetchAndDeployInstance(t *testing.T) { | |
62 Convey("Mocking temp dir", t, func() { | |
63 tempDir, err := ioutil.TempDir("", "cipd_test") | |
64 So(err, ShouldBeNil) | |
65 Reset(func() { os.RemoveAll(tempDir) }) | |
66 | |
67 mockClock(time.Now()) | |
68 mockResumableUpload() | |
69 | |
70 Convey("FetchAndDeployInstance full flow", func() { | |
71 // Build a package instance with some file. | |
72 inst := buildInstanceInMemory("testing/package", []File{ | |
73 makeTestFile("file", "test data", false), | |
74 }) | |
75 defer inst.Close() | |
76 service := mockFetchBackend([]PackageInstance{inst}) | |
77 | |
78 // Install the package, fetching it from the fake server
. | |
79 err = FetchAndDeployInstance(tempDir, FetchInstanceOptio
ns{ | |
80 Client: service.client, | |
81 PackageName: inst.PackageName(), | |
82 InstanceID: inst.InstanceID(), | |
83 }) | |
84 So(err, ShouldBeNil) | |
85 | |
86 // The file from the package should be installed. | |
87 data, err := ioutil.ReadFile(filepath.Join(tempDir, "fil
e")) | |
88 So(err, ShouldBeNil) | |
89 So(data, ShouldResemble, []byte("test data")) | |
90 }) | |
91 }) | |
92 } | |
93 | |
94 // buildInstanceInMemory makes fully functional PackageInstance object that uses | |
95 // memory buffer as a backing store. | |
96 func buildInstanceInMemory(pkgName string, files []File) PackageInstance { | |
97 out := bytes.Buffer{} | |
98 err := BuildInstance(BuildInstanceOptions{ | |
99 Input: files, | |
100 Output: &out, | |
101 PackageName: pkgName, | |
102 }) | |
103 So(err, ShouldBeNil) | |
104 inst, err := OpenInstance(bytes.NewReader(out.Bytes()), "") | |
105 So(err, ShouldBeNil) | |
106 return inst | |
107 } | |
108 | |
109 // mockFetchBackend returns remoteService that can be used by FetchInstance | |
110 // to download the package file (or multiple files). | |
111 func mockFetchBackend(instances []PackageInstance) *remoteService { | |
112 var readData = func(i PackageInstance) string { | |
113 r := i.DataReader() | |
114 _, err := r.Seek(0, os.SEEK_SET) | |
115 if err != nil { | |
116 panic(err) | |
117 } | |
118 data, err := ioutil.ReadAll(r) | |
119 if err != nil { | |
120 panic(err) | |
121 } | |
122 return string(data) | |
123 } | |
124 allCalls := []expectedHTTPCall{} | |
125 for _, inst := range instances { | |
126 instCalls := []expectedHTTPCall{ | |
127 expectedHTTPCall{ | |
128 Method: "GET", | |
129 Path: "/_ah/api/repo/v1/instance", | |
130 Query: url.Values{ | |
131 "instance_id": []string{inst.InstanceID
()}, | |
132 "package_name": []string{inst.PackageNam
e()}, | |
133 }, | |
134 Reply: `{ | |
135 "status": "SUCCESS", | |
136 "instance": { | |
137 "registered_by": "user:a@example.com", | |
138 "registered_ts": "0" | |
139 }, | |
140 "fetch_url": "http://localhost/fake_fetch_url" | |
141 }`, | |
142 }, | |
143 // Simulate a transient error. | |
144 expectedHTTPCall{ | |
145 Method: "GET", | |
146 Path: "/fake_fetch_url", | |
147 Status: 500, | |
148 Reply: "error", | |
149 }, | |
150 expectedHTTPCall{ | |
151 Method: "GET", | |
152 Path: "/fake_fetch_url", | |
153 Status: 200, | |
154 Reply: readData(inst), | |
155 }, | |
156 } | |
157 allCalls = append(allCalls, instCalls...) | |
158 } | |
159 return mockRemoteServiceWithExpectations(allCalls) | |
160 } | |
OLD | NEW |