Merge lp:~allenap/gwacl/storage-get-blob into lp:gwacl

Proposed by Gavin Panella
Status: Merged
Approved by: Gavin Panella
Approved revision: 56
Merged at revision: 56
Proposed branch: lp:~allenap/gwacl/storage-get-blob
Merge into: lp:gwacl
Diff against target: 91 lines (+76/-0)
2 files modified
storage.go (+20/-0)
storage_test.go (+56/-0)
To merge this branch: bzr merge lp:~allenap/gwacl/storage-get-blob
Reviewer Review Type Date Requested Status
Julian Edwards (community) Approve
Review via email: mp+154867@code.launchpad.net

Commit message

New Storage API operation to get a blob.

To post a comment you must log in.
Revision history for this message
Julian Edwards (julian-edwards) :
review: Approve
lp:~allenap/gwacl/storage-get-blob updated
56. By Gavin Panella

Assert instead of Check that the reader is not nil.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'storage.go'
2--- storage.go 2013-03-22 06:34:24 +0000
3+++ storage.go 2013-03-22 06:54:19 +0000
4@@ -421,3 +421,23 @@
5 }
6 return nil
7 }
8+
9+// Get the specified blob from the given container.
10+func (context *StorageContext) GetBlob(container, filename string) (io.ReadCloser, error) {
11+ uri := fmt.Sprintf(
12+ "http://%s.blob.core.windows.net/%s/%s",
13+ context.Account, container, filename)
14+ req, err := http.NewRequest("GET", uri, nil)
15+ if err != nil {
16+ return nil, err
17+ }
18+ addStandardHeaders(req, context.Account, context.Key, "2012-02-12")
19+ resp, err := context.send(req, nil)
20+ if err != nil {
21+ return nil, err
22+ }
23+ if resp.StatusCode != http.StatusOK {
24+ return nil, fmt.Errorf("failed to get blob: %s", resp.Status)
25+ }
26+ return resp.Body, nil
27+}
28
29=== modified file 'storage_test.go'
30--- storage_test.go 2013-03-22 06:34:24 +0000
31+++ storage_test.go 2013-03-22 06:54:19 +0000
32@@ -768,3 +768,59 @@
33 err := context.DeleteBlob("container", "blobname")
34 c.Assert(err.Error(), Equals, "failed to delete blob: 246 Frotzed")
35 }
36+
37+type TestGetBlob struct{}
38+
39+var _ = Suite(&TestGetBlob{})
40+
41+func (suite *TestGetBlob) Test(c *C) {
42+ context := makeStorageContext()
43+ response_body := "blob-in-a-can"
44+ response := &http.Response{
45+ Status: fmt.Sprintf("%d", http.StatusOK),
46+ StatusCode: http.StatusOK,
47+ Body: ioutil.NopCloser(strings.NewReader(response_body)),
48+ }
49+ transport := &TestTransport{Response: response}
50+ context.client = &http.Client{Transport: transport}
51+ reader, err := context.GetBlob("container", "blobname")
52+ c.Assert(reader, NotNil)
53+ defer reader.Close()
54+ c.Assert(err, IsNil)
55+
56+ c.Check(transport.Request.Method, Equals, "GET")
57+ c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(
58+ "http://%s.blob.core.windows.net/container/blobname",
59+ context.Account))
60+ c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")
61+
62+ data, err := ioutil.ReadAll(reader)
63+ c.Assert(err, IsNil)
64+ c.Check(string(data), Equals, response_body)
65+}
66+
67+// Client-side errors from the HTTP client are propagated back to the caller.
68+func (suite *TestGetBlob) TestError(c *C) {
69+ error := fmt.Errorf("canned-error")
70+ transport := &TestTransport{Error: error}
71+ context := makeStorageContext()
72+ context.client = &http.Client{Transport: transport}
73+ reader, err := context.GetBlob("container", "blobname")
74+ c.Check(reader, IsNil)
75+ c.Assert(err, NotNil)
76+}
77+
78+// Server-side errors are propagated back to the caller.
79+func (suite *TestGetBlob) TestErrorResponse(c *C) {
80+ response := &http.Response{
81+ Status: "246 Frotzed",
82+ StatusCode: 246,
83+ }
84+ transport := &TestTransport{Response: response}
85+ context := makeStorageContext()
86+ context.client = &http.Client{Transport: transport}
87+ reader, err := context.GetBlob("container", "blobname")
88+ c.Check(reader, IsNil)
89+ c.Assert(err, NotNil)
90+ c.Assert(err.Error(), Equals, "failed to get blob: 246 Frotzed")
91+}

Subscribers

People subscribed via source and target branches

to all changes: