Merge lp:~jtv/gwacl/require-storage-location into lp:gwacl

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: 218
Merged at revision: 215
Proposed branch: lp:~jtv/gwacl/require-storage-location
Merge into: lp:gwacl
Diff against target: 334 lines (+73/-48)
5 files modified
helpers_http_test.go (+3/-2)
storage_base.go (+5/-14)
storage_base_test.go (+44/-16)
storage_test.go (+20/-16)
testing_test.go (+1/-0)
To merge this branch: bzr merge lp:~jtv/gwacl/require-storage-location
Reviewer Review Type Date Requested Status
Julian Edwards (community) Approve
Review via email: mp+178721@code.launchpad.net

Commit message

Make StorageContext.AzureEndpoint required.

Description of the change

Unfortunately, making this required is a runtime-incompatible API change. That is, client code that fails to provide it will still compile but it will panic at run time.

There was a lot of collateral damage, as expected. In particular, two storage tests relied on some arbitrary hard-coded names (not even mentioned in the tests themselves!) being identical between various helper functions. Luckily it wasn't hard to clean this up a bit. The tests themselves are now the only source of those arbitrary strings.

The test-helper factory for storage contexts sets an "unguessable" AzureEndpoint by default, so that we don't accidentally rely on such implicit connections here. Tests that need a known string, have to set one. As per the normal policy I used example.com, except of course in the tests for the functions that actually generate those strings. Those are already acceptance-tested against the real-world URLs, although it probably won't show up in the diff here.

Jeroen

To post a comment you must log in.
Revision history for this message
Julian Edwards (julian-edwards) wrote :

Looks great! Good testing as always from you.

8 - Account: MakeRandomString(10),
9 - Key: base64.StdEncoding.EncodeToString(MakeRandomByteSlice(10)),
10 + Account: MakeRandomString(10),
11 + Key: base64.StdEncoding.EncodeToString(MakeRandomByteSlice(10)),
12 + AzureEndpoint: APIEndpoint("http://" + MakeRandomString(5) + ".example.com/"),

I'd like to just take a moment to bitch at gofmt for changing lines completely unrelated to the diff at hand. >:(

