@@ -2,6 +2,8 @@ package azblob_test
2
2
3
3
import (
4
4
"context"
5
+ "io/ioutil"
6
+ "time"
5
7
6
8
"crypto/md5"
7
9
@@ -74,6 +76,154 @@ func (b *aztestsSuite) TestAppendBlockWithMD5(c *chk.C) {
74
76
validateStorageError (c , err , azblob .ServiceCodeMd5Mismatch )
75
77
}
76
78
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
+
77
227
func (s * aztestsSuite ) TestBlobCreateAppendMetadataNonEmpty (c * chk.C ) {
78
228
bsu := getBSU ()
79
229
containerURL , _ := createNewContainer (c , bsu )
0 commit comments