Skip to content

Commit 678206e

Browse files
authored
Merge pull request #118 from Azure/dev
Release 0.6.0
2 parents 046bbc2 + 943658f commit 678206e

19 files changed

+754
-17
lines changed

azblob/sas_service.go

+2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ func (v BlobSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *Share
6161
v.IPRange.String(),
6262
string(v.Protocol),
6363
v.Version,
64+
resource,
65+
"", // signed timestamp, @TODO add for snapshot sas feature
6466
v.CacheControl, // rscc
6567
v.ContentDisposition, // rscd
6668
v.ContentEncoding, // rsce

azblob/url_append_blob.go

+11
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ func (ab AppendBlobURL) AppendBlock(ctx context.Context, body io.ReadSeeker, ac
6969
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
7070
}
7171

72+
// AppendBlockFromURL copies a new block of data from source URL to the end of the existing append blob.
73+
// For more information, see https://docs.microsoft.com/rest/api/storageservices/append-block-from-url.
74+
func (ab AppendBlobURL) AppendBlockFromURL(ctx context.Context, sourceURL url.URL, offset int64, count int64, ac AppendBlobAccessConditions, transactionalMD5 []byte) (*AppendBlobAppendBlockFromURLResponse, error) {
75+
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
76+
ifAppendPositionEqual, ifMaxSizeLessThanOrEqual := ac.AppendPositionAccessConditions.pointers()
77+
return ab.abClient.AppendBlockFromURL(ctx, sourceURL.String(), 0, httpRange{offset: offset, count: count}.pointers(),
78+
transactionalMD5, nil, transactionalMD5, ac.LeaseAccessConditions.pointers(),
79+
ifMaxSizeLessThanOrEqual, ifAppendPositionEqual,
80+
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
81+
}
82+
7283
type AppendBlobAccessConditions struct {
7384
ModifiedAccessConditions
7485
LeaseAccessConditions

azblob/url_page_blob.go

+14
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,20 @@ func (pb PageBlobURL) UploadPages(ctx context.Context, offset int64, body io.Rea
7272
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
7373
}
7474

75+
// UploadPagesFromURL copies 1 or more pages from a source URL to the page blob.
76+
// The sourceOffset specifies the start offset of source data to copy from.
77+
// The destOffset specifies the start offset of data in page blob will be written to.
78+
// The count must be a multiple of 512 bytes.
79+
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-page-from-url.
80+
func (pb PageBlobURL) UploadPagesFromURL(ctx context.Context, sourceURL url.URL, sourceOffset int64, destOffset int64, count int64, ac PageBlobAccessConditions, transactionalMD5 []byte) (*PageBlobUploadPagesFromURLResponse, error) {
81+
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
82+
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual := ac.SequenceNumberAccessConditions.pointers()
83+
return pb.pbClient.UploadPagesFromURL(ctx, sourceURL.String(), *PageRange{Start: sourceOffset, End: sourceOffset + count - 1}.pointers(), 0,
84+
*PageRange{Start: destOffset, End: destOffset + count - 1}.pointers(), transactionalMD5, nil, ac.LeaseAccessConditions.pointers(),
85+
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual,
86+
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
87+
}
88+
7589
// ClearPages frees the specified pages from the page blob.
7690
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-page.
7791
func (pb PageBlobURL) ClearPages(ctx context.Context, offset int64, count int64, ac PageBlobAccessConditions) (*PageBlobClearPagesResponse, error) {

azblob/version.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package azblob
22

3-
const serviceLibVersion = "0.5"
3+
const serviceLibVersion = "0.6"

azblob/zc_mmf_unix.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// +build linux darwin freebsd openbsd netbsd
1+
// +build linux darwin freebsd openbsd netbsd dragonfly
22

33
package azblob
44

azblob/zc_pipeline.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ type PipelineOptions struct {
1717

1818
// Telemetry configures the built-in telemetry policy behavior.
1919
Telemetry TelemetryOptions
20+
21+
// HTTPSender configures the sender of HTTP requests
22+
HTTPSender pipeline.Factory
2023
}
2124

2225
// NewPipeline creates a Pipeline using the specified credentials and options.
@@ -35,8 +38,9 @@ func NewPipeline(c Credential, o PipelineOptions) pipeline.Pipeline {
3538
f = append(f, c)
3639
}
3740
f = append(f,
38-
pipeline.MethodFactoryMarker(), // indicates at what stage in the pipeline the method factory is invoked
39-
NewRequestLogPolicyFactory(o.RequestLog))
41+
NewRequestLogPolicyFactory(o.RequestLog),
42+
pipeline.MethodFactoryMarker()) // indicates at what stage in the pipeline the method factory is invoked
43+
4044

41-
return pipeline.NewPipeline(f, pipeline.Options{HTTPSender: nil, Log: o.Log})
45+
return pipeline.NewPipeline(f, pipeline.Options{HTTPSender: o.HTTPSender, Log: o.Log})
4246
}

azblob/zc_policy_retry.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ func (o RetryOptions) calcDelay(try int32) time.Duration { // try is >=1; never
120120
}
121121

122122
// Introduce some jitter: [0.0, 1.0) / 2 = [0.0, 0.5) + 0.8 = [0.8, 1.3)
123-
delay = time.Duration(delay.Seconds() * (rand.Float64()/2 + 0.8) * float64(time.Second)) // NOTE: We want math/rand; not crypto/rand
123+
// For casts and rounding - be careful, as per https://github.com/golang/go/issues/20757
124+
delay = time.Duration(float32(delay) * (rand.Float32()/2 + 0.8)) // NOTE: We want math/rand; not crypto/rand
124125
if delay > o.MaxRetryDelay {
125126
delay = o.MaxRetryDelay
126127
}
@@ -157,7 +158,8 @@ func NewRetryPolicyFactory(o RetryOptions) pipeline.Factory {
157158
logf("Primary try=%d, Delay=%v\n", primaryTry, delay)
158159
time.Sleep(delay) // The 1st try returns 0 delay
159160
} else {
160-
delay := time.Second * time.Duration(rand.Float32()/2+0.8)
161+
// For casts and rounding - be careful, as per https://github.com/golang/go/issues/20757
162+
delay := time.Duration(float32(time.Second) * (rand.Float32()/2 + 0.8))
161163
logf("Secondary try=%d, Delay=%v\n", try-primaryTry, delay)
162164
time.Sleep(delay) // Delay with some jitter before trying secondary
163165
}

azblob/zt_examples_test.go

+28
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"io"
1010
"log"
11+
"net"
1112
"net/http"
1213
"net/url"
1314
"os"
@@ -154,6 +155,33 @@ func ExampleNewPipeline() {
154155
return level <= pipeline.LogWarning // Log all events from warning to more severe
155156
},
156157
},
158+
159+
// Set HTTPSender to override the default HTTP Sender that sends the request over the network
160+
HTTPSender: pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc {
161+
return func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
162+
// Implement the HTTP client that will override the default sender.
163+
// For example, below HTTP client uses a transport that is different from http.DefaultTransport
164+
client := http.Client{
165+
Transport: &http.Transport{
166+
Proxy: nil,
167+
DialContext: (&net.Dialer{
168+
Timeout: 30 * time.Second,
169+
KeepAlive: 30 * time.Second,
170+
DualStack: true,
171+
}).DialContext,
172+
MaxIdleConns: 100,
173+
IdleConnTimeout: 180 * time.Second,
174+
TLSHandshakeTimeout: 10 * time.Second,
175+
ExpectContinueTimeout: 1 * time.Second,
176+
},
177+
}
178+
179+
// Send the request over the network
180+
resp, err := client.Do(request.WithContext(ctx))
181+
182+
return &httpResponse{response: resp}, err
183+
}
184+
}),
157185
}
158186

