~ubuntu-branches/ubuntu/saucy/juju-core/saucy-proposed

« back to all changes in this revision

Viewing changes to src/launchpad.net/juju-core/environs/azure/storage_test.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-07-11 17:18:27 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20130711171827-vjqkg40r0dlf7ys2
Tags: 1.11.2-0ubuntu1
* New upstream release.
* Make juju-core the default juju (LP: #1190634):
  - d/control: Add virtual package juju -> juju-core.
  - d/juju-core.postinst.in: Bump priority of alternatives over that of
    python juju packages.
* Enable for all architectures (LP: #1172505):
  - d/control: Version BD on golang-go to >= 2:1.1.1 to ensure CGO
    support for non-x86 archs, make juju-core Arch: any.
  - d/README.source: Dropped - no longer required.
* d/watch: Updated for new upstream tarball naming.

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 azure
 
5
 
 
6
import (
 
7
        "fmt"
 
8
        "io/ioutil"
 
9
        . "launchpad.net/gocheck"
 
10
        "launchpad.net/gwacl"
 
11
        "launchpad.net/juju-core/errors"
 
12
        "net/http"
 
13
        "strings"
 
14
)
 
15
 
 
16
type StorageSuite struct {
 
17
        ProviderSuite
 
18
}
 
19
 
 
20
var _ = Suite(new(StorageSuite))
 
21
 
 
22
// TestTransport is used as an http.Client.Transport for testing.  It records
 
23
// the latest request, and returns a predetermined Response and error.
 
24
type TestTransport struct {
 
25
        Request  *http.Request
 
26
        Response *http.Response
 
27
        Error    error
 
28
}
 
29
 
 
30
func (t *TestTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
 
31
        t.Request = req
 
32
        return t.Response, t.Error
 
33
}
 
34
 
 
35
func makeResponse(content string, status int) *http.Response {
 
36
        return &http.Response{
 
37
                Status:     fmt.Sprintf("%d", status),
 
38
                StatusCode: status,
 
39
                Body:       ioutil.NopCloser(strings.NewReader(content)),
 
40
        }
 
41
}
 
42
 
 
43
// testStorageContext is a struct implementing the storageContext interface
 
44
// used in test.  It will return, via getContainer() and getStorageContext()
 
45
// the objects used at creation time.
 
46
type testStorageContext struct {
 
47
        container      string
 
48
        storageContext *gwacl.StorageContext
 
49
}
 
50
 
 
51
func (context *testStorageContext) getContainer() string {
 
52
        return context.container
 
53
}
 
54
 
 
55
func (context *testStorageContext) getStorageContext() (*gwacl.StorageContext, error) {
 
56
        return context.storageContext, nil
 
57
}
 
58
 
 
59
// makeAzureStorage creates a test azureStorage object that will talk to a
 
60
// fake http server set up to always return the given http.Response object.
 
61
// makeAzureStorage returns an azureStorage object and a TestTransport object.
 
62
// The TestTransport object can be used to check that the expected query has
 
63
// been issued to the test server.
 
64
func makeAzureStorage(response *http.Response, container string, account string) (azureStorage, *TestTransport) {
 
65
        transport := &TestTransport{Response: response}
 
66
        client := &http.Client{Transport: transport}
 
67
        storageContext := gwacl.NewTestStorageContext(client)
 
68
        storageContext.Account = account
 
69
        context := &testStorageContext{container: container, storageContext: storageContext}
 
70
        azStorage := azureStorage{context}
 
71
        return azStorage, transport
 
72
}
 
73
 
 
74
var blobListResponse = `
 
75
  <?xml version="1.0" encoding="utf-8"?>
 
76
  <EnumerationResults ContainerName="http://myaccount.blob.core.windows.net/mycontainer">
 
77
    <Prefix>prefix</Prefix>
 
78
    <Marker>marker</Marker>
 
79
    <MaxResults>maxresults</MaxResults>
 
80
    <Delimiter>delimiter</Delimiter>
 
81
    <Blobs>
 
82
      <Blob>
 
83
        <Name>prefix-1</Name>
 
84
        <Url>blob-url1</Url>
 
85
      </Blob>
 
86
      <Blob>
 
87
        <Name>prefix-2</Name>
 
88
        <Url>blob-url2</Url>
 
89
      </Blob>
 
90
    </Blobs>
 
91
    <NextMarker />
 
92
  </EnumerationResults>`
 
93
 
 
94
func (StorageSuite) TestList(c *C) {
 
95
        container := "container"
 
96
        response := makeResponse(blobListResponse, http.StatusOK)
 
97
        azStorage, transport := makeAzureStorage(response, container, "account")
 
98
        prefix := "prefix"
 
99
        names, err := azStorage.List(prefix)
 
100
        c.Assert(err, IsNil)
 
101
        // The prefix has been passed down as a query parameter.
 
102
        c.Check(transport.Request.URL.Query()["prefix"], DeepEquals, []string{prefix})
 
103
        // The container name is used in the requested URL.
 
104
        c.Check(transport.Request.URL.String(), Matches, ".*"+container+".*")
 
105
        c.Check(names, DeepEquals, []string{"prefix-1", "prefix-2"})
 
106
}
 
107
 
 
108
func (StorageSuite) TestGet(c *C) {
 
109
        blobContent := "test blob"
 
110
        container := "container"
 
111
        filename := "blobname"
 
112
        response := makeResponse(blobContent, http.StatusOK)
 
113
        azStorage, transport := makeAzureStorage(response, container, "account")
 
114
        reader, err := azStorage.Get(filename)
 
115
        c.Assert(err, IsNil)
 
116
        c.Assert(reader, NotNil)
 
117
        defer reader.Close()
 
118
 
 
119
        context, err := azStorage.getStorageContext()
 
120
        c.Assert(err, IsNil)
 
121
        c.Check(transport.Request.URL.String(), Matches, context.GetFileURL(container, filename)+"?.*")
 
122
        data, err := ioutil.ReadAll(reader)
 
123
        c.Assert(err, IsNil)
 
124
        c.Check(string(data), Equals, blobContent)
 
125
}
 
126
 
 
127
func (StorageSuite) TestGetReturnsNotFoundIf404(c *C) {
 
128
        container := "container"
 
129
        filename := "blobname"
 
130
        response := makeResponse("not found", http.StatusNotFound)
 
131
        azStorage, _ := makeAzureStorage(response, container, "account")
 
132
        _, err := azStorage.Get(filename)
 
133
        c.Assert(err, NotNil)
 
134
        c.Check(errors.IsNotFoundError(err), Equals, true)
 
135
}
 
136
 
 
137
func (StorageSuite) TestPut(c *C) {
 
138
        blobContent := "test blob"
 
139
        container := "container"
 
140
        filename := "blobname"
 
141
        response := makeResponse("", http.StatusCreated)
 
142
        azStorage, transport := makeAzureStorage(response, container, "account")
 
143
        err := azStorage.Put(filename, strings.NewReader(blobContent), int64(len(blobContent)))
 
144
        c.Assert(err, IsNil)
 
145
 
 
146
        context, err := azStorage.getStorageContext()
 
147
        c.Assert(err, IsNil)
 
148
        c.Check(transport.Request.URL.String(), Matches, context.GetFileURL(container, filename)+"?.*")
 
149
}
 
150
 
 
151
func (StorageSuite) TestRemove(c *C) {
 
152
        container := "container"
 
153
        filename := "blobname"
 
154
        response := makeResponse("", http.StatusAccepted)
 
155
        azStorage, transport := makeAzureStorage(response, container, "account")
 
156
        err := azStorage.Remove(filename)
 
157
        c.Assert(err, IsNil)
 
158
 
 
159
        context, err := azStorage.getStorageContext()
 
160
        c.Assert(err, IsNil)
 
161
        c.Check(transport.Request.URL.String(), Matches, context.GetFileURL(container, filename)+"?.*")
 
162
        c.Check(transport.Request.Method, Equals, "DELETE")
 
163
}
 
164
 
 
165
func (StorageSuite) TestRemoveErrors(c *C) {
 
166
        container := "container"
 
167
        filename := "blobname"
 
168
        response := makeResponse("", http.StatusForbidden)
 
169
        azStorage, _ := makeAzureStorage(response, container, "account")
 
170
        err := azStorage.Remove(filename)
 
171
        c.Assert(err, NotNil)
 
172
}
 
173
 
 
174
func (StorageSuite) TestRemoveNonExistantBlobSucceeds(c *C) {
 
175
        container := "container"
 
176
        filename := "blobname"
 
177
        response := makeResponse("", http.StatusNotFound)
 
178
        azStorage, _ := makeAzureStorage(response, container, "account")
 
179
        err := azStorage.Remove(filename)
 
180
        c.Assert(err, IsNil)
 
181
}
 
182
 
 
183
func (StorageSuite) TestURL(c *C) {
 
184
        container := "container"
 
185
        filename := "blobname"
 
186
        account := "account"
 
187
        azStorage, _ := makeAzureStorage(nil, container, account)
 
188
        URL, err := azStorage.URL(filename)
 
189
        c.Assert(err, IsNil)
 
190
        c.Check(URL, Matches, fmt.Sprintf("http://%s.blob.core.windows.net/%s/%s", account, container, filename))
 
191
}