44 + if context.AzureEndpoint == APIEndpoint("") {
45 + panic(errors.New("no Azure blob storage endpoint specified"))

Can you mention the parameter by name please, it will save a confused developer from hunting down this line of source.

review: Approve
218. By Jeroen T. Vermeulen

Name AzureEndpoint in panic text.

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Collateral damage is a recurring problem in Go.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'helpers_http_test.go'
--- helpers_http_test.go 2013-07-08 10:03:48 +0000
+++ helpers_http_test.go 2013-08-07 02:15:36 +0000
@@ -50,8 +50,9 @@
50// random base64-encoded key.50// random base64-encoded key.
51func makeStorageContext(transport http.RoundTripper) *StorageContext {51func makeStorageContext(transport http.RoundTripper) *StorageContext {
52 context := &StorageContext{52 context := &StorageContext{
53 Account: MakeRandomString(10),53 Account: MakeRandomString(10),
54 Key: base64.StdEncoding.EncodeToString(MakeRandomByteSlice(10)),54 Key: base64.StdEncoding.EncodeToString(MakeRandomByteSlice(10)),
55 AzureEndpoint: APIEndpoint("http://" + MakeRandomString(5) + ".example.com/"),
55 }56 }
56 context.client = &http.Client{Transport: transport}57 context.client = &http.Client{Transport: transport}
57 return context58 return context
5859
=== modified file 'storage_base.go'
--- storage_base.go 2013-08-06 10:15:28 +0000
+++ storage_base.go 2013-08-07 02:15:36 +0000
@@ -210,12 +210,7 @@
210 Key string210 Key string
211211
212 // AzureEndpoint specifies a base service endpoint URL for the Azure APIs.212 // AzureEndpoint specifies a base service endpoint URL for the Azure APIs.
213 // If this is not set, it will default to the international endpoint which213 // This field is required.
214 // will not work in mainland China.
215 //
216 // Try to set this if at all possible. Use GetEndpoint() to obtain the
217 // endpoint associated with a given service location, e.g. "West US" or
218 // "North Europe" or "East China".
219 AzureEndpoint APIEndpoint214 AzureEndpoint APIEndpoint
220215
221 client *http.Client216 client *http.Client
@@ -334,20 +329,16 @@
334// getAccountURL returns the base URL for the context's storage account.329// getAccountURL returns the base URL for the context's storage account.
335// (The result ends in a slash.)330// (The result ends in a slash.)
336func (context *StorageContext) getAccountURL() string {331func (context *StorageContext) getAccountURL() string {
337 endpoint := context.AzureEndpoint332 if context.AzureEndpoint == APIEndpoint("") {
338 if endpoint == "" {333 panic(errors.New("no AzureEndpoint specified in gwacl.StorageContext"))
339 // No API endpoint specified. Default to the international one.
340 // This will not work for mainland China.
341 // TODO: Make this required, and panic() instead.
342 endpoint = GetEndpoint("West US")
343 }334 }
344 return endpoint.BlobStorageAPI(context.Account)335 return context.AzureEndpoint.BlobStorageAPI(context.Account)
345}336}
346337
347// getContainerURL returns the URL for a given storage container.338// getContainerURL returns the URL for a given storage container.
348// (The result does not end in a slash.)339// (The result does not end in a slash.)
349func (context *StorageContext) getContainerURL(container string) string {340func (context *StorageContext) getContainerURL(container string) string {
350 return context.getAccountURL() + url.QueryEscape(container)341 return strings.TrimRight(context.getAccountURL(), "/") + "/" + url.QueryEscape(container)
351}342}
352343
353// GetFileURL returns the URL for a given file in the given container.344// GetFileURL returns the URL for a given file in the given container.
354345
=== modified file 'storage_base_test.go'
--- storage_base_test.go 2013-08-06 04:53:38 +0000
+++ storage_base_test.go 2013-08-07 02:15:36 +0000
@@ -6,6 +6,7 @@
6import (6import (
7 "bytes"7 "bytes"
8 "encoding/base64"8 "encoding/base64"
9 "errors"
9 "fmt"10 "fmt"
10 "io/ioutil"11 "io/ioutil"
11 . "launchpad.net/gocheck"12 . "launchpad.net/gocheck"
@@ -309,33 +310,50 @@
309 "http://"+url.QueryEscape(account)+".blob.example.com")310 "http://"+url.QueryEscape(account)+".blob.example.com")
310}311}
311312
312func (*TestStorageContext) TestGetAccountURLDefaultsToInternationalEndpoint(c *C) {313func (*TestStorageContext) TestGetAccountURLRequiresEndpoint(c *C) {
313 context := StorageContext{Account: "myaccount"}314 context := StorageContext{Account: "myaccount"}
314 c.Check(315 c.Check(
315 context.getAccountURL(),316 context.getAccountURL,
316 Equals,317 Panics,
317 "https://myaccount.blob.core.windows.net/")318 errors.New("no AzureEndpoint specified in gwacl.StorageContext"))
318}319}
319320
320func (suite *TestStorageContext) TestGetContainerURL(c *C) {321func (suite *TestStorageContext) TestGetContainerURLAddsContainer(c *C) {
321 account := makeNastyURLUnfriendlyString()322 account := makeNastyURLUnfriendlyString()
322 container := makeNastyURLUnfriendlyString()323 container := makeNastyURLUnfriendlyString()
323 context := StorageContext{Account: account}324 context := StorageContext{
325 Account: account,
326 AzureEndpoint: "http://example.com/",
327 }
324 c.Check(328 c.Check(
325 context.getContainerURL(container),329 context.getContainerURL(container),
326 Equals,330 Equals,
327 "https://"+url.QueryEscape(account)+".blob.core.windows.net/"+url.QueryEscape(container))331 "http://"+url.QueryEscape(account)+".blob.example.com/"+url.QueryEscape(container))
332}
333
334func (suite *TestStorageContext) TestGetContainerURLAddsSlashIfNeeded(c *C) {
335 context := StorageContext{
336 Account: "account",
337 AzureEndpoint: "http://example.com",
338 }
339 c.Check(
340 context.getContainerURL("container"),
341 Equals,
342 "http://account.blob.example.com/container")
328}343}
329344
330func (suite *TestStorageContext) TestGetFileURL(c *C) {345func (suite *TestStorageContext) TestGetFileURL(c *C) {
331 account := makeNastyURLUnfriendlyString()346 account := makeNastyURLUnfriendlyString()
332 container := makeNastyURLUnfriendlyString()347 container := makeNastyURLUnfriendlyString()
333 file := makeNastyURLUnfriendlyString()348 file := makeNastyURLUnfriendlyString()
334 context := StorageContext{Account: account}349 context := StorageContext{
350 Account: account,
351 AzureEndpoint: "http://example.com/",
352 }
335 c.Check(353 c.Check(
336 context.GetFileURL(container, file),354 context.GetFileURL(container, file),
337 Equals,355 Equals,
338 "https://"+url.QueryEscape(account)+".blob.core.windows.net/"+url.QueryEscape(container)+"/"+url.QueryEscape(file))356 "http://"+url.QueryEscape(account)+".blob.example.com/"+url.QueryEscape(container)+"/"+url.QueryEscape(file))
339}357}
340358
341func (suite *TestStorageContext) TestGetSignedFileURL(c *C) {359func (suite *TestStorageContext) TestGetSignedFileURL(c *C) {
@@ -343,7 +361,11 @@
343 container := "container"361 container := "container"
344 file := "/a/file"362 file := "/a/file"
345 key := base64.StdEncoding.EncodeToString([]byte("dummykey"))363 key := base64.StdEncoding.EncodeToString([]byte("dummykey"))
346 context := StorageContext{Account: account, Key: key}364 context := StorageContext{
365 Account: account,
366 Key: key,
367 AzureEndpoint: "http://example.com/",
368 }
347 expires := time.Now()369 expires := time.Now()
348370
349 signedURL := context.GetAnonymousFileURL(container, file, expires)371 signedURL := context.GetAnonymousFileURL(container, file, expires)
@@ -408,11 +430,12 @@
408 response := makeHttpResponse(http.StatusOK, responseBody)430 response := makeHttpResponse(http.StatusOK, responseBody)
409 transport := &TestTransport{Response: response}431 transport := &TestTransport{Response: response}
410 context := makeStorageContext(transport)432 context := makeStorageContext(transport)
433 context.AzureEndpoint = "http://example.com/"
411 request := &ListContainersRequest{Marker: ""}434 request := &ListContainersRequest{Marker: ""}
412 results, err := context.ListContainers(request)435 results, err := context.ListContainers(request)
413 c.Assert(err, IsNil)436 c.Assert(err, IsNil)
414 c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(437 c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(
415 "https://%s.blob.core.windows.net/?comp=list", context.Account))438 "http://%s.blob.example.com/?comp=list", context.Account))
416 c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")439 c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")
417 c.Assert(results, NotNil)440 c.Assert(results, NotNil)
418 c.Assert(results.Containers[0].Name, Equals, "name-value")441 c.Assert(results.Containers[0].Name, Equals, "name-value")
@@ -666,11 +689,12 @@
666 response := makeHttpResponse(http.StatusCreated, "")689 response := makeHttpResponse(http.StatusCreated, "")
667 transport := &TestTransport{Response: response}690 transport := &TestTransport{Response: response}
668 context := makeStorageContext(transport)691 context := makeStorageContext(transport)
692 context.AzureEndpoint = "http://example.com/"
669 containerName := MakeRandomString(10)693 containerName := MakeRandomString(10)
670 err := context.CreateContainer(containerName)694 err := context.CreateContainer(containerName)
671 c.Assert(err, IsNil)695 c.Assert(err, IsNil)
672 c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(696 c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(
673 "https://%s.blob.core.windows.net/%s?restype=container",697 "http://%s.blob.example.com/%s?restype=container",
674 context.Account, containerName))698 context.Account, containerName))
675 c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")699 c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")
676}700}
@@ -720,11 +744,12 @@
720 response := makeHttpResponse(http.StatusAccepted, "")744 response := makeHttpResponse(http.StatusAccepted, "")
721 transport := &TestTransport{Response: response}745 transport := &TestTransport{Response: response}
722 context := makeStorageContext(transport)746 context := makeStorageContext(transport)
747 context.AzureEndpoint = "http://example.com/"
723 containerName := MakeRandomString(10)748 containerName := MakeRandomString(10)
724 err := context.DeleteContainer(containerName)749 err := context.DeleteContainer(containerName)
725 c.Assert(err, IsNil)750 c.Assert(err, IsNil)
726 c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(751 c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(
727 "https://%s.blob.core.windows.net/%s?restype=container",752 "http://%s.blob.example.com/%s?restype=container",
728 context.Account, containerName))753 context.Account, containerName))
729 c.Check(transport.Request.Method, Equals, "DELETE")754 c.Check(transport.Request.Method, Equals, "DELETE")
730 c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")755 c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")
@@ -786,11 +811,12 @@
786811
787 transport := &TestTransport{Response: response}812 transport := &TestTransport{Response: response}
788 context := makeStorageContext(transport)813 context := makeStorageContext(transport)
814 context.AzureEndpoint = "http://example.com/"
789 containerName := MakeRandomString(10)815 containerName := MakeRandomString(10)
790 props, err := context.GetContainerProperties(containerName)816 props, err := context.GetContainerProperties(containerName)
791 c.Assert(err, IsNil)817 c.Assert(err, IsNil)
792 c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(818 c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(
793 "https://%s.blob.core.windows.net/%s?restype=container",819 "http://%s.blob.example.com/%s?restype=container",
794 context.Account, containerName))820 context.Account, containerName))
795 c.Check(transport.Request.Method, Equals, "GET")821 c.Check(transport.Request.Method, Equals, "GET")
796 c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")822 c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")
@@ -1099,6 +1125,7 @@
1099 response := makeHttpResponse(http.StatusCreated, "")1125 response := makeHttpResponse(http.StatusCreated, "")
1100 transport := &TestTransport{Response: response}1126 transport := &TestTransport{Response: response}
1101 context := makeStorageContext(transport)1127 context := makeStorageContext(transport)
1128 context.AzureEndpoint = "http://example.com/"
1102 blocklist := &BlockList{}1129 blocklist := &BlockList{}
1103 blocklist.Add(BlockListLatest, "b1")1130 blocklist.Add(BlockListLatest, "b1")
1104 blocklist.Add(BlockListLatest, "b2")1131 blocklist.Add(BlockListLatest, "b2")
@@ -1107,7 +1134,7 @@
11071134
1108 c.Check(transport.Request.Method, Equals, "PUT")1135 c.Check(transport.Request.Method, Equals, "PUT")
1109 c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(1136 c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(
1110 "https://%s.blob.core.windows.net/container/blobname?comp=blocklist",1137 "http://%s.blob.example.com/container/blobname?comp=blocklist",
1111 context.Account))1138 context.Account))
1112 c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")1139 c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")
11131140
@@ -1340,6 +1367,7 @@
1340 response := makeHttpResponse(http.StatusOK, "")1367 response := makeHttpResponse(http.StatusOK, "")
1341 transport := &TestTransport{Response: response}1368 transport := &TestTransport{Response: response}
1342 context := makeStorageContext(transport)1369 context := makeStorageContext(transport)
1370 context.AzureEndpoint = "http://example.com/"
1343 err := context.SetContainerACL(&SetContainerACLRequest{1371 err := context.SetContainerACL(&SetContainerACLRequest{
1344 Container: "mycontainer", Access: "container"})1372 Container: "mycontainer", Access: "container"})
13451373
@@ -1347,7 +1375,7 @@
1347 c.Check(transport.Request.Method, Equals, "PUT")1375 c.Check(transport.Request.Method, Equals, "PUT")
1348 c.Check(transport.Request.URL.String(), Matches,1376 c.Check(transport.Request.URL.String(), Matches,
1349 fmt.Sprintf(1377 fmt.Sprintf(
1350 "https://%s.blob.core.windows.net/mycontainer?.*", context.Account))1378 "http://%s.blob.example.com/mycontainer?.*", context.Account))
1351 c.Check(transport.Request.URL.Query(), DeepEquals, url.Values{1379 c.Check(transport.Request.URL.Query(), DeepEquals, url.Values{
1352 "comp": {"acl"},1380 "comp": {"acl"},
1353 "restype": {"container"},1381 "restype": {"container"},
13541382
=== modified file 'storage_test.go'
--- storage_test.go 2013-08-05 12:01:32 +0000
+++ storage_test.go 2013-08-07 02:15:36 +0000
@@ -26,13 +26,14 @@
26 // UploadBlockBlob then sends the list of blocks with PutBlockList.26 // UploadBlockBlob then sends the list of blocks with PutBlockList.
27 transport.AddExchange(makeFakeCreatedResponse(), nil)27 transport.AddExchange(makeFakeCreatedResponse(), nil)
28 // Upload a random blob of data.28 // Upload a random blob of data.
29 data := uploadRandomBlob(c, context, 10)29 data := uploadRandomBlob(c, context, 10, "MyContainer", "MyFile")
30 // There were two exchanges.30 // There were two exchanges.
31 c.Assert(transport.ExchangeCount, Equals, 2)31 c.Assert(transport.ExchangeCount, Equals, 2)
32 // The first request is a Put Block with the block data.32 // The first request is a Put Block with the block data.
33 assertBlockSent(c, context, data, b64("000000000000000000000000000000"), transport.Exchanges[0])33 fileURL := context.GetFileURL("MyContainer", "MyFile")
34 assertBlockSent(c, context, data, b64("000000000000000000000000000000"), transport.Exchanges[0], fileURL)
34 // The second request is Put Block List to commit the block above.35 // The second request is Put Block List to commit the block above.
35 assertBlockListSent(c, context, []string{b64("000000000000000000000000000000")}, transport.Exchanges[1])36 assertBlockListSent(c, context, []string{b64("000000000000000000000000000000")}, transport.Exchanges[1], fileURL)
36}37}
3738
38func (suite *testUploadBlockBlob) TestLargeFile(c *C) {39func (suite *testUploadBlockBlob) TestLargeFile(c *C) {
@@ -44,28 +45,29 @@
44 // UploadBlockBlob then sends the list of blocks with PutBlockList.45 // UploadBlockBlob then sends the list of blocks with PutBlockList.
45 transport.AddExchange(makeFakeCreatedResponse(), nil)46 transport.AddExchange(makeFakeCreatedResponse(), nil)
46 // Upload a large random blob of data.47 // Upload a large random blob of data.
47 data := uploadRandomBlob(c, context, 1348*1024)48 data := uploadRandomBlob(c, context, 1348*1024, "MyContainer", "MyFile")
48 // There were three exchanges.49 // There were three exchanges.
49 c.Assert(transport.ExchangeCount, Equals, 3)50 c.Assert(transport.ExchangeCount, Equals, 3)
50 // The first two requests are Put Block with chunks of the block data. The51 // The first two requests are Put Block with chunks of the block data. The
51 // weird looking block IDs are base64 encodings of the strings "0" and "1".52 // weird looking block IDs are base64 encodings of the strings "0" and "1".
52 assertBlockSent(c, context, data[:1024*1024], b64("000000000000000000000000000000"), transport.Exchanges[0])53 fileURL := context.GetFileURL("MyContainer", "MyFile")
53 assertBlockSent(c, context, data[1024*1024:], b64("000000000000000000000000000001"), transport.Exchanges[1])54 assertBlockSent(c, context, data[:1024*1024], b64("000000000000000000000000000000"), transport.Exchanges[0], fileURL)
55 assertBlockSent(c, context, data[1024*1024:], b64("000000000000000000000000000001"), transport.Exchanges[1], fileURL)
54 // The second request is Put Block List to commit the block above.56 // The second request is Put Block List to commit the block above.
55 assertBlockListSent(c, context, []string{b64("000000000000000000000000000000"), b64("000000000000000000000000000001")}, transport.Exchanges[2])57 assertBlockListSent(c, context, []string{b64("000000000000000000000000000000"), b64("000000000000000000000000000001")}, transport.Exchanges[2], fileURL)
56}58}
5759
58func uploadRandomBlob(c *C, context *StorageContext, size int) []byte {60func uploadRandomBlob(c *C, context *StorageContext, size int, container, filename string) []byte {
59 data := MakeRandomByteSlice(size)61 data := MakeRandomByteSlice(size)
60 err := context.UploadBlockBlob(62 err := context.UploadBlockBlob(
61 "MyContainer", "MyFile", bytes.NewReader(data))63 container, filename, bytes.NewReader(data))
62 c.Assert(err, IsNil)64 c.Assert(err, IsNil)
63 return data65 return data
64}66}
6567
66func assertBlockSent(68func assertBlockSent(
67 c *C, context *StorageContext, data []byte, blockID string, exchange *MockingTransportExchange) {69 c *C, context *StorageContext, data []byte, blockID string, exchange *MockingTransportExchange, fileURL string) {
68 c.Check(exchange.Request.URL.String(), Matches, context.GetFileURL("MyContainer", "MyFile")+"?.*")70 c.Check(exchange.Request.URL.String(), Matches, fileURL+"?.*")
69 c.Check(exchange.Request.URL.Query(), DeepEquals, url.Values{71 c.Check(exchange.Request.URL.Query(), DeepEquals, url.Values{
70 "comp": {"block"},72 "comp": {"block"},
71 "blockid": {blockID},73 "blockid": {blockID},
@@ -85,10 +87,11 @@
85}87}
8688
87func assertBlockListSent(89func assertBlockListSent(
88 c *C, context *StorageContext, blockIDs []string, exchange *MockingTransportExchange) {90 c *C, context *StorageContext, blockIDs []string, exchange *MockingTransportExchange, fileURL string) {
89 c.Check(exchange.Request.URL.String(), Equals, fmt.Sprintf(91 c.Check(exchange.Request.URL.String(), Matches, fileURL+"?.*")
90 "https://%s.blob.core.windows.net/MyContainer/MyFile"+92 c.Check(exchange.Request.URL.Query(), DeepEquals, url.Values{
91 "?comp=blocklist", context.Account))93 "comp": {"blocklist"},
94 })
92 body, err := ioutil.ReadAll(exchange.Request.Body)95 body, err := ioutil.ReadAll(exchange.Request.Body)
93 c.Check(err, IsNil)96 c.Check(err, IsNil)
94 expected := "<BlockList>\n"97 expected := "<BlockList>\n"
@@ -272,10 +275,11 @@
272 }275 }
273 transport := &TestTransport{Response: response}276 transport := &TestTransport{Response: response}
274 context := makeStorageContext(transport)277 context := makeStorageContext(transport)
278 context.AzureEndpoint = "http://example.com/"
275 results, err := context.ListAllContainers()279 results, err := context.ListAllContainers()
276 c.Assert(err, IsNil)280 c.Assert(err, IsNil)
277 c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(281 c.Check(transport.Request.URL.String(), Equals, fmt.Sprintf(
278 "https://%s.blob.core.windows.net/?comp=list", context.Account))282 "http://%s.blob.example.com/?comp=list", context.Account))
279 c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")283 c.Check(transport.Request.Header.Get("Authorization"), Not(Equals), "")
280 c.Assert(results, NotNil)284 c.Assert(results, NotNil)
281 c.Assert(results.Containers[0].Name, Equals, "name-value")285 c.Assert(results.Containers[0].Name, Equals, "name-value")
282286
=== modified file 'testing_test.go'
--- testing_test.go 2013-06-27 13:58:43 +0000
+++ testing_test.go 2013-08-07 02:15:36 +0000
@@ -19,6 +19,7 @@
19 transport := &TestTransport{Error: error}19 transport := &TestTransport{Error: error}
20 client := &http.Client{Transport: transport}20 client := &http.Client{Transport: transport}
21 context := NewTestStorageContext(client)21 context := NewTestStorageContext(client)
22 context.AzureEndpoint = "http://example.com/"
22 request := &ListContainersRequest{Marker: ""}23 request := &ListContainersRequest{Marker: ""}
23 _, err := context.ListContainers(request)24 _, err := context.ListContainers(request)
24 c.Check(err, ErrorMatches, ".*"+errorMessage+".*")25 c.Check(err, ErrorMatches, ".*"+errorMessage+".*")

Subscribers

People subscribed via source and target branches