159187
// Create a request pipeline object configured with credentials and with pipeline options. Once created,

azblob/zt_policy_retry_test.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ func testRetryTestScenario(c *chk.C, scenario retryTestScenario) {
155155
MaxRetryDelay: 4 * time.Second,
156156
RetryReadsFromSecondaryHost: "SecondaryDC",
157157
}
158+
minExpectedTimeToMaxRetries := (retryOptions.MaxRetryDelay * time.Duration(retryOptions.MaxTries-3)) / 2 // a very rough approximation, of a lower bound, given assumption that we hit the cap early in the retry count, and pessimistically assuming that all get halved by random jitter calcs
158159
ctx := context.Background()
159160
ctx, cancel := context.WithTimeout(ctx, 64 /*2^MaxTries(6)*/ *retryOptions.TryTimeout)
160161
retrytestPolicyFactory := newRetryTestPolicyFactory(c, scenario, retryOptions.MaxTries, cancel)
@@ -164,16 +165,18 @@ func testRetryTestScenario(c *chk.C, scenario retryTestScenario) {
164165
}
165166
p := pipeline.NewPipeline(factories[:], pipeline.Options{})
166167
request, err := pipeline.NewRequest(http.MethodGet, *u, strings.NewReader("TestData"))
168+
start := time.Now()
167169
response, err := p.Do(ctx, nil, request)
168170
switch scenario {
169171
case retryTestScenarioRetryUntilSuccess:
170172
if err != nil || response == nil || response.Response() == nil || response.Response().StatusCode != http.StatusOK {
171173
c.Fail() // Operation didn't run to success
172174
}
173175
case retryTestScenarioRetryUntilMaxRetries:
174-
c.Assert(err, chk.NotNil) // Ensure we ended with an error
175-
c.Assert(response, chk.IsNil) // Ensure we ended without a valid response
176-
c.Assert(retrytestPolicyFactory.try, chk.Equals, retryOptions.MaxTries) // Ensure the operation ends with the exact right number of tries
176+
c.Assert(err, chk.NotNil) // Ensure we ended with an error
177+
c.Assert(response, chk.IsNil) // Ensure we ended without a valid response
178+
c.Assert(retrytestPolicyFactory.try, chk.Equals, retryOptions.MaxTries) // Ensure the operation ends with the exact right number of tries
179+
c.Assert(time.Since(start) > minExpectedTimeToMaxRetries, chk.Equals, true) // Ensure it took about as long to get here as we expect (bearing in mind randomness in the jitter), as a basic sanity check of our delay duration calculations
177180
case retryTestScenarioRetryUntilOperationCancel:
178181
c.Assert(err, chk.Equals, context.Canceled) // Ensure we ended due to cancellation
179182
c.Assert(response, chk.IsNil) // Ensure we ended without a valid response

azblob/zt_test.go

+10
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,21 @@ func createNewPageBlob(c *chk.C, container azblob.ContainerURL) (blob azblob.Pag
187187
blob, name = getPageBlobURL(c, container)
188188

189189
resp, err := blob.Create(ctx, azblob.PageBlobPageBytes*10, 0, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
190+
c.Assert(err, chk.IsNil)
191+
c.Assert(resp.StatusCode(), chk.Equals, 201)
192+
return
193+
}
194+
195+
func createNewPageBlobWithSize(c *chk.C, container azblob.ContainerURL, sizeInBytes int64) (blob azblob.PageBlobURL, name string) {
196+
blob, name = getPageBlobURL(c, container)
197+
198+
resp, err := blob.Create(ctx, sizeInBytes, 0, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
190199

191200
c.Assert(err, chk.IsNil)
192201
c.Assert(resp.StatusCode(), chk.Equals, 201)
193202
return
194203
}
204+
195205
func createBlockBlobWithPrefix(c *chk.C, container azblob.ContainerURL, prefix string) (blob azblob.BlockBlobURL, name string) {
196206
name = prefix + generateName(blobPrefix)
197207
blob = container.NewBlockBlobURL(name)

azblob/zt_url_append_blob_test.go

+150
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package azblob_test
22

33
import (
44
"context"
5+
"io/ioutil"
6+
"time"
57

68
"crypto/md5"
79

@@ -74,6 +76,154 @@ func (b *aztestsSuite) TestAppendBlockWithMD5(c *chk.C) {
7476
validateStorageError(c, err, azblob.ServiceCodeMd5Mismatch)
7577
}
7678

79+
func (b *aztestsSuite) TestAppendBlockFromURL(c *chk.C) {
80+
bsu := getBSU()
81+
credential, err := getGenericCredential("")
82+
if err != nil {
83+
c.Fatal("Invalid credential")
84+
}
85+
container, _ := createNewContainer(c, bsu)
86+
defer delContainer(c, container)
87+
88+
testSize := 4 * 1024 * 1024 // 4MB
89+
r, sourceData := getRandomDataAndReader(testSize)
90+
ctx := context.Background() // Use default Background context
91+
srcBlob := container.NewAppendBlobURL(generateName("appendsrc"))
92+
destBlob := container.NewAppendBlobURL(generateName("appenddest"))
93+
94+
// Prepare source blob for copy.
95+
cResp1, err := srcBlob.Create(context.Background(), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
96+
c.Assert(err, chk.IsNil)
97+
c.Assert(cResp1.StatusCode(), chk.Equals, 201)
98+
appendResp, err := srcBlob.AppendBlock(context.Background(), r, azblob.AppendBlobAccessConditions{}, nil)
99+
c.Assert(err, chk.IsNil)
100+
c.Assert(appendResp.Response().StatusCode, chk.Equals, 201)
101+
c.Assert(appendResp.BlobAppendOffset(), chk.Equals, "0")
102+
c.Assert(appendResp.BlobCommittedBlockCount(), chk.Equals, int32(1))
103+
c.Assert(appendResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
104+
c.Assert(appendResp.LastModified().IsZero(), chk.Equals, false)
105+
c.Assert(appendResp.ContentMD5(), chk.Not(chk.Equals), "")
106+
c.Assert(appendResp.RequestID(), chk.Not(chk.Equals), "")
107+
c.Assert(appendResp.Version(), chk.Not(chk.Equals), "")
108+
c.Assert(appendResp.Date().IsZero(), chk.Equals, false)
109+
110+
// Get source blob URL with SAS for AppendBlockFromURL.
111+
srcBlobParts := azblob.NewBlobURLParts(srcBlob.URL())
112+
113+
srcBlobParts.SAS, err = azblob.BlobSASSignatureValues{
114+
Protocol: azblob.SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
115+
ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration
116+
ContainerName: srcBlobParts.ContainerName,
117+
BlobName: srcBlobParts.BlobName,
118+
Permissions: azblob.BlobSASPermissions{Read: true}.String(),
119+
}.NewSASQueryParameters(credential)
120+
if err != nil {
121+
c.Fatal(err)
122+
}
123+
124+
srcBlobURLWithSAS := srcBlobParts.URL()
125+
126+
// Append block from URL.
127+
cResp2, err := destBlob.Create(context.Background(), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
128+
c.Assert(err, chk.IsNil)
129+
c.Assert(cResp2.StatusCode(), chk.Equals, 201)
130+
appendFromURLResp, err := destBlob.AppendBlockFromURL(ctx, srcBlobURLWithSAS, 0, int64(testSize), azblob.AppendBlobAccessConditions{}, nil)
131+
c.Assert(err, chk.IsNil)
132+
c.Assert(appendFromURLResp.Response().StatusCode, chk.Equals, 201)
133+
c.Assert(appendFromURLResp.BlobAppendOffset(), chk.Equals, "0")
134+
c.Assert(appendFromURLResp.BlobCommittedBlockCount(), chk.Equals, int32(1))
135+
c.Assert(appendFromURLResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
136+
c.Assert(appendFromURLResp.LastModified().IsZero(), chk.Equals, false)
137+
c.Assert(appendFromURLResp.ContentMD5(), chk.Not(chk.Equals), "")
138+
c.Assert(appendFromURLResp.RequestID(), chk.Not(chk.Equals), "")
139+
c.Assert(appendFromURLResp.Version(), chk.Not(chk.Equals), "")
140+
c.Assert(appendFromURLResp.Date().IsZero(), chk.Equals, false)
141+
142+
// Check data integrity through downloading.
143+
downloadResp, err := destBlob.BlobURL.Download(ctx, 0, azblob.CountToEnd, azblob.BlobAccessConditions{}, false)
144+
c.Assert(err, chk.IsNil)
145+
destData, err := ioutil.ReadAll(downloadResp.Body(azblob.RetryReaderOptions{}))
146+
c.Assert(err, chk.IsNil)
147+
c.Assert(destData, chk.DeepEquals, sourceData)
148+
}
149+
150+
func (b *aztestsSuite) TestAppendBlockFromURLWithMD5(c *chk.C) {
151+
bsu := getBSU()
152+
credential, err := getGenericCredential("")
153+
if err != nil {
154+
c.Fatal("Invalid credential")
155+
}
156+
container, _ := createNewContainer(c, bsu)
157+
defer delContainer(c, container)
158+
159+
testSize := 4 * 1024 * 1024 // 4MB
160+
r, sourceData := getRandomDataAndReader(testSize)
161+
md5Value := md5.Sum(sourceData)
162+
ctx := context.Background() // Use default Background context
163+
srcBlob := container.NewAppendBlobURL(generateName("appendsrc"))
164+
destBlob := container.NewAppendBlobURL(generateName("appenddest"))
165+
166+
// Prepare source blob for copy.
167+
cResp1, err := srcBlob.Create(context.Background(), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
168+
c.Assert(err, chk.IsNil)
169+
c.Assert(cResp1.StatusCode(), chk.Equals, 201)
170+
appendResp, err := srcBlob.AppendBlock(context.Background(), r, azblob.AppendBlobAccessConditions{}, nil)
171+
c.Assert(err, chk.IsNil)
172+
c.Assert(appendResp.Response().StatusCode, chk.Equals, 201)
173+
c.Assert(appendResp.BlobAppendOffset(), chk.Equals, "0")
174+
c.Assert(appendResp.BlobCommittedBlockCount(), chk.Equals, int32(1))
175+
c.Assert(appendResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
176+
c.Assert(appendResp.LastModified().IsZero(), chk.Equals, false)
177+
c.Assert(appendResp.ContentMD5(), chk.Not(chk.Equals), "")
178+
c.Assert(appendResp.RequestID(), chk.Not(chk.Equals), "")
179+
c.Assert(appendResp.Version(), chk.Not(chk.Equals), "")
180+
c.Assert(appendResp.Date().IsZero(), chk.Equals, false)
181+
182+
// Get source blob URL with SAS for AppendBlockFromURL.
183+
srcBlobParts := azblob.NewBlobURLParts(srcBlob.URL())
184+
185+
srcBlobParts.SAS, err = azblob.BlobSASSignatureValues{
186+
Protocol: azblob.SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
187+
ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration
188+
ContainerName: srcBlobParts.ContainerName,
189+
BlobName: srcBlobParts.BlobName,
190+
Permissions: azblob.BlobSASPermissions{Read: true}.String(),
191+
}.NewSASQueryParameters(credential)
192+
if err != nil {
193+
c.Fatal(err)
194+
}
195+
196+
srcBlobURLWithSAS := srcBlobParts.URL()
197+
198+
// Append block from URL.
199+
cResp2, err := destBlob.Create(context.Background(), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
200+
c.Assert(err, chk.IsNil)
201+
c.Assert(cResp2.StatusCode(), chk.Equals, 201)
202+
appendFromURLResp, err := destBlob.AppendBlockFromURL(ctx, srcBlobURLWithSAS, 0, int64(testSize), azblob.AppendBlobAccessConditions{}, md5Value[:])
203+
c.Assert(err, chk.IsNil)
204+
c.Assert(appendFromURLResp.Response().StatusCode, chk.Equals, 201)
205+
c.Assert(appendFromURLResp.BlobAppendOffset(), chk.Equals, "0")
206+
c.Assert(appendFromURLResp.BlobCommittedBlockCount(), chk.Equals, int32(1))
207+
c.Assert(appendFromURLResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
208+
c.Assert(appendFromURLResp.LastModified().IsZero(), chk.Equals, false)
209+
c.Assert(appendFromURLResp.ContentMD5(), chk.DeepEquals, md5Value[:])
210+
c.Assert(appendFromURLResp.RequestID(), chk.Not(chk.Equals), "")
211+
c.Assert(appendFromURLResp.Version(), chk.Not(chk.Equals), "")
212+
c.Assert(appendFromURLResp.Date().IsZero(), chk.Equals, false)
213+
214+
// Check data integrity through downloading.
215+
downloadResp, err := destBlob.BlobURL.Download(ctx, 0, azblob.CountToEnd, azblob.BlobAccessConditions{}, false)
216+
c.Assert(err, chk.IsNil)
217+
destData, err := ioutil.ReadAll(downloadResp.Body(azblob.RetryReaderOptions{}))
218+
c.Assert(err, chk.IsNil)
219+
c.Assert(destData, chk.DeepEquals, sourceData)
220+
221+
// Test append block from URL with bad MD5 value
222+
_, badMD5 := getRandomDataAndReader(16)
223+
_, err = destBlob.AppendBlockFromURL(ctx, srcBlobURLWithSAS, 0, int64(testSize), azblob.AppendBlobAccessConditions{}, badMD5[:])
224+
validateStorageError(c, err, azblob.ServiceCodeMd5Mismatch)
225+
}
226+
77227
func (s *aztestsSuite) TestBlobCreateAppendMetadataNonEmpty(c *chk.C) {
78228
bsu := getBSU()
79229
containerURL, _ := createNewContainer(c, bsu)

azblob/zt_url_blob_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ func (s *aztestsSuite) TestBlobStartCopyUsingSASSrc(c *chk.C) {
257257
if err != nil {
258258
c.Fatal("Invalid credential")
259259
}
260-
serviceSASValues := azblob.BlobSASSignatureValues{Version: "2015-04-05", StartTime: time.Now().Add(-1 * time.Hour).UTC(),
260+
serviceSASValues := azblob.BlobSASSignatureValues{StartTime: time.Now().Add(-1 * time.Hour).UTC(),
261261
ExpiryTime: time.Now().Add(time.Hour).UTC(), Permissions: azblob.BlobSASPermissions{Read: true, Write: true}.String(),
262262
ContainerName: containerName, BlobName: blobName}
263263
queryParams, err := serviceSASValues.NewSASQueryParameters(credential)

azblob/zt_url_container_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -701,8 +701,7 @@ func (s *aztestsSuite) TestContainerSetPermissionsACLSinglePolicy(c *chk.C) {
701701
_, err = containerURL.SetAccessPolicy(ctx, azblob.PublicAccessNone, permissions, azblob.ContainerAccessConditions{})
702702
c.Assert(err, chk.IsNil)
703703

704-
serviceSASValues := azblob.BlobSASSignatureValues{Version: "2015-04-05",
705-
Identifier: "0000", ContainerName: containerName}
704+
serviceSASValues := azblob.BlobSASSignatureValues{Identifier: "0000", ContainerName: containerName}
706705
queryParams, err := serviceSASValues.NewSASQueryParameters(credential)
707706
if err != nil {
708707
c.Fatal(err)

0 commit comments

Comments
 (0)